diff options
author | vnugent <public@vaughnnugent.com> | 2023-10-22 14:37:11 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-10-22 14:37:11 -0400 |
commit | aef1b25aae6fc27c4557dc7e4c9d75cbe22a1f8f (patch) | |
tree | 4c7661218668933f0a27bfca04f79c89b3e81d21 /lib/Utils.Memory/mimalloc | |
parent | d997950a29ec3ce29cd652298e678d708218fdad (diff) |
partial mimalloc support, native source code packages, and default tasks
Diffstat (limited to 'lib/Utils.Memory/mimalloc')
112 files changed, 49424 insertions, 0 deletions
diff --git a/lib/Utils.Memory/mimalloc/.gitattributes b/lib/Utils.Memory/mimalloc/.gitattributes new file mode 100644 index 0000000..0332e03 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/.gitattributes @@ -0,0 +1,12 @@ +# default behavior is to always use unix style line endings +* text eol=lf +*.png binary +*.pdn binary +*.jpg binary +*.sln binary +*.suo binary +*.vcproj binary +*.patch binary +*.dll binary +*.lib binary +*.exe binary diff --git a/lib/Utils.Memory/mimalloc/.gitignore b/lib/Utils.Memory/mimalloc/.gitignore new file mode 100644 index 0000000..f8b7f5e --- /dev/null +++ b/lib/Utils.Memory/mimalloc/.gitignore @@ -0,0 +1,9 @@ +ide/vs20??/*.db +ide/vs20??/*.opendb +ide/vs20??/*.user +ide/vs20??/*.vcxproj.filters +ide/vs20??/.vs +ide/vs20??/VTune* +out/ +docs/ +*.zip diff --git a/lib/Utils.Memory/mimalloc/CMakeLists.txt b/lib/Utils.Memory/mimalloc/CMakeLists.txt new file mode 100644 index 0000000..2bcd1ef --- /dev/null +++ b/lib/Utils.Memory/mimalloc/CMakeLists.txt @@ -0,0 +1,526 @@ +cmake_minimum_required(VERSION 3.13) +project(libmimalloc C CXX) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +option(MI_SECURE "Use full security mitigations (like guard pages, allocation randomization, double-free mitigation, and free-list corruption detection)" OFF) +option(MI_DEBUG_FULL "Use full internal heap invariant checking in DEBUG mode (expensive)" OFF) +option(MI_PADDING "Enable padding to detect heap block overflow (always on in DEBUG or SECURE mode, or with Valgrind/ASAN)" OFF) +option(MI_OVERRIDE "Override the standard malloc interface (e.g. define entry points for malloc() etc)" ON) +option(MI_XMALLOC "Enable abort() call on memory allocation failure by default" OFF) +option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF) +option(MI_TRACK_VALGRIND "Compile with Valgrind support (adds a small overhead)" OFF) +option(MI_TRACK_ASAN "Compile with address sanitizer support (adds a small overhead)" OFF) +option(MI_TRACK_ETW "Compile with Windows event tracing (ETW) support (adds a small overhead)" OFF) +option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF) +option(MI_SEE_ASM "Generate assembly files" OFF) +option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON) +option(MI_OSX_ZONE "Use malloc zone to override standard malloc on macOS" ON) +option(MI_WIN_REDIRECT "Use redirection module ('mimalloc-redirect') on Windows if compiling mimalloc as a DLL" ON) +option(MI_LOCAL_DYNAMIC_TLS "Use slightly slower, dlopen-compatible TLS mechanism (Unix)" OFF) +option(MI_BUILD_SHARED "Build shared library" ON) +option(MI_BUILD_STATIC "Build static library" ON) +option(MI_BUILD_OBJECT "Build object library" ON) +option(MI_BUILD_TESTS "Build test executables" ON) +option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF) +option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clang++)" OFF) +option(MI_SKIP_COLLECT_ON_EXIT "Skip collecting memory on program exit" OFF) +option(MI_NO_PADDING "Force no use of padding even in DEBUG mode etc." OFF) + +# deprecated options +option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode (deprecated, use MI_DEBUG_FULL instead)" OFF) +option(MI_INSTALL_TOPLEVEL "Install directly into $CMAKE_INSTALL_PREFIX instead of PREFIX/lib/mimalloc-version (deprecated)" OFF) +option(MI_USE_LIBATOMIC "Explicitly link with -latomic (on older systems) (deprecated and detected automatically)" OFF) + +include(CheckIncludeFiles) +include(GNUInstallDirs) +include("cmake/mimalloc-config-version.cmake") + +set(mi_sources + src/alloc.c + src/alloc-aligned.c + src/alloc-posix.c + src/arena.c + src/bitmap.c + src/heap.c + src/init.c + src/options.c + src/os.c + src/page.c + src/random.c + src/segment.c + src/segment-map.c + src/stats.c + src/prim/prim.c) + +set(mi_cflags "") +set(mi_libraries "") + +# ----------------------------------------------------------------------------- +# Convenience: set default build type depending on the build directory +# ----------------------------------------------------------------------------- + +message(STATUS "") +if (NOT CMAKE_BUILD_TYPE) + if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$" OR MI_DEBUG_FULL) + message(STATUS "No build type selected, default to: Debug") + set(CMAKE_BUILD_TYPE "Debug") + else() + message(STATUS "No build type selected, default to: Release") + set(CMAKE_BUILD_TYPE "Release") + endif() +endif() + +if("${CMAKE_BINARY_DIR}" MATCHES ".*(S|s)ecure$") + message(STATUS "Default to secure build") + set(MI_SECURE "ON") +endif() + + +# ----------------------------------------------------------------------------- +# Process options +# ----------------------------------------------------------------------------- + +if(CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel") + set(MI_USE_CXX "ON") +endif() + +if(MI_OVERRIDE) + message(STATUS "Override standard malloc (MI_OVERRIDE=ON)") + if(APPLE) + if(MI_OSX_ZONE) + # use zone's on macOS + message(STATUS " Use malloc zone to override malloc (MI_OSX_ZONE=ON)") + list(APPEND mi_sources src/prim/osx/alloc-override-zone.c) + list(APPEND mi_defines MI_OSX_ZONE=1) + if (NOT MI_OSX_INTERPOSE) + message(STATUS " WARNING: zone overriding usually also needs interpose (use -DMI_OSX_INTERPOSE=ON)") + endif() + endif() + if(MI_OSX_INTERPOSE) + # use interpose on macOS + message(STATUS " Use interpose to override malloc (MI_OSX_INTERPOSE=ON)") + list(APPEND mi_defines MI_OSX_INTERPOSE=1) + if (NOT MI_OSX_ZONE) + message(STATUS " WARNING: interpose usually also needs zone overriding (use -DMI_OSX_INTERPOSE=ON)") + endif() + endif() + if(MI_USE_CXX AND MI_OSX_INTERPOSE) + message(STATUS " WARNING: if dynamically overriding malloc/free, it is more reliable to build mimalloc as C code (use -DMI_USE_CXX=OFF)") + endif() + endif() +endif() + +if(WIN32) + if (MI_WIN_REDIRECT) + if (MSVC_C_ARCHITECTURE_ID MATCHES "ARM") + message(STATUS "Cannot use redirection on Windows ARM (MI_WIN_REDIRECT=OFF)") + set(MI_WIN_REDIRECT OFF) + endif() + endif() + if (NOT MI_WIN_REDIRECT) + # use a negative define for backward compatibility + list(APPEND mi_defines MI_WIN_NOREDIRECT=1) + endif() +endif() + +if(MI_SECURE) + message(STATUS "Set full secure build (MI_SECURE=ON)") + list(APPEND mi_defines MI_SECURE=4) +endif() + +if(MI_TRACK_VALGRIND) + CHECK_INCLUDE_FILES("valgrind/valgrind.h;valgrind/memcheck.h" MI_HAS_VALGRINDH) + if (NOT MI_HAS_VALGRINDH) + set(MI_TRACK_VALGRIND OFF) + message(WARNING "Cannot find the 'valgrind/valgrind.h' and 'valgrind/memcheck.h' -- install valgrind first") + message(STATUS "Compile **without** Valgrind support (MI_TRACK_VALGRIND=OFF)") + else() + message(STATUS "Compile with Valgrind support (MI_TRACK_VALGRIND=ON)") + list(APPEND mi_defines MI_TRACK_VALGRIND=1) + endif() +endif() + +if(MI_TRACK_ASAN) + if (APPLE AND MI_OVERRIDE) + set(MI_TRACK_ASAN OFF) + message(WARNING "Cannot enable address sanitizer support on macOS if MI_OVERRIDE is ON (MI_TRACK_ASAN=OFF)") + endif() + if (MI_TRACK_VALGRIND) + set(MI_TRACK_ASAN OFF) + message(WARNING "Cannot enable address sanitizer support with also Valgrind support enabled (MI_TRACK_ASAN=OFF)") + endif() + if(MI_TRACK_ASAN) + CHECK_INCLUDE_FILES("sanitizer/asan_interface.h" MI_HAS_ASANH) + if (NOT MI_HAS_ASANH) + set(MI_TRACK_ASAN OFF) + message(WARNING "Cannot find the 'sanitizer/asan_interface.h' -- install address sanitizer support first") + message(STATUS "Compile **without** address sanitizer support (MI_TRACK_ASAN=OFF)") + else() + message(STATUS "Compile with address sanitizer support (MI_TRACK_ASAN=ON)") + list(APPEND mi_defines MI_TRACK_ASAN=1) + list(APPEND mi_cflags -fsanitize=address) + list(APPEND mi_libraries -fsanitize=address) + endif() + endif() +endif() + +if(MI_TRACK_ETW) + if(NOT WIN32) + set(MI_TRACK_ETW OFF) + message(WARNING "Can only enable ETW support on Windows (MI_TRACK_ETW=OFF)") + endif() + if (MI_TRACK_VALGRIND OR MI_TRACK_ASAN) + set(MI_TRACK_ETW OFF) + message(WARNING "Cannot enable ETW support with also Valgrind or ASAN support enabled (MI_TRACK_ETW=OFF)") + endif() + if(MI_TRACK_ETW) + message(STATUS "Compile with Windows event tracing support (MI_TRACK_ETW=ON)") + list(APPEND mi_defines MI_TRACK_ETW=1) + endif() +endif() + +if(MI_SEE_ASM) + message(STATUS "Generate assembly listings (MI_SEE_ASM=ON)") + list(APPEND mi_cflags -save-temps) +endif() + +if(MI_CHECK_FULL) + message(STATUS "The MI_CHECK_FULL option is deprecated, use MI_DEBUG_FULL instead") + set(MI_DEBUG_FULL "ON") +endif() + +if (MI_SKIP_COLLECT_ON_EXIT) + message(STATUS "Skip collecting memory on program exit (MI_SKIP_COLLECT_ON_EXIT=ON)") + list(APPEND mi_defines MI_SKIP_COLLECT_ON_EXIT=1) +endif() + +if(MI_DEBUG_FULL) + message(STATUS "Set debug level to full internal invariant checking (MI_DEBUG_FULL=ON)") + list(APPEND mi_defines MI_DEBUG=3) # full invariant checking +endif() + +if(MI_NO_PADDING) + message(STATUS "Suppress any padding of heap blocks (MI_NO_PADDING=ON)") + list(APPEND mi_defines MI_PADDING=0) +else() + if(MI_PADDING) + message(STATUS "Enable explicit padding of heap blocks (MI_PADDING=ON)") + list(APPEND mi_defines MI_PADDING=1) + endif() +endif() + +if(MI_XMALLOC) + message(STATUS "Enable abort() calls on memory allocation failure (MI_XMALLOC=ON)") + list(APPEND mi_defines MI_XMALLOC=1) +endif() + +if(MI_SHOW_ERRORS) + message(STATUS "Enable printing of error and warning messages by default (MI_SHOW_ERRORS=ON)") + list(APPEND mi_defines MI_SHOW_ERRORS=1) +endif() + +if(MI_DEBUG_TSAN) + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + message(STATUS "Build with thread sanitizer (MI_DEBUG_TSAN=ON)") + list(APPEND mi_defines MI_TSAN=1) + list(APPEND mi_cflags -fsanitize=thread -g -O1) + list(APPEND mi_libraries -fsanitize=thread) + else() + message(WARNING "Can only use thread sanitizer with clang (MI_DEBUG_TSAN=ON but ignored)") + endif() +endif() + +if(MI_DEBUG_UBSAN) + if(CMAKE_BUILD_TYPE MATCHES "Debug") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(STATUS "Build with undefined-behavior sanitizer (MI_DEBUG_UBSAN=ON)") + list(APPEND mi_cflags -fsanitize=undefined -g -fno-sanitize-recover=undefined) + list(APPEND mi_libraries -fsanitize=undefined) + if (NOT MI_USE_CXX) + message(STATUS "(switch to use C++ due to MI_DEBUG_UBSAN)") + set(MI_USE_CXX "ON") + endif() + else() + message(WARNING "Can only use undefined-behavior sanitizer with clang++ (MI_DEBUG_UBSAN=ON but ignored)") + endif() + else() + message(WARNING "Can only use thread sanitizer with a debug build (CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE})") + endif() +endif() + +if(MI_USE_CXX) + message(STATUS "Use the C++ compiler to compile (MI_USE_CXX=ON)") + set_source_files_properties(${mi_sources} PROPERTIES LANGUAGE CXX ) + set_source_files_properties(src/static.c test/test-api.c test/test-api-fill test/test-stress PROPERTIES LANGUAGE CXX ) + if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang") + list(APPEND mi_cflags -Wno-deprecated) + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM") + list(APPEND mi_cflags -Kc++) + endif() +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Haiku") + SET(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib) + SET(CMAKE_INSTALL_INCLUDEDIR ~/config/non-packaged/headers) + endif() + +# Compiler flags +if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") + list(APPEND mi_cflags -Wall -Wextra -Wno-unknown-pragmas -fvisibility=hidden) + if(NOT MI_USE_CXX) + list(APPEND mi_cflags -Wstrict-prototypes) + endif() + if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang") + list(APPEND mi_cflags -Wpedantic -Wno-static-in-inline) + endif() +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "Intel") + list(APPEND mi_cflags -Wall -fvisibility=hidden) +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku") + if(MI_LOCAL_DYNAMIC_TLS) + list(APPEND mi_cflags -ftls-model=local-dynamic) + else() + list(APPEND mi_cflags -ftls-model=initial-exec) + endif() + if(MI_OVERRIDE) + list(APPEND mi_cflags -fno-builtin-malloc) + endif() +endif() + +if (MSVC AND MSVC_VERSION GREATER_EQUAL 1914) + list(APPEND mi_cflags /Zc:__cplusplus) +endif() + +# extra needed libraries +if(WIN32) + list(APPEND mi_libraries psapi shell32 user32 advapi32 bcrypt) + set(pc_libraries "-lpsapi -lshell32 -luser32 -ladvapi32 -lbcrypt") +else() + set(pc_libraries "") + find_library(MI_LIBPTHREAD pthread) + if (MI_LIBPTHREAD) + list(APPEND mi_libraries ${MI_LIBPTHREAD}) + set(pc_libraries "${pc_libraries} -pthread") + endif() + find_library(MI_LIBRT rt) + if(MI_LIBRT) + list(APPEND mi_libraries ${MI_LIBRT}) + set(pc_libraries "${pc_libraries} -lrt") + endif() + find_library(MI_LIBATOMIC atomic) + if (NOT MI_LIBATOMIC AND MI_USE_LIBATOMIC) + set(MI_LIBATOMIC atomic) + endif() + if (MI_LIBATOMIC) + list(APPEND mi_libraries ${MI_LIBATOMIC}) + set(pc_libraries "${pc_libraries} -latomic") + endif() +endif() + +# ----------------------------------------------------------------------------- +# Install and output names +# ----------------------------------------------------------------------------- + +# dynamic/shared library and symlinks always go to /usr/local/lib equivalent +set(mi_install_libdir "${CMAKE_INSTALL_LIBDIR}") + +# static libraries and object files, includes, and cmake config files +# are either installed at top level, or use versioned directories for side-by-side installation (default) +if (MI_INSTALL_TOPLEVEL) + set(mi_install_objdir "${CMAKE_INSTALL_LIBDIR}") + set(mi_install_incdir "${CMAKE_INSTALL_INCLUDEDIR}") + set(mi_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/mimalloc") +else() + set(mi_install_objdir "${CMAKE_INSTALL_LIBDIR}/mimalloc-${mi_version}") # for static library and object files + set(mi_install_incdir "${CMAKE_INSTALL_INCLUDEDIR}/mimalloc-${mi_version}") # for includes + set(mi_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/mimalloc-${mi_version}") # for cmake package info +endif() + +set(mi_basename "mimalloc") +if(MI_SECURE) + set(mi_basename "${mi_basename}-secure") +endif() +if(MI_TRACK_VALGRIND) + set(mi_basename "${mi_basename}-valgrind") +endif() +if(MI_TRACK_ASAN) + set(mi_basename "${mi_basename}-asan") +endif() +string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LC) +if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel|none)$")) + set(mi_basename "${mi_basename}-${CMAKE_BUILD_TYPE_LC}") #append build type (e.g. -debug) if not a release version +endif() + +if(MI_BUILD_SHARED) + list(APPEND mi_build_targets "shared") +endif() +if(MI_BUILD_STATIC) + list(APPEND mi_build_targets "static") +endif() +if(MI_BUILD_OBJECT) + list(APPEND mi_build_targets "object") +endif() +if(MI_BUILD_TESTS) + list(APPEND mi_build_targets "tests") +endif() + +message(STATUS "") +message(STATUS "Library base name: ${mi_basename}") +message(STATUS "Version : ${mi_version}") +message(STATUS "Build type : ${CMAKE_BUILD_TYPE_LC}") +if(MI_USE_CXX) + message(STATUS "C++ Compiler : ${CMAKE_CXX_COMPILER}") +else() + message(STATUS "C Compiler : ${CMAKE_C_COMPILER}") +endif() +message(STATUS "Compiler flags : ${mi_cflags}") +message(STATUS "Compiler defines : ${mi_defines}") +message(STATUS "Link libraries : ${mi_libraries}") +message(STATUS "Build targets : ${mi_build_targets}") +message(STATUS "") + +# ----------------------------------------------------------------------------- +# Main targets +# ----------------------------------------------------------------------------- + +# shared library +if(MI_BUILD_SHARED) + add_library(mimalloc SHARED ${mi_sources}) + set_target_properties(mimalloc PROPERTIES VERSION ${mi_version} SOVERSION ${mi_version_major} OUTPUT_NAME ${mi_basename} ) + target_compile_definitions(mimalloc PRIVATE ${mi_defines} MI_SHARED_LIB MI_SHARED_LIB_EXPORT) + target_compile_options(mimalloc PRIVATE ${mi_cflags}) + target_link_libraries(mimalloc PRIVATE ${mi_libraries}) + target_include_directories(mimalloc PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${mi_install_incdir}> + ) + if(WIN32 AND MI_WIN_REDIRECT) + # On windows, link and copy the mimalloc redirection dll too. + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(MIMALLOC_REDIRECT_SUFFIX "32") + else() + set(MIMALLOC_REDIRECT_SUFFIX "") + endif() + + target_link_libraries(mimalloc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.lib) + add_custom_command(TARGET mimalloc POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.dll" $<TARGET_FILE_DIR:mimalloc> + COMMENT "Copy mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.dll to output directory") + install(FILES "$<TARGET_FILE_DIR:mimalloc>/mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.dll" DESTINATION ${mi_install_libdir}) + endif() + + install(TARGETS mimalloc EXPORT mimalloc DESTINATION ${mi_install_libdir} LIBRARY) + install(EXPORT mimalloc DESTINATION ${mi_install_cmakedir}) +endif() + +# static library +if (MI_BUILD_STATIC) + add_library(mimalloc-static STATIC ${mi_sources}) + set_property(TARGET mimalloc-static PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(mimalloc-static PRIVATE ${mi_defines} MI_STATIC_LIB) + target_compile_options(mimalloc-static PRIVATE ${mi_cflags}) + target_link_libraries(mimalloc-static PRIVATE ${mi_libraries}) + target_include_directories(mimalloc-static PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${mi_install_incdir}> + ) + if(WIN32) + # When building both static and shared libraries on Windows, a static library should use a + # different output name to avoid the conflict with the import library of a shared one. + string(REPLACE "mimalloc" "mimalloc-static" mi_output_name ${mi_basename}) + set_target_properties(mimalloc-static PROPERTIES OUTPUT_NAME ${mi_output_name}) + else() + set_target_properties(mimalloc-static PROPERTIES OUTPUT_NAME ${mi_basename}) + endif() + + install(TARGETS mimalloc-static EXPORT mimalloc DESTINATION ${mi_install_objdir} LIBRARY) + install(EXPORT mimalloc DESTINATION ${mi_install_cmakedir}) +endif() + +# install include files +install(FILES include/mimalloc.h DESTINATION ${mi_install_incdir}) +install(FILES include/mimalloc-override.h DESTINATION ${mi_install_incdir}) +install(FILES include/mimalloc-new-delete.h DESTINATION ${mi_install_incdir}) +install(FILES cmake/mimalloc-config.cmake DESTINATION ${mi_install_cmakedir}) +install(FILES cmake/mimalloc-config-version.cmake DESTINATION ${mi_install_cmakedir}) + + +# single object file for more predictable static overriding +if (MI_BUILD_OBJECT) + add_library(mimalloc-obj OBJECT src/static.c) + set_property(TARGET mimalloc-obj PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(mimalloc-obj PRIVATE ${mi_defines}) + target_compile_options(mimalloc-obj PRIVATE ${mi_cflags}) + target_include_directories(mimalloc-obj PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${mi_install_incdir}> + ) + + # Copy the generated object file (`static.o`) to the output directory (as `mimalloc.o`) + if(NOT WIN32) + set(mimalloc-obj-static "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/mimalloc-obj.dir/src/static.c${CMAKE_C_OUTPUT_EXTENSION}") + set(mimalloc-obj-out "${CMAKE_CURRENT_BINARY_DIR}/${mi_basename}${CMAKE_C_OUTPUT_EXTENSION}") + add_custom_command(OUTPUT ${mimalloc-obj-out} DEPENDS mimalloc-obj COMMAND "${CMAKE_COMMAND}" -E copy "${mimalloc-obj-static}" "${mimalloc-obj-out}") + add_custom_target(mimalloc-obj-target ALL DEPENDS ${mimalloc-obj-out}) + endif() + + # the following seems to lead to cmake warnings/errors on some systems, disable for now :-( + # install(TARGETS mimalloc-obj EXPORT mimalloc DESTINATION ${mi_install_objdir}) + + # the FILES expression can also be: $<TARGET_OBJECTS:mimalloc-obj> + # but that fails cmake versions less than 3.10 so we leave it as is for now + install(FILES ${mimalloc-obj-static} + DESTINATION ${mi_install_objdir} + RENAME ${mi_basename}${CMAKE_C_OUTPUT_EXTENSION} ) +endif() + +# pkg-config file support +include("cmake/JoinPaths.cmake") +join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") +join_paths(libdir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_LIBDIR}") + +configure_file(mimalloc.pc.in mimalloc.pc @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mimalloc.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/") + +# ----------------------------------------------------------------------------- +# API surface testing +# ----------------------------------------------------------------------------- + +if (MI_BUILD_TESTS) + enable_testing() + + foreach(TEST_NAME api api-fill stress) + add_executable(mimalloc-test-${TEST_NAME} test/test-${TEST_NAME}.c) + target_compile_definitions(mimalloc-test-${TEST_NAME} PRIVATE ${mi_defines}) + target_compile_options(mimalloc-test-${TEST_NAME} PRIVATE ${mi_cflags}) + target_include_directories(mimalloc-test-${TEST_NAME} PRIVATE include) + target_link_libraries(mimalloc-test-${TEST_NAME} PRIVATE mimalloc ${mi_libraries}) + + add_test(NAME test-${TEST_NAME} COMMAND mimalloc-test-${TEST_NAME}) + endforeach() +endif() + +# ----------------------------------------------------------------------------- +# Set override properties +# ----------------------------------------------------------------------------- +if (MI_OVERRIDE) + if (MI_BUILD_SHARED) + target_compile_definitions(mimalloc PRIVATE MI_MALLOC_OVERRIDE) + endif() + if(NOT WIN32) + # It is only possible to override malloc on Windows when building as a DLL. + if (MI_BUILD_STATIC) + target_compile_definitions(mimalloc-static PRIVATE MI_MALLOC_OVERRIDE) + endif() + if (MI_BUILD_OBJECT) + target_compile_definitions(mimalloc-obj PRIVATE MI_MALLOC_OVERRIDE) + endif() + endif() +endif() diff --git a/lib/Utils.Memory/mimalloc/LICENSE b/lib/Utils.Memory/mimalloc/LICENSE new file mode 100644 index 0000000..670b668 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen + +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. diff --git a/lib/Utils.Memory/mimalloc/SECURITY.md b/lib/Utils.Memory/mimalloc/SECURITY.md new file mode 100644 index 0000000..e138ec5 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/SECURITY.md @@ -0,0 +1,41 @@ +<!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 BLOCK --> + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + +<!-- END MICROSOFT SECURITY.MD BLOCK --> diff --git a/lib/Utils.Memory/mimalloc/azure-pipelines.yml b/lib/Utils.Memory/mimalloc/azure-pipelines.yml new file mode 100644 index 0000000..0247c76 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/azure-pipelines.yml @@ -0,0 +1,197 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: + branches: + include: + - master + - dev + - dev-slice + tags: + include: + - v* + +jobs: +- job: + displayName: Windows + pool: + vmImage: + windows-2022 + strategy: + matrix: + Debug: + BuildType: debug + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + MSBuildConfiguration: Debug + Release: + BuildType: release + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + MSBuildConfiguration: Release + Secure: + BuildType: secure + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + MSBuildConfiguration: Release + steps: + - task: CMake@1 + inputs: + workingDirectory: $(BuildType) + cmakeArgs: .. $(cmakeExtraArgs) + - task: MSBuild@1 + inputs: + solution: $(BuildType)/libmimalloc.sln + configuration: '$(MSBuildConfiguration)' + msbuildArguments: -m + - script: ctest --verbose --timeout 120 -C $(MSBuildConfiguration) + workingDirectory: $(BuildType) + displayName: CTest + #- script: $(BuildType)\$(BuildType)\mimalloc-test-stress + # displayName: TestStress + #- upload: $(Build.SourcesDirectory)/$(BuildType) + # artifact: mimalloc-windows-$(BuildType) + +- job: + displayName: Linux + pool: + vmImage: + ubuntu-22.04 + strategy: + matrix: + Debug: + CC: gcc + CXX: g++ + BuildType: debug + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + Release: + CC: gcc + CXX: g++ + BuildType: release + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + Secure: + CC: gcc + CXX: g++ + BuildType: secure + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + Debug++: + CC: gcc + CXX: g++ + BuildType: debug-cxx + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON -DMI_USE_CXX=ON + Debug Clang: + CC: clang + CXX: clang++ + BuildType: debug-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + Release Clang: + CC: clang + CXX: clang++ + BuildType: release-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + Secure Clang: + CC: clang + CXX: clang++ + BuildType: secure-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + Debug++ Clang: + CC: clang + CXX: clang++ + BuildType: debug-clang-cxx + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON -DMI_USE_CXX=ON + Debug ASAN Clang: + CC: clang + CXX: clang++ + BuildType: debug-asan-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON -DMI_TRACK_ASAN=ON + Debug UBSAN Clang: + CC: clang + CXX: clang++ + BuildType: debug-ubsan-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON -DMI_DEBUG_UBSAN=ON + Debug TSAN Clang++: + CC: clang + CXX: clang++ + BuildType: debug-tsan-clang-cxx + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_USE_CXX=ON -DMI_DEBUG_TSAN=ON + + steps: + - task: CMake@1 + inputs: + workingDirectory: $(BuildType) + cmakeArgs: .. $(cmakeExtraArgs) + - script: make -j$(nproc) -C $(BuildType) + displayName: Make + - script: ctest --verbose --timeout 180 + workingDirectory: $(BuildType) + displayName: CTest +# - upload: $(Build.SourcesDirectory)/$(BuildType) +# artifact: mimalloc-ubuntu-$(BuildType) + +- job: + displayName: macOS + pool: + vmImage: + macOS-latest + strategy: + matrix: + Debug: + BuildType: debug + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + Release: + BuildType: release + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + Secure: + BuildType: secure + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + steps: + - task: CMake@1 + inputs: + workingDirectory: $(BuildType) + cmakeArgs: .. $(cmakeExtraArgs) + - script: make -j$(sysctl -n hw.ncpu) -C $(BuildType) + displayName: Make + # - script: MIMALLOC_VERBOSE=1 ./mimalloc-test-api + # workingDirectory: $(BuildType) + # displayName: TestAPI + # - script: MIMALLOC_VERBOSE=1 ./mimalloc-test-stress + # workingDirectory: $(BuildType) + # displayName: TestStress + - script: ctest --verbose --timeout 120 + workingDirectory: $(BuildType) + displayName: CTest + +# - upload: $(Build.SourcesDirectory)/$(BuildType) +# artifact: mimalloc-macos-$(BuildType) + +# - job: +# displayName: Windows-2017 +# pool: +# vmImage: +# vs2017-win2016 +# strategy: +# matrix: +# Debug: +# BuildType: debug +# cmakeExtraArgs: -A x64 -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON +# MSBuildConfiguration: Debug +# Release: +# BuildType: release +# cmakeExtraArgs: -A x64 -DCMAKE_BUILD_TYPE=Release +# MSBuildConfiguration: Release +# Secure: +# BuildType: secure +# cmakeExtraArgs: -A x64 -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON +# MSBuildConfiguration: Release +# steps: +# - task: CMake@1 +# inputs: +# workingDirectory: $(BuildType) +# cmakeArgs: .. $(cmakeExtraArgs) +# - task: MSBuild@1 +# inputs: +# solution: $(BuildType)/libmimalloc.sln +# configuration: '$(MSBuildConfiguration)' +# - script: | +# cd $(BuildType) +# ctest --verbose --timeout 120 +# displayName: CTest diff --git a/lib/Utils.Memory/mimalloc/cmake/JoinPaths.cmake b/lib/Utils.Memory/mimalloc/cmake/JoinPaths.cmake new file mode 100644 index 0000000..c68d91b --- /dev/null +++ b/lib/Utils.Memory/mimalloc/cmake/JoinPaths.cmake @@ -0,0 +1,23 @@ +# This module provides function for joining paths +# known from most languages +# +# SPDX-License-Identifier: (MIT OR CC0-1.0) +# Copyright 2020 Jan Tojnar +# https://github.com/jtojnar/cmake-snips +# +# Modelled after Python’s os.path.join +# https://docs.python.org/3.7/library/os.path.html#os.path.join +# Windows not supported +function(join_paths joined_path first_path_segment) + set(temp_path "${first_path_segment}") + foreach(current_segment IN LISTS ARGN) + if(NOT ("${current_segment}" STREQUAL "")) + if(IS_ABSOLUTE "${current_segment}") + set(temp_path "${current_segment}") + else() + set(temp_path "${temp_path}/${current_segment}") + endif() + endif() + endforeach() + set(${joined_path} "${temp_path}" PARENT_SCOPE) +endfunction() diff --git a/lib/Utils.Memory/mimalloc/cmake/mimalloc-config-version.cmake b/lib/Utils.Memory/mimalloc/cmake/mimalloc-config-version.cmake new file mode 100644 index 0000000..a44c121 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/cmake/mimalloc-config-version.cmake @@ -0,0 +1,19 @@ +set(mi_version_major 2) +set(mi_version_minor 1) +set(mi_version_patch 2) +set(mi_version ${mi_version_major}.${mi_version_minor}) + +set(PACKAGE_VERSION ${mi_version}) +if(PACKAGE_FIND_VERSION_MAJOR) + if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "${mi_version_major}") + if ("${PACKAGE_FIND_VERSION_MINOR}" EQUAL "${mi_version_minor}") + set(PACKAGE_VERSION_EXACT TRUE) + elseif("${PACKAGE_FIND_VERSION_MINOR}" LESS "${mi_version_minor}") + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_UNSUITABLE TRUE) + endif() + else() + set(PACKAGE_VERSION_UNSUITABLE TRUE) + endif() +endif() diff --git a/lib/Utils.Memory/mimalloc/cmake/mimalloc-config.cmake b/lib/Utils.Memory/mimalloc/cmake/mimalloc-config.cmake new file mode 100644 index 0000000..a49b02a --- /dev/null +++ b/lib/Utils.Memory/mimalloc/cmake/mimalloc-config.cmake @@ -0,0 +1,14 @@ +include(${CMAKE_CURRENT_LIST_DIR}/mimalloc.cmake) +get_filename_component(MIMALLOC_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}" PATH) # one up from the cmake dir, e.g. /usr/local/lib/cmake/mimalloc-2.0 +get_filename_component(MIMALLOC_VERSION_DIR "${CMAKE_CURRENT_LIST_DIR}" NAME) +string(REPLACE "/lib/cmake" "/lib" MIMALLOC_LIBRARY_DIR "${MIMALLOC_CMAKE_DIR}") +if("${MIMALLOC_VERSION_DIR}" EQUAL "mimalloc") + # top level install + string(REPLACE "/lib/cmake" "/include" MIMALLOC_INCLUDE_DIR "${MIMALLOC_CMAKE_DIR}") + set(MIMALLOC_OBJECT_DIR "${MIMALLOC_LIBRARY_DIR}") +else() + # versioned + string(REPLACE "/lib/cmake/" "/include/" MIMALLOC_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}") + string(REPLACE "/lib/cmake/" "/lib/" MIMALLOC_OBJECT_DIR "${CMAKE_CURRENT_LIST_DIR}") +endif() +set(MIMALLOC_TARGET_DIR "${MIMALLOC_LIBRARY_DIR}") # legacy diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg new file mode 100644 index 0000000..9005097 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg @@ -0,0 +1,887 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='167.731pt' version='1.1' viewBox='52.938 54.996 381.624 167.731' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip1'> +<path d='M82.148 206.586H434.164V81.34H82.148Z'/> +</clipPath> +<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/> +<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/> +<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/> +<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/> +<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/> +<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/> +<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/> +<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/> +<use id='g3-102' transform='scale(1.143)' xlink:href='#g0-102'/> +<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/> +<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/> +<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/> +<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/> +<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/> +<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/> +<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/> +<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/> +<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/> +<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/> +<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/> +<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/> +<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/> +<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/> +<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/> +<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/> +<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/> +<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/> +<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/> +<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/> +<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/> +<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/> +<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/> +<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/> +<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/> +<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/> +<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/> +<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/> +<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/> +<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/> +<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/> +<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/> +<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/> +<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/> +<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/> +<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/> +<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/> +<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/> +<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/> +<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/> +<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/> +<path d='M1.325 -2.657H2.12V-3.096H1.304V-3.898C1.304 -4.38 1.743 -4.449 1.974 -4.449C2.12 -4.449 2.308 -4.428 2.566 -4.331V-4.84C2.385 -4.882 2.169 -4.91 1.981 -4.91C1.262 -4.91 0.739 -4.394 0.739 -3.703V-3.096H0.202V-2.657H0.739V0H1.325V-2.657Z' id='g0-102'/> +<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/> +<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/> +<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/> +<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/> +<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/> +<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/> +<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/> +<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/> +<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/> +<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/> +</defs> +<g id='page1'> +<path d='M140.82 215.441V206.586M199.488 215.441V206.586M258.156 215.441V206.586M316.824 215.441V206.586M375.496 215.441V206.586M140.82 72.48V81.34M199.488 72.48V81.34M258.156 72.48V81.34M316.824 72.48V81.34M375.496 72.48V81.34' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 210.836V206.586M170.152 210.836V206.586M228.824 210.836V206.586M287.492 210.836V206.586M346.16 210.836V206.586M404.828 210.836V206.586M111.484 77.086V81.34M170.152 77.086V81.34M228.824 77.086V81.34M287.492 77.086V81.34M346.16 77.086V81.34M404.828 77.086V81.34' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 206.586H86.402M82.148 175.273H86.402M82.148 143.961H86.402M82.148 112.648H86.402M82.148 81.34H86.402M434.164 206.586H429.91M434.164 175.273H429.91M434.164 143.961H429.91M434.164 112.648H429.91M434.164 81.34H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 206.586V81.34H434.164V206.586H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 34.954)'> +<use x='114.487' xlink:href='#g3-99' y='186.027'/> +<use x='118.25' xlink:href='#g3-102' y='186.027'/> +<use x='120.838' xlink:href='#g3-114' y='186.027'/> +<use x='123.73' xlink:href='#g3-97' y='186.027'/> +<use x='127.798' xlink:href='#g3-99' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 45.565 34.954)'> +<use x='114.487' xlink:href='#g3-108' y='186.027'/> +<use x='116.507' xlink:href='#g3-101' y='186.027'/> +<use x='120.271' xlink:href='#g3-97' y='186.027'/> +<use x='124.339' xlink:href='#g3-110' y='186.027'/> +<use x='128.711' xlink:href='#g3-78' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 106.188 34.954)'> +<use x='114.487' xlink:href='#g3-114' y='186.027'/> +<use x='117.379' xlink:href='#g3-101' y='186.027'/> +<use x='121.142' xlink:href='#g3-100' y='186.027'/> +<use x='125.515' xlink:href='#g3-105' y='186.027'/> +<use x='127.535' xlink:href='#g3-115' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 159.716 34.954)'> +<use x='114.487' xlink:href='#g3-108' y='186.027'/> +<use x='116.507' xlink:href='#g3-97' y='186.027'/> +<use x='120.34' xlink:href='#g3-114' y='186.027'/> +<use x='123.232' xlink:href='#g3-115' y='186.027'/> +<use x='126.478' xlink:href='#g3-111' y='186.027'/> +<use x='130.712' xlink:href='#g3-110' y='186.027'/> +<use x='135.085' xlink:href='#g3-78' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 215.596 34.954)'> +<use x='114.487' xlink:href='#g3-109' y='186.027'/> +<use x='121.211' xlink:href='#g3-115' y='186.027'/> +<use x='124.458' xlink:href='#g3-116' y='186.027'/> +<use x='127.516' xlink:href='#g3-114' y='186.027'/> +<use x='130.408' xlink:href='#g3-101' y='186.027'/> +<use x='134.171' xlink:href='#g3-115' y='186.027'/> +<use x='137.418' xlink:href='#g3-115' y='186.027'/> +<use x='140.664' xlink:href='#g3-78' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 277.158 34.954)'> +<use x='114.487' xlink:href='#g3-114' y='186.027'/> +<use x='117.379' xlink:href='#g3-112' y='186.027'/> +<use x='121.751' xlink:href='#g3-116' y='186.027'/> +<use x='124.809' xlink:href='#g3-101' y='186.027'/> +<use x='128.573' xlink:href='#g3-115' y='186.027'/> +<use x='131.819' xlink:href='#g3-116' y='186.027'/> +<use x='134.877' xlink:href='#g3-78' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 22.192)'> +<use x='114.487' xlink:href='#g2-48' y='186.027'/> +<use x='117.133' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.12)'> +<use x='114.487' xlink:href='#g2-48' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-53' y='186.027'/> +<use x='121.25' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.431)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.743)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-53' y='186.027'/> +<use x='121.25' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.054)'> +<use x='114.487' xlink:href='#g2-50' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-120' y='186.027'/> +</g> +<path clip-path='url(#clip1)' d='M82.148 143.961H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M88.945 206.586H92.18V143.961H88.945ZM147.613 206.586H150.852V143.961H147.613ZM206.281 206.586H209.52V143.961H206.281ZM264.949 206.586H268.188V143.961H264.949ZM323.621 206.586H326.859V143.961H323.621ZM382.289 206.586H385.527V143.961H382.289Z' fill='#993333'/> +<path clip-path='url(#clip1)' d='M88.945 206.586H92.18V143.961H88.945ZM147.613 206.586H150.852V143.961H147.613ZM206.281 206.586H209.52V143.961H206.281ZM264.949 206.586H268.188V143.961H264.949ZM323.621 206.586H326.859V143.961H323.621ZM382.289 206.586H385.527V143.961H382.289Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M90.563 143.961V143.898' fill='#993333'/> +<path clip-path='url(#clip1)' d='M90.563 143.961V143.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M88.57 143.898H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M90.563 143.961V144.023' fill='#993333'/> +<path clip-path='url(#clip1)' d='M90.563 143.961V144.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M92.555 144.024H88.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M149.231 143.961V143.523' fill='#993333'/> +<path clip-path='url(#clip1)' d='M149.231 143.961V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M147.238 143.524H151.226' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M149.231 143.961V144.398' fill='#993333'/> +<path clip-path='url(#clip1)' d='M149.231 143.961V144.398' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M151.223 144.398H147.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M207.902 143.961V142.207' fill='#993333'/> +<path clip-path='url(#clip1)' d='M207.902 143.961V142.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M205.91 142.207H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M207.902 143.961V145.715' fill='#993333'/> +<path clip-path='url(#clip1)' d='M207.902 143.961V145.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M209.891 145.715H205.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M266.57 143.961V143.336' fill='#993333'/> +<path clip-path='url(#clip1)' d='M266.57 143.961V143.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M264.578 143.336H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M266.57 143.961V144.586' fill='#993333'/> +<path clip-path='url(#clip1)' d='M266.57 143.961V144.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M268.563 144.586H264.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M325.238 143.961V143.586' fill='#993333'/> +<path clip-path='url(#clip1)' d='M325.238 143.961V143.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M323.246 143.586H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M325.238 143.961V144.336' fill='#993333'/> +<path clip-path='url(#clip1)' d='M325.238 143.961V144.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M327.231 144.336H323.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M383.906 143.961V143.523' fill='#993333'/> +<path clip-path='url(#clip1)' d='M383.906 143.961V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M381.914 143.524H385.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M383.906 143.961V144.398' fill='#993333'/> +<path clip-path='url(#clip1)' d='M383.906 143.961V144.398' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M385.898 144.398H381.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M94.176 206.586H97.41V142.519H94.176ZM152.844 206.586H156.082V140.203H152.844ZM211.512 206.586H214.75V148.344H211.512ZM270.18 206.586H273.418V121.418H270.18ZM328.852 206.586H332.09V135.07H328.852ZM387.52 206.586H390.758V81.34H387.52Z' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M94.176 206.586H97.41V142.519H94.176ZM152.844 206.586H156.082V140.203H152.844ZM211.512 206.586H214.75V148.344H211.512ZM270.18 206.586H273.418V121.418H270.18ZM328.852 206.586H332.09V135.07H328.852ZM387.52 206.586H390.758V81.34H387.52Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M95.793 142.519V142.519' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M93.801 142.52H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M95.793 142.519V142.519' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M93.801 142.52H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M154.461 140.203V139.203' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M154.461 140.203V139.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M152.469 139.203H156.457' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M154.461 140.203V141.207' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M154.461 140.203V141.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M156.453 141.207H152.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M213.133 148.344V148.031' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M213.133 148.344V148.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M211.141 148.032H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M213.133 148.344V148.656' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M213.133 148.344V148.656' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M215.121 148.656H211.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M271.801 121.418V121.23' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M271.801 121.418V121.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M269.809 121.23H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M271.801 121.418V121.605' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M271.801 121.418V121.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M273.793 121.606H269.808' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M330.469 135.07V134.254' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M330.469 135.07V134.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M328.477 134.254H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M330.469 135.07V135.883' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M330.469 135.07V135.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M332.461 135.883H328.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M389.137 81.34V81.34' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M387.145 81.34H391.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M389.137 81.34V81.34' fill='#8080bf'/> +<path clip-path='url(#clip1)' d='M387.145 81.34H391.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M99.406 206.586H102.641V140.266H99.406ZM158.074 206.586H161.313V142.898H158.074ZM216.742 206.586H219.981V134.754H216.742ZM275.41 206.586H278.649V99.25H275.41ZM334.082 206.586H337.32V81.34H334.082ZM392.75 206.586H395.988V81.34H392.75Z' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M99.406 206.586H102.641V140.266H99.406ZM158.074 206.586H161.313V142.898H158.074ZM216.742 206.586H219.981V134.754H216.742ZM275.41 206.586H278.649V99.25H275.41ZM334.082 206.586H337.32V81.34H334.082ZM392.75 206.586H395.988V81.34H392.75Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M101.024 140.266V140.203' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M101.024 140.266V140.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M99.031 140.203H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M101.024 140.266V140.328' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M101.024 140.266V140.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M103.016 140.328H99.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M159.691 142.898V142.269' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M159.691 142.898V142.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M157.699 142.269H161.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M159.691 142.898V143.523' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M159.691 142.898V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M161.684 143.524H157.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M218.363 134.754V134.066' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M218.363 134.754V134.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M216.371 134.067H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M218.363 134.754V135.445' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M218.363 134.754V135.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M220.352 135.445H216.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M277.031 99.25V91.168' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M277.031 99.25V91.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M275.039 91.172H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M277.031 99.25V107.328' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M277.031 99.25V107.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M279.024 107.328H275.039' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M335.699 81.34V81.34' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M333.707 81.34H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M335.699 81.34V81.34' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M333.707 81.34H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M394.367 81.34V81.34' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M392.375 81.34H396.363' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M394.367 81.34V81.34' fill='#ffb733'/> +<path clip-path='url(#clip1)' d='M392.375 81.34H396.363' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M104.637 206.586H107.871V124.859H104.637ZM163.305 206.586H166.543V141.207H163.305ZM221.973 206.586H225.211V118.035H221.973ZM280.641 206.586H283.879V121.043H280.641ZM339.313 206.586H342.551V133.066H339.313ZM397.981 206.586H401.219V89.039H397.981Z' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M104.637 206.586H107.871V124.859H104.637ZM163.305 206.586H166.543V141.207H163.305ZM221.973 206.586H225.211V118.035H221.973ZM280.641 206.586H283.879V121.043H280.641ZM339.313 206.586H342.551V133.066H339.313ZM397.981 206.586H401.219V89.039H397.981Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M106.254 124.859V124.797' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M106.254 124.859V124.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M104.261 124.796H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M106.254 124.859V124.922' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M106.254 124.859V124.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M108.246 124.922H104.261' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M164.922 141.207V140.894' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M164.922 141.207V140.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M162.929 140.895H166.917' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M164.922 141.207V141.519' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M164.922 141.207V141.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M166.914 141.52H162.929' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M223.594 118.035V117.973' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M223.594 118.035V117.973' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M221.601 117.973H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M223.594 118.035V118.098' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M223.594 118.035V118.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M225.582 118.098H221.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M282.262 121.043V120.539' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M282.262 121.043V120.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M280.269 120.539H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M282.262 121.043V121.543' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M282.262 121.043V121.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M284.254 121.543H280.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M340.93 133.066V132.812' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M340.93 133.066V132.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M338.937 132.812H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M340.93 133.066V133.316' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M340.93 133.066V133.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M342.922 133.316H338.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M399.598 89.039V88.539' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M399.598 89.039V88.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M397.605 88.539H401.593' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M399.598 89.039V89.543' fill='#bf80bf'/> +<path clip-path='url(#clip1)' d='M399.598 89.039V89.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M401.59 89.543H397.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M109.867 206.586H113.102V142.332H109.867ZM168.535 206.586H171.774V143.086H168.535ZM227.203 206.586H230.442V132.125H227.203ZM285.871 206.586H289.109V139.641H285.871ZM344.543 206.586H347.781V81.34H344.543ZM403.211 206.586H406.449V100.187H403.211Z' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M109.867 206.586H113.102V142.332H109.867ZM168.535 206.586H171.774V143.086H168.535ZM227.203 206.586H230.442V132.125H227.203ZM285.871 206.586H289.109V139.641H285.871ZM344.543 206.586H347.781V81.34H344.543ZM403.211 206.586H406.449V100.187H403.211Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M111.484 142.332V142.269' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M111.484 142.332V142.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M109.492 142.269H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M111.484 142.332V142.394' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M111.484 142.332V142.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M113.477 142.395H109.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M170.152 143.086V142.644' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M170.152 143.086V142.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M168.16 142.644H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M170.152 143.086V143.523' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M170.152 143.086V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M172.145 143.524H168.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M228.824 132.125V131.312' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M228.824 132.125V131.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M226.832 131.312H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M228.824 132.125V132.941' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M228.824 132.125V132.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M230.813 132.941H226.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M287.492 139.641V138.387' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M287.492 139.641V138.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M285.5 138.387H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M287.492 139.641V140.894' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M287.492 139.641V140.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M289.485 140.895H285.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M346.16 81.34V81.34' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M344.168 81.34H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M346.16 81.34V81.34' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M344.168 81.34H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M404.828 100.187V99.562' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M404.828 100.187V99.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M402.836 99.562H406.824' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M404.828 100.187V100.812' fill='#dfbf9f'/> +<path clip-path='url(#clip1)' d='M404.828 100.187V100.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M406.821 100.813H402.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M115.098 206.586H118.332V135.57H115.098ZM173.766 206.586H177.004V136.07H173.766ZM232.434 206.586H235.672V114.965H232.434ZM291.102 206.586H294.34V113.84H291.102ZM349.774 206.586H353.012V81.34H349.774ZM408.442 206.586H411.68V81.34H408.442Z' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M115.098 206.586H118.332V135.57H115.098ZM173.766 206.586H177.004V136.07H173.766ZM232.434 206.586H235.672V114.965H232.434ZM291.102 206.586H294.34V113.84H291.102ZM349.774 206.586H353.012V81.34H349.774ZM408.442 206.586H411.68V81.34H408.442Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M116.715 135.57V135.508' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M116.715 135.57V135.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M114.722 135.508H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M116.715 135.57V135.633' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M116.715 135.57V135.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M118.707 135.633H114.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M175.383 136.07V135.258' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M175.383 136.07V135.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M173.39 135.258H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M175.383 136.07V136.883' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M175.383 136.07V136.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M177.375 136.883H173.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M234.055 114.965V114.09' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M234.055 114.965V114.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M232.062 114.09H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M234.055 114.965V115.844' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M234.055 114.965V115.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M236.043 115.843H232.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M292.723 113.84V113.215' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M292.723 113.84V113.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M290.73 113.215H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M292.723 113.84V114.465' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M292.723 113.84V114.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M294.715 114.465H290.73' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M351.391 81.34V81.34' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M349.398 81.34H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M351.391 81.34V81.34' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M349.398 81.34H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M410.059 81.34V81.34' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M408.066 81.34H412.054' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M410.059 81.34V81.34' fill='#80bf80'/> +<path clip-path='url(#clip1)' d='M408.066 81.34H412.054' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M120.328 206.586H123.563V135.633H120.328ZM178.996 206.586H182.234V81.34H178.996ZM237.664 206.586H240.902V138.387H237.664ZM296.332 206.586H299.57V81.34H296.332ZM355.004 206.586H358.238V81.34H355.004ZM413.672 206.586H416.91V81.34H413.672Z' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M120.328 206.586H123.563V135.633H120.328ZM178.996 206.586H182.234V81.34H178.996ZM237.664 206.586H240.902V138.387H237.664ZM296.332 206.586H299.57V81.34H296.332ZM355.004 206.586H358.238V81.34H355.004ZM413.672 206.586H416.91V81.34H413.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M121.945 135.633V135.57' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M121.945 135.633V135.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M119.953 135.571H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M121.945 135.633V135.695' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M121.945 135.633V135.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M123.938 135.695H119.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M180.613 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M178.621 81.34H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M180.613 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M178.621 81.34H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M239.285 138.387V136.195' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M239.285 138.387V136.195' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M237.293 136.195H241.278' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M239.285 138.387V140.578' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M239.285 138.387V140.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M241.274 140.578H237.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M297.953 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M295.961 81.34H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M297.953 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M295.961 81.34H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M356.621 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M354.629 81.34H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M356.621 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M354.629 81.34H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M415.289 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M413.297 81.34H417.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M415.289 81.34V81.34' fill='#bfbf80'/> +<path clip-path='url(#clip1)' d='M413.297 81.34H417.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M125.559 206.586H128.793V139.266H125.559ZM184.227 206.586H187.465V135.695H184.227ZM242.895 206.586H246.133V137.824H242.895ZM301.563 206.586H304.801V97.433H301.563ZM360.234 206.586H363.469V81.34H360.234ZM418.902 206.586H422.141V81.34H418.902Z' fill='#339999'/> +<path clip-path='url(#clip1)' d='M125.559 206.586H128.793V139.266H125.559ZM184.227 206.586H187.465V135.695H184.227ZM242.895 206.586H246.133V137.824H242.895ZM301.563 206.586H304.801V97.433H301.563ZM360.234 206.586H363.469V81.34H360.234ZM418.902 206.586H422.141V81.34H418.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M127.176 139.266V139.203' fill='#339999'/> +<path clip-path='url(#clip1)' d='M127.176 139.266V139.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M125.183 139.203H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M127.176 139.266V139.328' fill='#339999'/> +<path clip-path='url(#clip1)' d='M127.176 139.266V139.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M129.168 139.328H125.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M185.844 135.695V135.258' fill='#339999'/> +<path clip-path='url(#clip1)' d='M185.844 135.695V135.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M183.851 135.258H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M185.844 135.695V136.133' fill='#339999'/> +<path clip-path='url(#clip1)' d='M185.844 135.695V136.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M187.836 136.133H183.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M244.516 137.824V137.012' fill='#339999'/> +<path clip-path='url(#clip1)' d='M244.516 137.824V137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M242.523 137.012H246.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M244.516 137.824V138.637' fill='#339999'/> +<path clip-path='url(#clip1)' d='M244.516 137.824V138.637' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M246.504 138.637H242.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M303.184 97.433V95.617' fill='#339999'/> +<path clip-path='url(#clip1)' d='M303.184 97.433V95.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M301.191 95.617H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M303.184 97.433V99.25' fill='#339999'/> +<path clip-path='url(#clip1)' d='M303.184 97.433V99.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M305.176 99.25H301.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M361.852 81.34V81.34' fill='#339999'/> +<path clip-path='url(#clip1)' d='M359.859 81.34H363.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M361.852 81.34V81.34' fill='#339999'/> +<path clip-path='url(#clip1)' d='M359.859 81.34H363.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M420.52 81.34V81.34' fill='#339999'/> +<path clip-path='url(#clip1)' d='M418.527 81.34H422.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M420.52 81.34V81.34' fill='#339999'/> +<path clip-path='url(#clip1)' d='M418.527 81.34H422.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M130.789 206.586H134.024V136.508H130.789ZM189.457 206.586H192.695V143.023H189.457ZM248.125 206.586H251.363V139.391H248.125ZM306.793 206.586H310.031V134.191H306.793ZM365.465 206.586H368.699V81.34H365.465ZM424.133 206.586H427.371V85.348H424.133Z' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M130.789 206.586H134.024V136.508H130.789ZM189.457 206.586H192.695V143.023H189.457ZM248.125 206.586H251.363V139.391H248.125ZM306.793 206.586H310.031V134.191H306.793ZM365.465 206.586H368.699V81.34H365.465ZM424.133 206.586H427.371V85.348H424.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M132.406 136.508V136.445' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M132.406 136.508V136.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M130.414 136.445H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M132.406 136.508V136.57' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M132.406 136.508V136.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M134.399 136.571H130.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M191.074 143.023V142.582' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M191.074 143.023V142.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M189.082 142.582H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M191.074 143.023V143.461' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M191.074 143.023V143.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M193.067 143.461H189.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M249.746 139.391V136.383' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M249.746 139.391V136.383' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M247.754 136.383H251.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M249.746 139.391V142.394' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M249.746 139.391V142.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M251.735 142.395H247.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M308.414 134.191V131.875' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M308.414 134.191V131.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M306.422 131.875H310.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M308.414 134.191V136.508' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M308.414 134.191V136.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M310.407 136.508H306.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M367.082 81.34V81.34' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M365.09 81.34H369.075' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M367.082 81.34V81.34' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M365.09 81.34H369.075' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M425.75 85.348V72.633' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M425.75 85.348V72.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M423.758 72.633H427.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M425.75 85.348V98.058' fill='#bf8080'/> +<path clip-path='url(#clip1)' d='M425.75 85.348V98.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M427.743 98.059H423.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -93.83 252.423)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -35.161 252.423)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 23.508 252.423)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 82.177 252.423)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 140.846 252.423)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 199.515 252.423)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -88.6 250.983)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-50' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -29.93 248.666)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-54' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 28.739 256.807)'> +<use x='114.487' xlink:href='#g2-48' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-57' y='186.027'/> +<use x='121.25' xlink:href='#g2-51' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 87.408 229.879)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-51' y='186.027'/> +<use x='121.25' xlink:href='#g2-54' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 146.077 243.531)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-52' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 204.746 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-53' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-56' y='186.027'/> +<use x='126.877' xlink:href='#g2-50' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -83.369 248.729)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-54' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -24.7 251.359)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-50' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 33.969 243.218)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-53' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 92.638 207.711)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-55' y='186.027'/> +<use x='121.25' xlink:href='#g2-49' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 151.307 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-50' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-51' y='186.027'/> +<use x='126.877' xlink:href='#g2-54' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 209.976 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-50' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-57' y='186.027'/> +<use x='126.877' xlink:href='#g2-49' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -78.139 233.323)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-51' y='186.027'/> +<use x='121.25' xlink:href='#g2-49' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -19.47 249.668)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-52' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 39.199 226.497)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-52' y='186.027'/> +<use x='121.25' xlink:href='#g2-49' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 97.868 229.503)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-51' y='186.027'/> +<use x='121.25' xlink:href='#g2-55' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 156.537 241.527)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-55' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 215.206 197.503)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-56' y='186.027'/> +<use x='121.25' xlink:href='#g2-56' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -72.908 250.795)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-51' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -14.239 251.547)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-49' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 44.43 240.588)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-57' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 103.099 248.102)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-55' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 161.768 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-50' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-49' y='186.027'/> +<use x='126.877' xlink:href='#g2-54' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 220.437 208.65)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-55' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -67.678 244.032)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-51' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -9.009 244.533)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-51' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 49.66 223.429)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-52' y='186.027'/> +<use x='121.25' xlink:href='#g2-54' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 108.329 222.302)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-52' y='186.027'/> +<use x='121.25' xlink:href='#g2-56' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 166.998 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-56' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-52' y='186.027'/> +<use x='126.877' xlink:href='#g2-50' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 225.667 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-57' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-57' y='186.027'/> +<use x='126.877' xlink:href='#g2-51' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -62.447 244.095)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-51' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -3.778 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-51' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-54' y='186.027'/> +<use x='126.877' xlink:href='#g2-51' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 54.891 246.85)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-57' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 113.56 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-50' y='186.027'/> +<use x='122.76' xlink:href='#g2-51' y='186.027'/> +<use x='125.406' xlink:href='#g2-46' y='186.027'/> +<use x='126.877' xlink:href='#g2-57' y='186.027'/> +<use x='129.523' xlink:href='#g2-57' y='186.027'/> +<use x='132.169' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 172.229 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-49' y='186.027'/> +<use x='122.76' xlink:href='#g2-56' y='186.027'/> +<use x='125.406' xlink:href='#g2-46' y='186.027'/> +<use x='126.877' xlink:href='#g2-53' y='186.027'/> +<use x='129.523' xlink:href='#g2-52' y='186.027'/> +<use x='132.169' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 230.898 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-51' y='186.027'/> +<use x='122.76' xlink:href='#g2-52' y='186.027'/> +<use x='125.406' xlink:href='#g2-46' y='186.027'/> +<use x='126.877' xlink:href='#g2-52' y='186.027'/> +<use x='129.523' xlink:href='#g2-53' y='186.027'/> +<use x='132.169' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -57.217 247.727)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-56' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 1.452 244.157)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-51' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 60.121 246.286)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-48' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 118.79 205.895)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-55' y='186.027'/> +<use x='121.25' xlink:href='#g2-52' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 177.459 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-52' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-51' y='186.027'/> +<use x='126.877' xlink:href='#g2-51' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 236.128 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-50' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-49' y='186.027'/> +<use x='126.877' xlink:href='#g2-50' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -51.986 244.971)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-50' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 6.683 251.484)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-50' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 65.352 247.852)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-48' y='186.027'/> +<use x='121.25' xlink:href='#g2-55' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 124.021 242.654)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-49' y='186.027'/> +<use x='121.25' xlink:href='#g2-54' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 182.69 189.8)'> +<use x='109.598' xlink:href='#g4-1' y='186.027'/> +<use x='113.103' xlink:href='#g4-1' y='186.027'/> +<use x='116.608' xlink:href='#g4-1' y='186.027'/> +<use x='120.114' xlink:href='#g2-50' y='186.027'/> +<use x='122.76' xlink:href='#g2-46' y='186.027'/> +<use x='124.23' xlink:href='#g2-50' y='186.027'/> +<use x='126.877' xlink:href='#g2-55' y='186.027'/> +<use x='129.523' xlink:href='#g2-120' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 241.359 193.808)'> +<use x='114.487' xlink:href='#g2-49' y='186.027'/> +<use x='117.133' xlink:href='#g2-46' y='186.027'/> +<use x='118.603' xlink:href='#g2-57' y='186.027'/> +<use x='121.25' xlink:href='#g2-52' y='186.027'/> +</g> +<g transform='matrix(0 -1 1 0 -126.667 313.708)'> +<use x='114.487' xlink:href='#g1-82' y='186.027'/> +<use x='120.457' xlink:href='#g1-101' y='186.027'/> +<use x='124.553' xlink:href='#g1-108' y='186.027'/> +<use x='126.753' xlink:href='#g1-97' y='186.027'/> +<use x='131.181' xlink:href='#g1-116' y='186.027'/> +<use x='134.509' xlink:href='#g1-105' y='186.027'/> +<use x='136.709' xlink:href='#g1-118' y='186.027'/> +<use x='140.957' xlink:href='#g1-101' y='186.027'/> +<use x='148.124' xlink:href='#g1-116' y='186.027'/> +<use x='151.452' xlink:href='#g1-105' y='186.027'/> +<use x='153.652' xlink:href='#g1-109' y='186.027'/> +<use x='160.972' xlink:href='#g1-101' y='186.027'/> +<use x='168.139' xlink:href='#g3-40' y='186.027'/> +<use x='171.432' xlink:href='#g3-108' y='186.027'/> +<use x='173.453' xlink:href='#g3-111' y='186.027'/> +<use x='177.452' xlink:href='#g3-119' y='186.027'/> +<use x='183' xlink:href='#g3-101' y='186.027'/> +<use x='186.764' xlink:href='#g3-114' y='186.027'/> +<use x='192.479' xlink:href='#g3-105' y='186.027'/> +<use x='194.499' xlink:href='#g3-115' y='186.027'/> +<use x='200.568' xlink:href='#g3-98' y='186.027'/> +<use x='205.176' xlink:href='#g3-101' y='186.027'/> +<use x='208.94' xlink:href='#g3-116' y='186.027'/> +<use x='211.998' xlink:href='#g3-116' y='186.027'/> +<use x='215.056' xlink:href='#g3-101' y='186.027'/> +<use x='218.819' xlink:href='#g3-114' y='186.027'/> +<use x='221.711' xlink:href='#g3-41' y='186.027'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg new file mode 100644 index 0000000..2d853ed --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg @@ -0,0 +1,1185 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='258.383pt' version='1.1' viewBox='106.736 54.996 381.623 258.383' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip2'> +<path d='M135.949 251.93H487.961V84.164H135.949Z'/> +</clipPath> +<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/> +<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/> +<use id='g3-45' transform='scale(1.143)' xlink:href='#g0-45'/> +<use id='g3-49' transform='scale(1.143)' xlink:href='#g0-49'/> +<use id='g3-54' transform='scale(1.143)' xlink:href='#g0-54'/> +<use id='g3-56' transform='scale(1.143)' xlink:href='#g0-56'/> +<use id='g3-58' transform='scale(1.143)' xlink:href='#g0-58'/> +<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/> +<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/> +<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/> +<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/> +<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/> +<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/> +<use id='g3-103' transform='scale(1.143)' xlink:href='#g0-103'/> +<use id='g3-104' transform='scale(1.143)' xlink:href='#g0-104'/> +<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/> +<use id='g3-106' transform='scale(1.143)' xlink:href='#g0-106'/> +<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/> +<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/> +<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/> +<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/> +<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/> +<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/> +<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/> +<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/> +<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/> +<use id='g3-120' transform='scale(1.143)' xlink:href='#g0-120'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/> +<use id='g2-44' transform='scale(0.714)' xlink:href='#g0-44'/> +<use id='g2-45' transform='scale(0.714)' xlink:href='#g0-45'/> +<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/> +<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/> +<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/> +<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/> +<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/> +<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/> +<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/> +<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/> +<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/> +<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/> +<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/> +<use id='g2-64' transform='scale(0.714)' xlink:href='#g0-64'/> +<use id='g2-67' transform='scale(0.714)' xlink:href='#g0-67'/> +<use id='g2-71' transform='scale(0.714)' xlink:href='#g0-71'/> +<use id='g2-73' transform='scale(0.714)' xlink:href='#g0-73'/> +<use id='g2-85' transform='scale(0.714)' xlink:href='#g0-85'/> +<use id='g2-88' transform='scale(0.714)' xlink:href='#g0-88'/> +<use id='g2-97' transform='scale(0.714)' xlink:href='#g0-97'/> +<use id='g2-98' transform='scale(0.714)' xlink:href='#g0-98'/> +<use id='g2-99' transform='scale(0.714)' xlink:href='#g0-99'/> +<use id='g2-100' transform='scale(0.714)' xlink:href='#g0-100'/> +<use id='g2-101' transform='scale(0.714)' xlink:href='#g0-101'/> +<use id='g2-103' transform='scale(0.714)' xlink:href='#g0-103'/> +<use id='g2-104' transform='scale(0.714)' xlink:href='#g0-104'/> +<use id='g2-108' transform='scale(0.714)' xlink:href='#g0-108'/> +<use id='g2-109' transform='scale(0.714)' xlink:href='#g0-109'/> +<use id='g2-110' transform='scale(0.714)' xlink:href='#g0-110'/> +<use id='g2-111' transform='scale(0.714)' xlink:href='#g0-111'/> +<use id='g2-112' transform='scale(0.714)' xlink:href='#g0-112'/> +<use id='g2-114' transform='scale(0.714)' xlink:href='#g0-114'/> +<use id='g2-115' transform='scale(0.714)' xlink:href='#g0-115'/> +<use id='g2-116' transform='scale(0.714)' xlink:href='#g0-116'/> +<use id='g2-117' transform='scale(0.714)' xlink:href='#g0-117'/> +<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/> +<use id='g2-122' transform='scale(0.714)' xlink:href='#g0-122'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/> +<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/> +<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/> +<path d='M1.339 -0.007V-0.628H0.711V0H0.907L0.704 0.893H1.018L1.339 -0.007Z' id='g0-44'/> +<path d='M2.05 -1.332V-1.771H0.084V-1.332H2.05Z' id='g0-45'/> +<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/> +<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/> +<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/> +<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/> +<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/> +<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/> +<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/> +<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/> +<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/> +<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/> +<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/> +<path d='M1.339 -3.096H0.711V-2.469H1.339V-3.096ZM0.711 -0.628V0H1.339V-0.628H0.711Z' id='g0-58'/> +<path d='M4.142 -0.614C4.038 -0.614 4.024 -0.614 3.968 -0.586C3.626 -0.467 3.271 -0.391 2.901 -0.391C1.778 -0.391 0.976 -1.339 0.976 -2.42C0.976 -3.592 1.883 -4.449 2.859 -4.449C3.055 -4.449 3.515 -4.4 3.745 -3.843C3.55 -3.954 3.333 -4.003 3.152 -4.003C2.406 -4.003 1.778 -3.306 1.778 -2.42C1.778 -1.513 2.427 -0.837 3.145 -0.837C3.689 -0.837 4.519 -1.276 4.519 -2.518C4.519 -3.222 4.47 -4.91 2.866 -4.91C1.541 -4.91 0.411 -3.815 0.411 -2.42C0.411 -1.039 1.527 0.07 2.873 0.07C3.515 0.07 4.115 -0.195 4.519 -0.614H4.142ZM3.152 -1.297C2.72 -1.297 2.343 -1.778 2.343 -2.42C2.343 -3.082 2.734 -3.543 3.145 -3.543C3.578 -3.543 3.954 -3.062 3.954 -2.42C3.954 -1.757 3.564 -1.297 3.152 -1.297Z' id='g0-64'/> +<path d='M4.317 -0.851C3.829 -0.551 3.605 -0.418 2.908 -0.418C1.827 -0.418 1.172 -1.43 1.172 -2.434C1.172 -3.466 1.89 -4.435 2.908 -4.435C3.368 -4.435 3.843 -4.289 4.163 -4.045L4.275 -4.679C3.787 -4.861 3.396 -4.917 2.887 -4.917C1.506 -4.917 0.474 -3.773 0.474 -2.427C0.474 -0.99 1.569 0.07 2.929 0.07C3.612 0.07 3.898 -0.07 4.359 -0.321L4.317 -0.851Z' id='g0-67'/> +<path d='M4.442 -2.085H2.88V-1.625H3.829V-0.558C3.522 -0.481 3.222 -0.418 2.908 -0.418C1.834 -0.418 1.172 -1.43 1.172 -2.427C1.172 -3.382 1.82 -4.435 2.873 -4.435C3.515 -4.435 3.919 -4.24 4.268 -3.947L4.38 -4.582C3.898 -4.812 3.473 -4.924 2.943 -4.924C1.534 -4.924 0.474 -3.822 0.474 -2.427C0.474 -1.067 1.527 0.07 2.901 0.07C3.403 0.07 3.996 -0.042 4.442 -0.272V-2.085Z' id='g0-71'/> +<path d='M1.381 -4.84H0.676V0H1.381V-4.84Z' id='g0-73'/> +<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/> +<path d='M4.4 -4.84H3.794V-1.625C3.794 -0.69 3.166 -0.265 2.566 -0.265S1.381 -0.697 1.381 -1.618V-4.84H0.676V-1.632C0.676 -0.607 1.555 0.146 2.559 0.146C3.557 0.146 4.4 -0.614 4.4 -1.632V-4.84Z' id='g0-85'/> +<path d='M2.755 -2.552L4.519 -4.84H3.759L2.413 -3.055L1.039 -4.84H0.209L2.071 -2.552L0.105 0H0.865L2.413 -2.099L3.996 0H4.826L2.755 -2.552Z' id='g0-88'/> +<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/> +<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/> +<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/> +<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/> +<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/> +<path d='M3.508 -3.166C3.354 -3.166 2.887 -3.159 2.357 -2.957L2.343 -2.95C2.092 -3.117 1.848 -3.166 1.646 -3.166C0.962 -3.166 0.453 -2.629 0.453 -2.029C0.453 -1.785 0.537 -1.534 0.697 -1.339C0.6 -1.22 0.495 -1.025 0.495 -0.76C0.495 -0.488 0.607 -0.314 0.669 -0.23C0.286 -0.007 0.209 0.314 0.209 0.481C0.209 1.011 0.941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 0.481C3.487 -0.502 2.267 -0.502 1.967 -0.502H1.318C1.206 -0.502 0.907 -0.502 0.907 -0.865C0.907 -1.004 0.955 -1.074 0.962 -1.088C1.206 -0.934 1.451 -0.886 1.639 -0.886C2.322 -0.886 2.831 -1.423 2.831 -2.022C2.831 -2.246 2.769 -2.448 2.643 -2.636C2.615 -2.678 2.615 -2.685 2.615 -2.692C2.615 -2.72 3.034 -2.72 3.068 -2.72C3.075 -2.72 3.34 -2.72 3.592 -2.692L3.508 -3.166ZM1.646 -1.318C1.269 -1.318 0.99 -1.555 0.99 -2.022C0.99 -2.566 1.339 -2.734 1.639 -2.734C2.015 -2.734 2.294 -2.497 2.294 -2.029C2.294 -1.485 1.946 -1.318 1.646 -1.318ZM1.974 0.042C2.134 0.042 2.957 0.042 2.957 0.488C2.957 0.788 2.434 0.997 1.848 0.997S0.739 0.788 0.739 0.488C0.739 0.453 0.739 0.042 1.304 0.042H1.974Z' id='g0-103'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.625 -3.166 1.304 -2.817 1.165 -2.671V-4.84H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-104'/> +<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/> +<path d='M1.381 -4.784H0.676V-4.08H1.381V-4.784ZM-0.453 1.186C-0.133 1.36 0.181 1.423 0.446 1.423C0.928 1.423 1.381 1.053 1.381 0.411V-3.096H0.795V0.46C0.795 0.586 0.795 0.697 0.649 0.816C0.488 0.934 0.293 0.934 0.23 0.934C-0.063 0.934 -0.244 0.802 -0.328 0.725L-0.453 1.186Z' id='g0-106'/> +<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/> +<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/> +<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/> +<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/> +<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/> +<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/> +<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/> +<path d='M3.243 -3.096H2.636V-1.074C2.636 -0.516 2.162 -0.342 1.757 -0.342C1.241 -0.342 1.186 -0.481 1.186 -0.802V-3.096H0.579V-0.76C0.579 -0.139 0.851 0.07 1.339 0.07C1.625 0.07 2.239 0.014 2.657 -0.321V0H3.243V-3.096Z' id='g0-117'/> +<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/> +<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/> +<path d='M2.957 -2.803V-3.096H0.307V-2.65H1.332C1.416 -2.65 1.499 -2.657 1.583 -2.657H2.127L0.209 -0.307V0H2.978V-0.467H1.897C1.813 -0.467 1.73 -0.46 1.646 -0.46H1.039L2.957 -2.803Z' id='g0-122'/> +</defs> +<g id='page2'> +<path d='M194.617 260.785V251.93M253.285 260.785V251.93M311.953 260.785V251.93M370.625 260.785V251.93M429.293 260.785V251.93M194.617 75.308V84.164M253.285 75.308V84.164M311.953 75.308V84.164M370.625 75.308V84.164M429.293 75.308V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 256.18V251.93M223.953 256.18V251.93M282.621 256.18V251.93M341.289 256.18V251.93M399.957 256.18V251.93M458.629 256.18V251.93M165.281 79.91V84.164M223.953 79.91V84.164M282.621 79.91V84.164M341.289 79.91V84.164M399.957 79.91V84.164M458.629 79.91V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 251.93H140.199M135.949 218.375H140.199M135.949 184.824H140.199M135.949 151.269H140.199M135.949 117.719H140.199M135.949 84.164H140.199M487.961 251.93H483.711M487.961 218.375H483.711M487.961 184.824H483.711M487.961 151.269H483.711M487.961 117.719H483.711M487.961 84.164H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 251.93V84.164H487.961V251.93H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 74.992)'> +<use x='168.285' xlink:href='#g3-97' y='191.334'/> +<use x='172.353' xlink:href='#g3-108' y='191.334'/> +<use x='174.373' xlink:href='#g3-108' y='191.334'/> +<use x='176.393' xlink:href='#g3-111' y='191.334'/> +<use x='180.863' xlink:href='#g3-99' y='191.334'/> +<use x='184.627' xlink:href='#g3-45' y='191.334'/> +<use x='187.449' xlink:href='#g3-116' y='191.334'/> +<use x='190.507' xlink:href='#g3-101' y='191.334'/> +<use x='194.271' xlink:href='#g3-115' y='191.334'/> +<use x='197.517' xlink:href='#g3-116' y='191.334'/> +<use x='200.575' xlink:href='#g3-49' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 36.532 74.992)'> +<use x='168.285' xlink:href='#g3-97' y='191.334'/> +<use x='172.353' xlink:href='#g3-108' y='191.334'/> +<use x='174.373' xlink:href='#g3-108' y='191.334'/> +<use x='176.393' xlink:href='#g3-111' y='191.334'/> +<use x='180.863' xlink:href='#g3-99' y='191.334'/> +<use x='184.627' xlink:href='#g3-45' y='191.334'/> +<use x='187.449' xlink:href='#g3-116' y='191.334'/> +<use x='190.507' xlink:href='#g3-101' y='191.334'/> +<use x='194.271' xlink:href='#g3-115' y='191.334'/> +<use x='197.517' xlink:href='#g3-116' y='191.334'/> +<use x='200.575' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 94.98 74.992)'> +<use x='168.285' xlink:href='#g3-115' y='191.334'/> +<use x='171.531' xlink:href='#g3-104' y='191.334'/> +<use x='175.904' xlink:href='#g3-54' y='191.334'/> +<use x='180.138' xlink:href='#g3-98' y='191.334'/> +<use x='184.746' xlink:href='#g3-101' y='191.334'/> +<use x='188.509' xlink:href='#g3-110' y='191.334'/> +<use x='192.882' xlink:href='#g3-99' y='191.334'/> +<use x='196.646' xlink:href='#g3-104' y='191.334'/> +<use x='201.018' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 153.649 74.992)'> +<use x='168.285' xlink:href='#g3-115' y='191.334'/> +<use x='171.531' xlink:href='#g3-104' y='191.334'/> +<use x='175.904' xlink:href='#g3-56' y='191.334'/> +<use x='180.138' xlink:href='#g3-98' y='191.334'/> +<use x='184.746' xlink:href='#g3-101' y='191.334'/> +<use x='188.509' xlink:href='#g3-110' y='191.334'/> +<use x='192.882' xlink:href='#g3-99' y='191.334'/> +<use x='196.646' xlink:href='#g3-104' y='191.334'/> +<use x='201.018' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 207.225 74.992)'> +<use x='168.285' xlink:href='#g3-120' y='191.334'/> +<use x='172.187' xlink:href='#g3-109' y='191.334'/> +<use x='178.912' xlink:href='#g3-97' y='191.334'/> +<use x='182.98' xlink:href='#g3-108' y='191.334'/> +<use x='185' xlink:href='#g3-108' y='191.334'/> +<use x='187.02' xlink:href='#g3-111' y='191.334'/> +<use x='191.49' xlink:href='#g3-99' y='191.334'/> +<use x='195.254' xlink:href='#g3-45' y='191.334'/> +<use x='198.076' xlink:href='#g3-116' y='191.334'/> +<use x='201.134' xlink:href='#g3-101' y='191.334'/> +<use x='204.898' xlink:href='#g3-115' y='191.334'/> +<use x='208.144' xlink:href='#g3-116' y='191.334'/> +<use x='211.202' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 263.494 74.992)'> +<use x='168.285' xlink:href='#g3-99' y='191.334'/> +<use x='172.049' xlink:href='#g3-97' y='191.334'/> +<use x='176.117' xlink:href='#g3-99' y='191.334'/> +<use x='179.88' xlink:href='#g3-104' y='191.334'/> +<use x='184.253' xlink:href='#g3-101' y='191.334'/> +<use x='188.017' xlink:href='#g3-45' y='191.334'/> +<use x='190.839' xlink:href='#g3-115' y='191.334'/> +<use x='194.086' xlink:href='#g3-99' y='191.334'/> +<use x='197.849' xlink:href='#g3-114' y='191.334'/> +<use x='200.741' xlink:href='#g3-97' y='191.334'/> +<use x='204.81' xlink:href='#g3-116' y='191.334'/> +<use x='207.868' xlink:href='#g3-99' y='191.334'/> +<use x='211.631' xlink:href='#g3-104' y='191.334'/> +<use x='216.004' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 62.23)'> +<use x='168.285' xlink:href='#g2-48' y='191.334'/> +<use x='170.931' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.677)'> +<use x='168.285' xlink:href='#g2-48' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -4.876)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -38.43)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.983)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -105.536)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<path clip-path='url(#clip2)' d='M135.949 184.824H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='#993333'/> +<path clip-path='url(#clip2)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M144.359 184.824V184.758' fill='#993333'/> +<path clip-path='url(#clip2)' d='M144.359 184.824V184.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M142.367 184.758H146.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M144.359 184.824V184.891' fill='#993333'/> +<path clip-path='url(#clip2)' d='M144.359 184.824V184.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M146.352 184.891H142.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M203.031 184.824V184.621' fill='#993333'/> +<path clip-path='url(#clip2)' d='M203.031 184.824V184.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M201.039 184.621H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M203.031 184.824V185.023' fill='#993333'/> +<path clip-path='url(#clip2)' d='M203.031 184.824V185.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M205.023 185.023H201.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M261.699 184.824V179.855' fill='#993333'/> +<path clip-path='url(#clip2)' d='M261.699 184.824V179.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M259.707 179.855H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M261.699 184.824V189.789' fill='#993333'/> +<path clip-path='url(#clip2)' d='M261.699 184.824V189.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M263.691 189.789H259.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M320.367 184.824V184.824' fill='#993333'/> +<path clip-path='url(#clip2)' d='M318.375 184.824H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M320.367 184.824V184.824' fill='#993333'/> +<path clip-path='url(#clip2)' d='M318.375 184.824H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M379.035 184.824V184.152' fill='#993333'/> +<path clip-path='url(#clip2)' d='M379.035 184.824V184.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M377.043 184.152H381.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M379.035 184.824V185.492' fill='#993333'/> +<path clip-path='url(#clip2)' d='M379.035 184.824V185.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M381.027 185.492H377.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M437.707 184.824V179.254' fill='#993333'/> +<path clip-path='url(#clip2)' d='M437.707 184.824V179.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M435.715 179.254H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M437.707 184.824V190.394' fill='#993333'/> +<path clip-path='url(#clip2)' d='M437.707 184.824V190.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M439.699 190.395H435.711' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M147.973 251.93H151.211V184.621H147.973ZM206.641 251.93H209.879V163.75H206.641ZM265.309 251.93H268.547V84.164H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M147.973 251.93H151.211V184.621H147.973ZM206.641 251.93H209.879V163.75H206.641ZM265.309 251.93H268.547V84.164H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M149.59 184.621V184.555' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M149.59 184.621V184.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M147.598 184.555H151.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M149.59 184.621V184.687' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M149.59 184.621V184.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M151.582 184.688H147.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M208.262 163.75V162.41' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M208.262 163.75V162.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M206.27 162.411H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M208.262 163.75V165.094' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M208.262 163.75V165.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M210.253 165.094H206.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M266.93 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M264.938 84.164H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M266.93 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M264.938 84.164H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M325.598 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M325.598 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M384.266 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M384.266 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M442.938 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M442.938 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip2)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M153.203 251.93H156.442V178.312H153.203ZM211.871 251.93H215.11V178.984H211.871ZM270.539 251.93H273.777V131.875H270.539ZM329.211 251.93H332.449V124.832H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M153.203 251.93H156.442V178.312H153.203ZM211.871 251.93H215.11V178.984H211.871ZM270.539 251.93H273.777V131.875H270.539ZM329.211 251.93H332.449V124.832H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M154.82 178.312V178.312' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M152.828 178.313H156.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M154.82 178.312V178.312' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M152.828 178.313H156.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M213.492 178.984V178.918' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M213.492 178.984V178.918' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M211.5 178.918H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M213.492 178.984V179.051' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M213.492 178.984V179.051' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M215.484 179.051H211.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M272.16 131.875V126.91' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M272.16 131.875V126.91' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M270.168 126.91H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M272.16 131.875V136.844' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M272.16 131.875V136.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M274.152 136.844H270.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M330.828 124.832V121.945' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M330.828 124.832V121.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M328.836 121.946H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M330.828 124.832V127.715' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M330.828 124.832V127.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M332.82 127.715H328.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M389.496 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M389.496 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M448.168 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M448.168 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip2)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M158.434 251.93H161.672V164.422H158.434ZM217.102 251.93H220.34V166.57H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V97.383H334.442ZM393.109 251.93H396.348V130.535H393.109ZM451.777 251.93H455.016V184.824H451.777Z' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M158.434 251.93H161.672V164.422H158.434ZM217.102 251.93H220.34V166.57H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V97.383H334.442ZM393.109 251.93H396.348V130.535H393.109ZM451.777 251.93H455.016V184.824H451.777Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M160.051 164.422V164.355' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M160.051 164.422V164.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M158.058 164.356H162.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M160.051 164.422V164.488' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M160.051 164.422V164.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M162.043 164.488H158.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M218.723 166.57V166.57' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M216.73 166.57H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M218.723 166.57V166.57' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M216.73 166.57H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M277.391 84.164V84.164' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M277.391 84.164V84.164' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M336.059 97.383V93.558' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M336.059 97.383V93.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M334.066 93.559H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M336.059 97.383V101.207' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M336.059 97.383V101.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M338.05 101.207H334.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M394.727 130.535V129.996' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M394.727 130.535V129.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M392.734 129.996H396.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M394.727 130.535V131.07' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M394.727 130.535V131.07' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M396.718 131.07H392.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M453.399 184.824V179.254' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M453.399 184.824V179.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M451.406 179.254H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M453.399 184.824V190.394' fill='#bf80bf'/> +<path clip-path='url(#clip2)' d='M453.399 184.824V190.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M455.39 190.395H451.402' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M163.664 251.93H166.903V178.449H163.664ZM222.332 251.93H225.57V182.34H222.332ZM281 251.93H284.238V160.129H281ZM339.672 251.93H342.91V179.723H339.672ZM398.34 251.93H401.578V183.211H398.34ZM457.008 251.93H460.246V180.863H457.008Z' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M163.664 251.93H166.903V178.449H163.664ZM222.332 251.93H225.57V182.34H222.332ZM281 251.93H284.238V160.129H281ZM339.672 251.93H342.91V179.723H339.672ZM398.34 251.93H401.578V183.211H398.34ZM457.008 251.93H460.246V180.863H457.008Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M165.281 178.449V178.379' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M165.281 178.449V178.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M163.289 178.379H167.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M165.281 178.449V178.516' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M165.281 178.449V178.516' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M167.274 178.516H163.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M223.953 182.34V182.004' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M223.953 182.34V182.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M221.961 182.004H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M223.953 182.34V182.676' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M223.953 182.34V182.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M225.945 182.676H221.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M282.621 160.129V155.164' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M282.621 160.129V155.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M280.629 155.164H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M282.621 160.129V165.094' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M282.621 160.129V165.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M284.613 165.094H280.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M341.289 179.723V178.312' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M341.289 179.723V178.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M339.297 178.313H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M341.289 179.723V181.133' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M341.289 179.723V181.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M343.281 181.133H339.297' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M399.957 183.211V182.207' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M399.957 183.211V182.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M397.965 182.207H401.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M399.957 183.211V184.219' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M399.957 183.211V184.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M401.949 184.219H397.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M458.629 180.863V171.199' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M458.629 180.863V171.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M456.637 171.2H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M458.629 180.863V190.527' fill='#dfbf9f'/> +<path clip-path='url(#clip2)' d='M458.629 180.863V190.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M460.621 190.527H456.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M168.895 251.93H172.133V175.496H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M168.895 251.93H172.133V175.496H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M170.512 175.496V175.43' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M170.512 175.496V175.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M168.519 175.429H172.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M170.512 175.496V175.562' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M170.512 175.496V175.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M172.504 175.562H168.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M229.184 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M229.184 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M287.852 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M287.852 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M346.52 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M346.52 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M405.188 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M405.188 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M463.859 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M463.859 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip2)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M174.125 251.93H177.363V120.402H174.125ZM232.793 251.93H236.031V84.164H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V84.164H350.133ZM408.801 251.93H412.039V84.164H408.801ZM467.469 251.93H470.707V184.824H467.469Z' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M174.125 251.93H177.363V120.402H174.125ZM232.793 251.93H236.031V84.164H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V84.164H350.133ZM408.801 251.93H412.039V84.164H408.801ZM467.469 251.93H470.707V184.824H467.469Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M175.742 120.402V120.266' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M175.742 120.402V120.266' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M173.75 120.266H177.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M175.742 120.402V120.535' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M175.742 120.402V120.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M177.735 120.535H173.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M234.414 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M232.422 84.164H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M234.414 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M232.422 84.164H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M293.082 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M293.082 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M351.75 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M349.758 84.164H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M351.75 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M349.758 84.164H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M410.418 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M408.426 84.164H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M410.418 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M408.426 84.164H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M469.09 184.824V179.254' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M469.09 184.824V179.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M467.098 179.254H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M469.09 184.824V190.394' fill='#bfbf80'/> +<path clip-path='url(#clip2)' d='M469.09 184.824V190.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M471.082 190.395H467.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M179.356 251.93H182.594V168.652H179.356ZM238.024 251.93H241.262V169.457H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='#339999'/> +<path clip-path='url(#clip2)' d='M179.356 251.93H182.594V168.652H179.356ZM238.024 251.93H241.262V169.457H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M180.973 168.652V168.582' fill='#339999'/> +<path clip-path='url(#clip2)' d='M180.973 168.652V168.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M178.98 168.582H182.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M180.973 168.652V168.719' fill='#339999'/> +<path clip-path='url(#clip2)' d='M180.973 168.652V168.719' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M182.965 168.719H178.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M239.645 169.457V169.387' fill='#339999'/> +<path clip-path='url(#clip2)' d='M239.645 169.457V169.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M237.652 169.387H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M239.645 169.457V169.523' fill='#339999'/> +<path clip-path='url(#clip2)' d='M239.645 169.457V169.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M241.633 169.524H237.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M298.313 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M298.313 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M356.981 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M356.981 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M415.649 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M415.649 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M474.32 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M474.32 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip2)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M184.586 251.93H187.824V176.301H184.586ZM243.254 251.93H246.492V177.309H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V84.164H360.594ZM419.262 251.93H422.5V143.621H419.262ZM477.93 251.93H481.168V176.906H477.93Z' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M184.586 251.93H187.824V176.301H184.586ZM243.254 251.93H246.492V177.309H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V84.164H360.594ZM419.262 251.93H422.5V143.621H419.262ZM477.93 251.93H481.168V176.906H477.93Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M186.203 176.301V175.965' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M186.203 176.301V175.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M184.211 175.965H188.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M186.203 176.301V176.637' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M186.203 176.301V176.637' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M188.196 176.637H184.211' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M244.875 177.309V177.172' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M244.875 177.309V177.172' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M242.883 177.172H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M244.875 177.309V177.441' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M244.875 177.309V177.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M246.864 177.441H242.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M303.543 84.164V84.164' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M303.543 84.164V84.164' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M362.211 84.164V84.164' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M360.219 84.164H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M362.211 84.164V84.164' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M360.219 84.164H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M420.879 143.621V142.746' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M420.879 143.621V142.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M418.887 142.746H422.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M420.879 143.621V144.492' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M420.879 143.621V144.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M422.871 144.492H418.887' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M479.551 176.906V171.336' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M479.551 176.906V171.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M477.559 171.336H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M479.551 176.906V182.473' fill='#bf8080'/> +<path clip-path='url(#clip2)' d='M479.551 176.906V182.473' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M481.543 182.472H477.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M420.539 312.98H487.762V278.973H420.539Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 255.575 118.327)'> +<use x='168.285' xlink:href='#g2-99' y='167.424'/> +<use x='170.637' xlink:href='#g2-53' y='167.424'/> +<use x='173.284' xlink:href='#g2-45' y='167.424'/> +<use x='175.048' xlink:href='#g2-49' y='167.424'/> +<use x='177.694' xlink:href='#g2-56' y='167.424'/> +<use x='180.341' xlink:href='#g2-120' y='167.424'/> +<use x='182.779' xlink:href='#g2-108' y='167.424'/> +<use x='184.042' xlink:href='#g2-97' y='167.424'/> +<use x='186.438' xlink:href='#g2-114' y='167.424'/> +<use x='188.245' xlink:href='#g2-103' y='167.424'/> +<use x='190.891' xlink:href='#g2-101' y='167.424'/> +<use x='193.244' xlink:href='#g2-44' y='167.424'/> +<use x='196.478' xlink:href='#g2-49' y='167.424'/> +<use x='199.124' xlink:href='#g2-52' y='167.424'/> +<use x='201.771' xlink:href='#g2-52' y='167.424'/> +<use x='204.417' xlink:href='#g2-71' y='167.424'/> +<use x='207.946' xlink:href='#g2-98' y='167.424'/> +<use x='168.285' xlink:href='#g2-55' y='173.401'/> +<use x='170.931' xlink:href='#g2-50' y='173.401'/> +<use x='175.342' xlink:href='#g2-112' y='173.401'/> +<use x='177.928' xlink:href='#g2-114' y='173.401'/> +<use x='179.735' xlink:href='#g2-111' y='173.401'/> +<use x='182.529' xlink:href='#g2-99' y='173.401'/> +<use x='186.645' xlink:href='#g2-73' y='173.401'/> +<use x='188.115' xlink:href='#g2-110' y='173.401'/> +<use x='190.848' xlink:href='#g2-116' y='173.401'/> +<use x='192.759' xlink:href='#g2-101' y='173.401'/> +<use x='195.112' xlink:href='#g2-108' y='173.401'/> +<use x='198.139' xlink:href='#g2-88' y='173.401'/> +<use x='201.667' xlink:href='#g2-101' y='173.401'/> +<use x='204.019' xlink:href='#g2-111' y='173.401'/> +<use x='206.666' xlink:href='#g2-110' y='173.401'/> +<use x='211.163' xlink:href='#g2-64' y='173.401'/> +<use x='214.691' xlink:href='#g2-51' y='173.401'/> +<use x='217.338' xlink:href='#g2-71' y='173.401'/> +<use x='220.866' xlink:href='#g2-104' y='173.401'/> +<use x='223.599' xlink:href='#g2-122' y='173.401'/> +<use x='168.285' xlink:href='#g2-85' y='179.379'/> +<use x='171.917' xlink:href='#g2-98' y='179.379'/> +<use x='174.65' xlink:href='#g2-117' y='179.379'/> +<use x='177.383' xlink:href='#g2-110' y='179.379'/> +<use x='180.116' xlink:href='#g2-116' y='179.379'/> +<use x='182.027' xlink:href='#g2-117' y='179.379'/> +<use x='186.524' xlink:href='#g2-49' y='179.379'/> +<use x='189.17' xlink:href='#g2-56' y='179.379'/> +<use x='191.817' xlink:href='#g2-46' y='179.379'/> +<use x='193.287' xlink:href='#g2-48' y='179.379'/> +<use x='195.933' xlink:href='#g2-52' y='179.379'/> +<use x='198.58' xlink:href='#g2-46' y='179.379'/> +<use x='200.05' xlink:href='#g2-49' y='179.379'/> +<use x='202.696' xlink:href='#g2-44' y='179.379'/> +<use x='205.931' xlink:href='#g2-71' y='179.379'/> +<use x='209.459' xlink:href='#g2-67' y='179.379'/> +<use x='212.841' xlink:href='#g2-67' y='179.379'/> +<use x='217.986' xlink:href='#g2-55' y='179.379'/> +<use x='220.633' xlink:href='#g2-46' y='179.379'/> +<use x='222.103' xlink:href='#g2-52' y='179.379'/> +<use x='224.749' xlink:href='#g2-46' y='179.379'/> +<use x='226.219' xlink:href='#g2-48' y='179.379'/> +<use x='168.285' xlink:href='#g2-51' y='185.357'/> +<use x='170.931' xlink:href='#g2-54' y='185.357'/> +<use x='175.342' xlink:href='#g2-99' y='185.357'/> +<use x='177.694' xlink:href='#g2-111' y='185.357'/> +<use x='180.193' xlink:href='#g2-114' y='185.357'/> +<use x='182.001' xlink:href='#g2-101' y='185.357'/> +<use x='184.353' xlink:href='#g2-115' y='185.357'/> +<use x='188.146' xlink:href='#g2-111' y='185.357'/> +<use x='190.793' xlink:href='#g2-110' y='185.357'/> +<use x='195.29' xlink:href='#g2-50' y='185.357'/> +<use x='199.7' xlink:href='#g2-110' y='185.357'/> +<use x='202.433' xlink:href='#g2-117' y='185.357'/> +<use x='205.166' xlink:href='#g2-109' y='185.357'/> +<use x='209.369' xlink:href='#g2-97' y='185.357'/> +<use x='213.676' xlink:href='#g2-110' y='185.357'/> +<use x='216.409' xlink:href='#g2-111' y='185.357'/> +<use x='219.202' xlink:href='#g2-100' y='185.357'/> +<use x='221.935' xlink:href='#g2-101' y='185.357'/> +<use x='224.287' xlink:href='#g2-115' y='185.357'/> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-48' y='191.334'/> +<use x='173.578' xlink:href='#g2-50' y='191.334'/> +<use x='176.224' xlink:href='#g2-48' y='191.334'/> +<use x='178.87' xlink:href='#g2-45' y='191.334'/> +<use x='180.635' xlink:href='#g2-48' y='191.334'/> +<use x='183.281' xlink:href='#g2-49' y='191.334'/> +<use x='185.927' xlink:href='#g2-45' y='191.334'/> +<use x='187.692' xlink:href='#g2-49' y='191.334'/> +<use x='190.338' xlink:href='#g2-56' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -45.339 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 13.33 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 71.999 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 130.668 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 189.337 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 248.006 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -40.108 346.703)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 18.561 325.833)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-51' y='191.334'/> +<use x='175.048' xlink:href='#g2-49' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 77.23 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-50' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-56' y='191.334'/> +<use x='180.675' xlink:href='#g2-52' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 135.899 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-49' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-51' y='191.334'/> +<use x='183.321' xlink:href='#g2-50' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 194.568 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-49' y='191.334'/> +<use x='179.205' xlink:href='#g2-51' y='191.334'/> +<use x='181.851' xlink:href='#g2-46' y='191.334'/> +<use x='183.321' xlink:href='#g2-55' y='191.334'/> +<use x='185.968' xlink:href='#g2-49' y='191.334'/> +<use x='188.614' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 253.236 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-50' y='191.334'/> +<use x='176.558' xlink:href='#g2-56' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-55' y='191.334'/> +<use x='183.321' xlink:href='#g2-54' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -34.878 340.395)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 23.791 341.066)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 82.46 293.957)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-55' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 141.129 286.911)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-56' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 199.798 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-48' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-52' y='191.334'/> +<use x='183.321' xlink:href='#g2-52' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 258.467 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-50' y='191.334'/> +<use x='176.558' xlink:href='#g2-56' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-53' y='191.334'/> +<use x='183.321' xlink:href='#g2-51' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -29.648 326.504)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-51' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 29.021 328.651)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-50' y='191.334'/> +<use x='175.048' xlink:href='#g2-55' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 87.69 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-50' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-54' y='191.334'/> +<use x='180.675' xlink:href='#g2-56' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 146.359 259.465)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-51' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 205.028 292.615)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-56' y='191.334'/> +<use x='175.048' xlink:href='#g2-49' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 263.697 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -24.417 340.529)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 34.252 344.421)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-52' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 92.921 322.209)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-51' y='191.334'/> +<use x='175.048' xlink:href='#g2-55' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 151.59 341.804)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-56' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 210.259 345.293)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-50' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 268.928 342.945)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-54' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -19.187 337.576)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-52' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 39.482 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-54' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-50' y='191.334'/> +<use x='180.675' xlink:href='#g2-56' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 98.151 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-54' y='191.334'/> +<use x='176.558' xlink:href='#g2-48' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-48' y='191.334'/> +<use x='183.321' xlink:href='#g2-48' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 156.82 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-50' y='191.334'/> +<use x='176.558' xlink:href='#g2-49' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-55' y='191.334'/> +<use x='183.321' xlink:href='#g2-57' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 215.489 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-48' y='191.334'/> +<use x='179.205' xlink:href='#g2-55' y='191.334'/> +<use x='181.851' xlink:href='#g2-46' y='191.334'/> +<use x='183.321' xlink:href='#g2-48' y='191.334'/> +<use x='185.968' xlink:href='#g2-50' y='191.334'/> +<use x='188.614' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 274.158 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-51' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-51' y='191.334'/> +<use x='183.321' xlink:href='#g2-53' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -13.956 282.482)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-57' y='191.334'/> +<use x='175.048' xlink:href='#g2-54' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 44.713 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-52' y='191.334'/> +<use x='176.558' xlink:href='#g2-50' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-53' y='191.334'/> +<use x='183.321' xlink:href='#g2-56' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 103.382 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-50' y='191.334'/> +<use x='176.558' xlink:href='#g2-50' y='191.334'/> +<use x='179.205' xlink:href='#g2-57' y='191.334'/> +<use x='181.851' xlink:href='#g2-46' y='191.334'/> +<use x='183.321' xlink:href='#g2-53' y='191.334'/> +<use x='185.968' xlink:href='#g2-56' y='191.334'/> +<use x='188.614' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 162.051 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-55' y='191.334'/> +<use x='176.558' xlink:href='#g2-51' y='191.334'/> +<use x='179.205' xlink:href='#g2-53' y='191.334'/> +<use x='181.851' xlink:href='#g2-46' y='191.334'/> +<use x='183.321' xlink:href='#g2-50' y='191.334'/> +<use x='185.968' xlink:href='#g2-55' y='191.334'/> +<use x='188.614' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 220.72 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-50' y='191.334'/> +<use x='179.205' xlink:href='#g2-52' y='191.334'/> +<use x='181.851' xlink:href='#g2-46' y='191.334'/> +<use x='183.321' xlink:href='#g2-54' y='191.334'/> +<use x='185.968' xlink:href='#g2-55' y='191.334'/> +<use x='188.614' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 279.389 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -8.726 330.731)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-50' y='191.334'/> +<use x='175.048' xlink:href='#g2-52' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 49.943 331.537)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-50' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 108.612 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-52' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-54' y='191.334'/> +<use x='183.321' xlink:href='#g2-56' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 167.281 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-55' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-50' y='191.334'/> +<use x='180.675' xlink:href='#g2-57' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 225.95 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-52' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-49' y='191.334'/> +<use x='180.675' xlink:href='#g2-51' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 284.619 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-49' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-52' y='191.334'/> +<use x='183.321' xlink:href='#g2-55' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -3.495 338.381)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 55.174 339.388)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-49' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 113.843 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-52' y='191.334'/> +<use x='180.675' xlink:href='#g2-50' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 172.512 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-53' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-50' y='191.334'/> +<use x='180.675' xlink:href='#g2-55' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 231.181 305.701)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-54' y='191.334'/> +<use x='175.048' xlink:href='#g2-49' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 289.85 338.985)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-50' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -78.176 391.591)'> +<use x='168.285' xlink:href='#g1-82' y='191.334'/> +<use x='174.255' xlink:href='#g1-101' y='191.334'/> +<use x='178.351' xlink:href='#g1-108' y='191.334'/> +<use x='180.551' xlink:href='#g1-97' y='191.334'/> +<use x='184.979' xlink:href='#g1-116' y='191.334'/> +<use x='188.307' xlink:href='#g1-105' y='191.334'/> +<use x='190.507' xlink:href='#g1-118' y='191.334'/> +<use x='194.755' xlink:href='#g1-101' y='191.334'/> +<use x='201.922' xlink:href='#g1-116' y='191.334'/> +<use x='205.25' xlink:href='#g1-105' y='191.334'/> +<use x='207.45' xlink:href='#g1-109' y='191.334'/> +<use x='214.77' xlink:href='#g1-101' y='191.334'/> +<use x='221.937' xlink:href='#g3-40' y='191.334'/> +<use x='225.231' xlink:href='#g3-108' y='191.334'/> +<use x='227.251' xlink:href='#g3-111' y='191.334'/> +<use x='231.25' xlink:href='#g3-119' y='191.334'/> +<use x='236.799' xlink:href='#g3-101' y='191.334'/> +<use x='240.562' xlink:href='#g3-114' y='191.334'/> +<use x='246.277' xlink:href='#g3-105' y='191.334'/> +<use x='248.297' xlink:href='#g3-115' y='191.334'/> +<use x='254.366' xlink:href='#g3-98' y='191.334'/> +<use x='258.974' xlink:href='#g3-101' y='191.334'/> +<use x='262.738' xlink:href='#g3-116' y='191.334'/> +<use x='265.796' xlink:href='#g3-116' y='191.334'/> +<use x='268.854' xlink:href='#g3-101' y='191.334'/> +<use x='272.618' xlink:href='#g3-114' y='191.334'/> +<use x='275.51' xlink:href='#g3-41' y='191.334'/> +</g> +<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='#ffffff'/> +<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='#993333'/> +<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -40.354 114.479)'> +<use x='195.372' xlink:href='#g3-120' y='178.327'/> +<use x='199.274' xlink:href='#g3-109' y='178.327'/> +<use x='205.999' xlink:href='#g3-105' y='178.327'/> +<use x='208.019' xlink:href='#g3-58' y='178.327'/> +<use x='210.371' xlink:href='#g0-57' y='178.327'/> +<use x='214.076' xlink:href='#g0-57' y='178.327'/> +</g> +<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='#8080bf'/> +<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.441 114.036)'> +<use x='239.382' xlink:href='#g3-116' y='178.327'/> +<use x='242.44' xlink:href='#g3-99' y='178.327'/> +<use x='246.204' xlink:href='#g3-58' y='178.327'/> +<use x='248.556' xlink:href='#g0-53' y='178.327'/> +<use x='252.261' xlink:href='#g0-55' y='178.327'/> +</g> +<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='#ffb733'/> +<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.04 114.479)'> +<use x='281.863' xlink:href='#g3-106' y='178.327'/> +<use x='284.119' xlink:href='#g3-101' y='178.327'/> +<use x='287.882' xlink:href='#g3-58' y='178.327'/> +<use x='290.235' xlink:href='#g0-53' y='178.327'/> +<use x='293.94' xlink:href='#g0-56' y='178.327'/> +</g> +<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='#bf80bf'/> +<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.932 114.515)'> +<use x='321.287' xlink:href='#g3-116' y='178.327'/> +<use x='324.345' xlink:href='#g3-98' y='178.327'/> +<use x='328.717' xlink:href='#g3-98' y='178.327'/> +<use x='333.09' xlink:href='#g3-58' y='178.327'/> +<use x='335.442' xlink:href='#g0-53' y='178.327'/> +<use x='339.147' xlink:href='#g0-56' y='178.327'/> +</g> +<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='#dfbf9f'/> +<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.662 114.036)'> +<use x='356.019' xlink:href='#g3-114' y='178.327'/> +<use x='358.911' xlink:href='#g3-112' y='178.327'/> +<use x='363.284' xlink:href='#g3-58' y='178.327'/> +<use x='365.636' xlink:href='#g0-56' y='178.327'/> +<use x='369.341' xlink:href='#g0-49' y='178.327'/> +</g> +<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='#80bf80'/> +<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -43.882 114.515)'> +<use x='195.372' xlink:href='#g3-104' y='191.334'/> +<use x='199.744' xlink:href='#g3-111' y='191.334'/> +<use x='203.978' xlink:href='#g3-97' y='191.334'/> +<use x='207.811' xlink:href='#g3-114' y='191.334'/> +<use x='210.703' xlink:href='#g3-100' y='191.334'/> +<use x='215.076' xlink:href='#g3-58' y='191.334'/> +<use x='217.428' xlink:href='#g0-51' y='191.334'/> +<use x='221.133' xlink:href='#g0-51' y='191.334'/> +</g> +<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='#bfbf80'/> +<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -43.084 114.515)'> +<use x='239.382' xlink:href='#g3-109' y='191.334'/> +<use x='246.107' xlink:href='#g3-101' y='191.334'/> +<use x='249.871' xlink:href='#g3-115' y='191.334'/> +<use x='253.117' xlink:href='#g3-104' y='191.334'/> +<use x='257.489' xlink:href='#g3-58' y='191.334'/> +<use x='259.842' xlink:href='#g0-50' y='191.334'/> +<use x='263.547' xlink:href='#g0-56' y='191.334'/> +</g> +<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='#339999'/> +<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -42.353 114.515)'> +<use x='281.863' xlink:href='#g3-103' y='191.334'/> +<use x='286.097' xlink:href='#g3-108' y='191.334'/> +<use x='288.118' xlink:href='#g3-105' y='191.334'/> +<use x='290.138' xlink:href='#g3-98' y='191.334'/> +<use x='294.746' xlink:href='#g3-99' y='191.334'/> +<use x='298.509' xlink:href='#g3-58' y='191.334'/> +<use x='300.862' xlink:href='#g0-52' y='191.334'/> +<use x='304.567' xlink:href='#g0-55' y='191.334'/> +</g> +<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='#bf8080'/> +<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -40.026 114.479)'> +<use x='321.287' xlink:href='#g3-115' y='191.334'/> +<use x='324.533' xlink:href='#g3-109' y='191.334'/> +<use x='331.258' xlink:href='#g3-105' y='191.334'/> +<use x='333.278' xlink:href='#g3-58' y='191.334'/> +<use x='335.63' xlink:href='#g0-54' y='191.334'/> +<use x='339.335' xlink:href='#g0-55' y='191.334'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg new file mode 100644 index 0000000..393bfad --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg @@ -0,0 +1,757 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='193.064pt' version='1.1' viewBox='52.938 51.67 381.624 193.064' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip7'> +<path d='M82.148 228.594H434.164V60.828H82.148Z'/> +</clipPath> +<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/> +<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/> +<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/> +<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/> +<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/> +<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/> +<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/> +<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/> +<use id='g3-102' transform='scale(1.143)' xlink:href='#g0-102'/> +<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/> +<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/> +<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/> +<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/> +<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/> +<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/> +<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/> +<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/> +<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/> +<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g1-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g1-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/> +<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/> +<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/> +<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/> +<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/> +<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/> +<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/> +<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/> +<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/> +<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/> +<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/> +<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/> +<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/> +<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/> +<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/> +<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/> +<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/> +<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/> +<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/> +<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/> +<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/> +<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/> +<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/> +<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/> +<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/> +<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/> +<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/> +<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/> +<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/> +<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/> +<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/> +<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/> +<path d='M1.325 -2.657H2.12V-3.096H1.304V-3.898C1.304 -4.38 1.743 -4.449 1.974 -4.449C2.12 -4.449 2.308 -4.428 2.566 -4.331V-4.84C2.385 -4.882 2.169 -4.91 1.981 -4.91C1.262 -4.91 0.739 -4.394 0.739 -3.703V-3.096H0.202V-2.657H0.739V0H1.325V-2.657Z' id='g0-102'/> +<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/> +<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/> +<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/> +<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/> +<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/> +<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/> +<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/> +<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/> +<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/> +<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/> +</defs> +<g id='page7'> +<path d='M140.82 237.449V228.594M199.488 237.449V228.594M258.156 237.449V228.594M316.824 237.449V228.594M375.496 237.449V228.594M140.82 51.969V60.828M199.488 51.969V60.828M258.156 51.969V60.828M316.824 51.969V60.828M375.496 51.969V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 232.844V228.594M170.152 232.844V228.594M228.824 232.844V228.594M287.492 232.844V228.594M346.16 232.844V228.594M404.828 232.844V228.594M111.484 56.574V60.828M170.152 56.574V60.828M228.824 56.574V60.828M287.492 56.574V60.828M346.16 56.574V60.828M404.828 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 228.594H86.402M82.148 195.039H86.402M82.148 161.484H86.402M82.148 127.934H86.402M82.148 94.379H86.402M82.148 60.828H86.402M434.164 228.594H429.91M434.164 195.039H429.91M434.164 161.484H429.91M434.164 127.934H429.91M434.164 94.379H429.91M434.164 60.828H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 228.594V60.828H434.164V228.594H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 34.954)'> +<use x='114.487' xlink:href='#g3-99' y='208.035'/> +<use x='118.25' xlink:href='#g3-102' y='208.035'/> +<use x='120.838' xlink:href='#g3-114' y='208.035'/> +<use x='123.73' xlink:href='#g3-97' y='208.035'/> +<use x='127.798' xlink:href='#g3-99' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 45.565 34.954)'> +<use x='114.487' xlink:href='#g3-108' y='208.035'/> +<use x='116.507' xlink:href='#g3-101' y='208.035'/> +<use x='120.271' xlink:href='#g3-97' y='208.035'/> +<use x='124.339' xlink:href='#g3-110' y='208.035'/> +<use x='128.711' xlink:href='#g3-78' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 106.188 34.954)'> +<use x='114.487' xlink:href='#g3-114' y='208.035'/> +<use x='117.379' xlink:href='#g3-101' y='208.035'/> +<use x='121.142' xlink:href='#g3-100' y='208.035'/> +<use x='125.515' xlink:href='#g3-105' y='208.035'/> +<use x='127.535' xlink:href='#g3-115' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 159.716 34.954)'> +<use x='114.487' xlink:href='#g3-108' y='208.035'/> +<use x='116.507' xlink:href='#g3-97' y='208.035'/> +<use x='120.34' xlink:href='#g3-114' y='208.035'/> +<use x='123.232' xlink:href='#g3-115' y='208.035'/> +<use x='126.478' xlink:href='#g3-111' y='208.035'/> +<use x='130.712' xlink:href='#g3-110' y='208.035'/> +<use x='135.085' xlink:href='#g3-78' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 215.596 34.954)'> +<use x='114.487' xlink:href='#g3-109' y='208.035'/> +<use x='121.211' xlink:href='#g3-115' y='208.035'/> +<use x='124.458' xlink:href='#g3-116' y='208.035'/> +<use x='127.516' xlink:href='#g3-114' y='208.035'/> +<use x='130.408' xlink:href='#g3-101' y='208.035'/> +<use x='134.171' xlink:href='#g3-115' y='208.035'/> +<use x='137.418' xlink:href='#g3-115' y='208.035'/> +<use x='140.664' xlink:href='#g3-78' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 277.158 34.954)'> +<use x='114.487' xlink:href='#g3-114' y='208.035'/> +<use x='117.379' xlink:href='#g3-112' y='208.035'/> +<use x='121.751' xlink:href='#g3-116' y='208.035'/> +<use x='124.809' xlink:href='#g3-101' y='208.035'/> +<use x='128.573' xlink:href='#g3-115' y='208.035'/> +<use x='131.819' xlink:href='#g3-116' y='208.035'/> +<use x='134.877' xlink:href='#g3-78' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 22.192)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-120' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -11.361)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-120' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -44.915)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-120' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -78.468)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-120' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -112.021)'> +<use x='114.487' xlink:href='#g2-50' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-120' y='208.035'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -145.574)'> +<use x='114.487' xlink:href='#g2-50' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-120' y='208.035'/> +</g> +<path clip-path='url(#clip7)' d='M82.148 161.484H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M88.945 228.594H92.18V161.484H88.945ZM147.613 228.594H150.852V161.484H147.613ZM206.281 228.594H209.52V161.484H206.281ZM264.949 228.594H268.188V161.484H264.949ZM323.621 228.594H326.859V161.484H323.621ZM382.289 228.594H385.527V161.484H382.289Z' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M88.945 228.594H92.18V161.484H88.945ZM147.613 228.594H150.852V161.484H147.613ZM206.281 228.594H209.52V161.484H206.281ZM264.949 228.594H268.188V161.484H264.949ZM323.621 228.594H326.859V161.484H323.621ZM382.289 228.594H385.527V161.484H382.289Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M90.563 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M88.57 161.484H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M90.563 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M88.57 161.484H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M149.231 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M147.238 161.484H151.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M149.231 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M147.238 161.484H151.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M207.902 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M205.906 161.484H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M207.902 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M205.906 161.484H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M266.57 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M264.578 161.484H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M266.57 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M264.578 161.484H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M325.238 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M323.246 161.484H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M325.238 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M323.246 161.484H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M383.906 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M381.914 161.484H385.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M383.906 161.484V161.484' fill='#ffffff'/> +<path clip-path='url(#clip7)' d='M381.914 161.484H385.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M94.176 228.594H97.41V74.719H94.176ZM152.844 228.594H156.082V172.559H152.844ZM211.512 228.594H214.75V145.852H211.512ZM270.18 228.594H273.418V154.773H270.18ZM328.852 228.594H332.09V193.43H328.852ZM387.52 228.594H390.758V191.148H387.52Z' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M94.176 228.594H97.41V74.719H94.176ZM152.844 228.594H156.082V172.559H152.844ZM211.512 228.594H214.75V145.852H211.512ZM270.18 228.594H273.418V154.773H270.18ZM328.852 228.594H332.09V193.43H328.852ZM387.52 228.594H390.758V191.148H387.52Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M95.793 74.719V74.719' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M93.801 74.719H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M95.793 74.719V74.719' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M93.801 74.719H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M154.461 172.559V172.559' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M152.469 172.558H156.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M154.461 172.559V172.559' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M152.469 172.558H156.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M213.133 145.852V145.852' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M211.137 145.851H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M213.133 145.852V145.852' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M211.137 145.851H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M271.801 154.773V154.773' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M269.809 154.773H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M271.801 154.773V154.773' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M269.809 154.773H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M330.469 193.43V193.43' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M328.477 193.429H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M330.469 193.43V193.43' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M328.477 193.429H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M389.137 191.148V191.148' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M387.145 191.149H391.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M389.137 191.148V191.148' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M387.145 191.149H391.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M99.406 228.594H102.641V138.133H99.406ZM158.074 228.594H161.313V162.961H158.074ZM216.742 228.594H219.981V157.797H216.742ZM275.41 228.594H278.649V141.02H275.41ZM334.082 228.594H337.32V191.816H334.082ZM392.75 228.594H395.988V179.871H392.75Z' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M99.406 228.594H102.641V138.133H99.406ZM158.074 228.594H161.313V162.961H158.074ZM216.742 228.594H219.981V157.797H216.742ZM275.41 228.594H278.649V141.02H275.41ZM334.082 228.594H337.32V191.816H334.082ZM392.75 228.594H395.988V179.871H392.75Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M101.024 138.133V138.133' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M99.031 138.133H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M101.024 138.133V138.133' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M99.031 138.133H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M159.691 162.961V162.961' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M157.699 162.961H161.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M159.691 162.961V162.961' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M157.699 162.961H161.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M218.363 157.797V157.797' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M216.367 157.797H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M218.363 157.797V157.797' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M216.367 157.797H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M277.031 141.02V141.02' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M275.039 141.02H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M277.031 141.02V141.02' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M275.039 141.02H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M335.699 191.816V191.816' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M333.707 191.816H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M335.699 191.816V191.816' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M333.707 191.816H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M394.367 179.871V179.871' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M392.375 179.871H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M394.367 179.871V179.871' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M392.375 179.871H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M104.637 228.594H107.871V140.883H104.637ZM163.305 228.594H166.543V152.695H163.305ZM221.973 228.594H225.211V115.184H221.973ZM280.641 228.594H283.879V167.793H280.641ZM339.313 228.594H342.551V189.738H339.313ZM397.981 228.594H401.219V194.367H397.981Z' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M104.637 228.594H107.871V140.883H104.637ZM163.305 228.594H166.543V152.695H163.305ZM221.973 228.594H225.211V115.184H221.973ZM280.641 228.594H283.879V167.793H280.641ZM339.313 228.594H342.551V189.738H339.313ZM397.981 228.594H401.219V194.367H397.981Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M106.254 140.883V140.883' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M104.261 140.882H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M106.254 140.883V140.883' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M104.261 140.882H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M164.922 152.695V152.695' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M162.929 152.695H166.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M164.922 152.695V152.695' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M162.929 152.695H166.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M223.594 115.184V115.184' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M221.597 115.184H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M223.594 115.184V115.184' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M221.597 115.184H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M282.262 167.793V167.793' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M280.269 167.793H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M282.262 167.793V167.793' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M280.269 167.793H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M340.93 189.738V189.738' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M338.937 189.739H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M340.93 189.738V189.738' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M338.937 189.739H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M399.598 194.367V194.367' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M397.605 194.367H401.589' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M399.598 194.367V194.367' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M397.605 194.367H401.589' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M109.867 228.594H113.102V163.031H109.867ZM168.535 228.594H171.774V157.191H168.535ZM227.203 228.594H230.442V142.094H227.203ZM285.871 228.594H289.109V150.414H285.871ZM344.543 228.594H347.781V150.949H344.543ZM403.211 228.594H406.449V103.105H403.211Z' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M109.867 228.594H113.102V163.031H109.867ZM168.535 228.594H171.774V157.191H168.535ZM227.203 228.594H230.442V142.094H227.203ZM285.871 228.594H289.109V150.414H285.871ZM344.543 228.594H347.781V150.949H344.543ZM403.211 228.594H406.449V103.105H403.211Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M111.484 163.031V163.031' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M109.492 163.031H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M111.484 163.031V163.031' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M109.492 163.031H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M170.152 157.191V157.191' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M168.16 157.191H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M170.152 157.191V157.191' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M168.16 157.191H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M228.824 142.094V142.094' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M226.828 142.093H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M228.824 142.094V142.094' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M226.828 142.093H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M287.492 150.414V150.414' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M285.5 150.414H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M287.492 150.414V150.414' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M285.5 150.414H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M346.16 150.949V150.949' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M344.168 150.949H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M346.16 150.949V150.949' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M344.168 150.949H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M404.828 103.105V103.105' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M402.836 103.106H406.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M404.828 103.105V103.105' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M402.836 103.106H406.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M115.098 228.594H118.332V133.906H115.098ZM173.766 228.594H177.004V148.133H173.766ZM232.434 228.594H235.672V144.91H232.434ZM291.102 228.594H294.34V160.48H291.102ZM349.774 228.594H353.012V168.801H349.774ZM408.442 228.594H411.68V181.484H408.442Z' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M115.098 228.594H118.332V133.906H115.098ZM173.766 228.594H177.004V148.133H173.766ZM232.434 228.594H235.672V144.91H232.434ZM291.102 228.594H294.34V160.48H291.102ZM349.774 228.594H353.012V168.801H349.774ZM408.442 228.594H411.68V181.484H408.442Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M116.715 133.906V133.906' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M114.722 133.906H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M116.715 133.906V133.906' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M114.722 133.906H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M175.383 148.133V148.133' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M173.39 148.133H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M175.383 148.133V148.133' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M173.39 148.133H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M234.055 144.91V144.91' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M232.058 144.91H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M234.055 144.91V144.91' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M232.058 144.91H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M292.723 160.48V160.48' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M290.73 160.48H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M292.723 160.48V160.48' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M290.73 160.48H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M351.391 168.801V168.801' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M349.398 168.801H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M351.391 168.801V168.801' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M349.398 168.801H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M410.059 181.484V181.484' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M408.066 181.485H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M410.059 181.484V181.484' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M408.066 181.485H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M120.328 228.594H123.563V140.48H120.328ZM178.996 228.594H182.234V159.473H178.996ZM237.664 228.594H240.902V159.406H237.664ZM296.332 228.594H299.57V157.797H296.332ZM355.004 228.594H358.238V172.355H355.004ZM413.672 228.594H416.91V184.637H413.672Z' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M120.328 228.594H123.563V140.48H120.328ZM178.996 228.594H182.234V159.473H178.996ZM237.664 228.594H240.902V159.406H237.664ZM296.332 228.594H299.57V157.797H296.332ZM355.004 228.594H358.238V172.355H355.004ZM413.672 228.594H416.91V184.637H413.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M121.945 140.48V140.48' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M119.953 140.481H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M121.945 140.48V140.48' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M119.953 140.481H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M180.613 159.473V159.473' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M178.621 159.473H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M180.613 159.473V159.473' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M178.621 159.473H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M239.285 159.406V159.406' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M237.289 159.407H241.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M239.285 159.406V159.406' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M237.289 159.407H241.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M297.953 157.797V157.797' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M295.961 157.797H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M297.953 157.797V157.797' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M295.961 157.797H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M356.621 172.355V172.355' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M354.629 172.355H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M356.621 172.355V172.355' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M354.629 172.355H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M415.289 184.637V184.637' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M413.297 184.637H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M415.289 184.637V184.637' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M413.297 184.637H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M125.559 228.594H128.793V163.098H125.559ZM184.227 228.594H187.465V151.824H184.227ZM242.895 228.594H246.133V161.082H242.895ZM301.563 228.594H304.801V167.457H301.563ZM360.234 228.594H363.469V168.195H360.234ZM418.902 228.594H422.141V199.332H418.902Z' fill='#942994'/> +<path clip-path='url(#clip7)' d='M125.559 228.594H128.793V163.098H125.559ZM184.227 228.594H187.465V151.824H184.227ZM242.895 228.594H246.133V161.082H242.895ZM301.563 228.594H304.801V167.457H301.563ZM360.234 228.594H363.469V168.195H360.234ZM418.902 228.594H422.141V199.332H418.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M127.176 163.098V163.098' fill='#942994'/> +<path clip-path='url(#clip7)' d='M125.183 163.097H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M127.176 163.098V163.098' fill='#942994'/> +<path clip-path='url(#clip7)' d='M125.183 163.097H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M185.844 151.824V151.824' fill='#942994'/> +<path clip-path='url(#clip7)' d='M183.851 151.825H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M185.844 151.824V151.824' fill='#942994'/> +<path clip-path='url(#clip7)' d='M183.851 151.825H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M244.516 161.082V161.082' fill='#942994'/> +<path clip-path='url(#clip7)' d='M242.519 161.082H246.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M244.516 161.082V161.082' fill='#942994'/> +<path clip-path='url(#clip7)' d='M242.519 161.082H246.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M303.184 167.457V167.457' fill='#942994'/> +<path clip-path='url(#clip7)' d='M301.191 167.457H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M303.184 167.457V167.457' fill='#942994'/> +<path clip-path='url(#clip7)' d='M301.191 167.457H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M361.852 168.195V168.195' fill='#942994'/> +<path clip-path='url(#clip7)' d='M359.859 168.196H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M361.852 168.195V168.195' fill='#942994'/> +<path clip-path='url(#clip7)' d='M359.859 168.196H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M420.52 199.332V199.332' fill='#942994'/> +<path clip-path='url(#clip7)' d='M418.527 199.332H422.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M420.52 199.332V199.332' fill='#942994'/> +<path clip-path='url(#clip7)' d='M418.527 199.332H422.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M130.789 228.594H134.024V157.996H130.789ZM189.457 228.594H192.695V153.969H189.457ZM248.125 228.594H251.363V154.305H248.125ZM306.793 228.594H310.031V122.633H306.793ZM365.465 228.594H368.699V165.98H365.465ZM424.133 228.594H427.371V150.211H424.133Z' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M130.789 228.594H134.024V157.996H130.789ZM189.457 228.594H192.695V153.969H189.457ZM248.125 228.594H251.363V154.305H248.125ZM306.793 228.594H310.031V122.633H306.793ZM365.465 228.594H368.699V165.98H365.465ZM424.133 228.594H427.371V150.211H424.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M132.406 157.996V157.996' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M130.414 157.996H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M132.406 157.996V157.996' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M130.414 157.996H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M191.074 153.969V153.969' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M189.082 153.969H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M191.074 153.969V153.969' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M189.082 153.969H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M249.746 154.305V154.305' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M247.75 154.305H251.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M249.746 154.305V154.305' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M247.75 154.305H251.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M308.414 122.633V122.633' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M306.422 122.633H310.407' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M308.414 122.633V122.633' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M306.422 122.633H310.407' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M367.082 165.98V165.98' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M365.09 165.98H369.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M367.082 165.98V165.98' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M365.09 165.98H369.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M425.75 150.211V150.211' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M423.758 150.211H427.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M425.75 150.211V150.211' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M423.758 150.211H427.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -115.838 269.769)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -57.169 269.769)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 1.5 269.769)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 60.169 269.769)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 118.838 269.769)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 177.507 269.769)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -110.608 183.001)'> +<use x='114.487' xlink:href='#g2-50' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-50' y='208.035'/> +<use x='121.25' xlink:href='#g2-57' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -51.938 280.841)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-56' y='208.035'/> +<use x='121.25' xlink:href='#g2-52' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 6.731 254.133)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-50' y='208.035'/> +<use x='121.25' xlink:href='#g2-51' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 65.4 263.058)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 124.069 301.711)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-50' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 182.738 299.43)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-54' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -105.377 246.416)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-51' y='208.035'/> +<use x='121.25' xlink:href='#g2-53' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -46.708 271.245)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-56' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 11.961 266.078)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-53' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 70.63 249.302)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-51' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 129.299 300.101)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-53' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 187.968 288.156)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-55' y='208.035'/> +<use x='121.25' xlink:href='#g2-51' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -100.147 249.167)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-51' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -41.478 260.978)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-51' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 17.191 223.466)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-54' y='208.035'/> +<use x='121.25' xlink:href='#g2-57' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 75.86 276.077)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 134.529 298.021)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-56' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 193.198 302.651)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -94.916 271.312)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-56' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -36.247 265.474)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-54' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 22.422 250.375)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-50' y='208.035'/> +<use x='121.25' xlink:href='#g2-57' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 81.091 258.696)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-54' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 139.76 259.233)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-54' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 198.429 211.387)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-56' y='208.035'/> +<use x='121.25' xlink:href='#g2-55' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -89.686 242.188)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-52' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -31.017 256.415)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-50' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 27.652 253.194)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-50' y='208.035'/> +<use x='121.25' xlink:href='#g2-53' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 86.321 268.762)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-50' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 144.99 277.083)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-56' y='208.035'/> +<use x='121.25' xlink:href='#g2-57' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 203.659 289.767)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-55' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -84.455 248.765)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-51' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -25.786 267.756)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-51' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 32.883 267.689)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-51' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 91.552 266.078)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-53' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 150.221 280.64)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-56' y='208.035'/> +<use x='121.25' xlink:href='#g2-52' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 208.89 292.921)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-54' y='208.035'/> +<use x='121.25' xlink:href='#g2-54' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -79.225 271.379)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-56' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -20.556 260.106)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-52' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 38.113 269.366)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 96.782 275.741)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 155.451 276.48)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-48' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 214.12 307.617)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-52' y='208.035'/> +<use x='121.25' xlink:href='#g2-52' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -73.994 266.279)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-48' y='208.035'/> +<use x='121.25' xlink:href='#g2-53' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -15.325 262.253)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 43.344 262.589)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-49' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 102.013 230.914)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-53' y='208.035'/> +<use x='121.25' xlink:href='#g2-56' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 160.682 274.265)'> +<use x='114.487' xlink:href='#g2-48' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-57' y='208.035'/> +<use x='121.25' xlink:href='#g2-51' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 219.351 258.495)'> +<use x='114.487' xlink:href='#g2-49' y='208.035'/> +<use x='117.133' xlink:href='#g2-46' y='208.035'/> +<use x='118.603' xlink:href='#g2-49' y='208.035'/> +<use x='121.25' xlink:href='#g2-55' y='208.035'/> +</g> +<g transform='matrix(0 -1 1 0 -148.675 311.091)'> +<use x='114.487' xlink:href='#g1-82' y='208.035'/> +<use x='120.457' xlink:href='#g1-101' y='208.035'/> +<use x='124.553' xlink:href='#g1-108' y='208.035'/> +<use x='126.753' xlink:href='#g1-97' y='208.035'/> +<use x='131.181' xlink:href='#g1-116' y='208.035'/> +<use x='134.509' xlink:href='#g1-105' y='208.035'/> +<use x='136.709' xlink:href='#g1-118' y='208.035'/> +<use x='140.957' xlink:href='#g1-101' y='208.035'/> +<use x='148.124' xlink:href='#g1-114' y='208.035'/> +<use x='151.272' xlink:href='#g1-115' y='208.035'/> +<use x='154.805' xlink:href='#g1-115' y='208.035'/> +<use x='161.409' xlink:href='#g3-40' y='208.035'/> +<use x='164.702' xlink:href='#g3-108' y='208.035'/> +<use x='166.722' xlink:href='#g3-111' y='208.035'/> +<use x='170.721' xlink:href='#g3-119' y='208.035'/> +<use x='176.27' xlink:href='#g3-101' y='208.035'/> +<use x='180.034' xlink:href='#g3-114' y='208.035'/> +<use x='185.749' xlink:href='#g3-105' y='208.035'/> +<use x='187.769' xlink:href='#g3-115' y='208.035'/> +<use x='193.838' xlink:href='#g3-98' y='208.035'/> +<use x='198.446' xlink:href='#g3-101' y='208.035'/> +<use x='202.209' xlink:href='#g3-116' y='208.035'/> +<use x='205.267' xlink:href='#g3-116' y='208.035'/> +<use x='208.325' xlink:href='#g3-101' y='208.035'/> +<use x='212.089' xlink:href='#g3-114' y='208.035'/> +<use x='214.981' xlink:href='#g3-41' y='208.035'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg new file mode 100644 index 0000000..419dc25 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg @@ -0,0 +1,1028 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='255.738pt' version='1.1' viewBox='106.736 54.996 381.624 255.738' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip8'> +<path d='M135.949 249.281H487.961V81.519H135.949Z'/> +</clipPath> +<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/> +<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/> +<use id='g3-45' transform='scale(1.143)' xlink:href='#g0-45'/> +<use id='g3-49' transform='scale(1.143)' xlink:href='#g0-49'/> +<use id='g3-54' transform='scale(1.143)' xlink:href='#g0-54'/> +<use id='g3-56' transform='scale(1.143)' xlink:href='#g0-56'/> +<use id='g3-58' transform='scale(1.143)' xlink:href='#g0-58'/> +<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/> +<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/> +<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/> +<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/> +<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/> +<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/> +<use id='g3-103' transform='scale(1.143)' xlink:href='#g0-103'/> +<use id='g3-104' transform='scale(1.143)' xlink:href='#g0-104'/> +<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/> +<use id='g3-106' transform='scale(1.143)' xlink:href='#g0-106'/> +<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/> +<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/> +<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/> +<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/> +<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/> +<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/> +<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/> +<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/> +<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/> +<use id='g3-120' transform='scale(1.143)' xlink:href='#g0-120'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g1-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g1-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/> +<use id='g2-44' transform='scale(0.714)' xlink:href='#g0-44'/> +<use id='g2-45' transform='scale(0.714)' xlink:href='#g0-45'/> +<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/> +<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/> +<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/> +<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/> +<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/> +<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/> +<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/> +<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/> +<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/> +<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/> +<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/> +<use id='g2-64' transform='scale(0.714)' xlink:href='#g0-64'/> +<use id='g2-67' transform='scale(0.714)' xlink:href='#g0-67'/> +<use id='g2-71' transform='scale(0.714)' xlink:href='#g0-71'/> +<use id='g2-73' transform='scale(0.714)' xlink:href='#g0-73'/> +<use id='g2-85' transform='scale(0.714)' xlink:href='#g0-85'/> +<use id='g2-88' transform='scale(0.714)' xlink:href='#g0-88'/> +<use id='g2-97' transform='scale(0.714)' xlink:href='#g0-97'/> +<use id='g2-98' transform='scale(0.714)' xlink:href='#g0-98'/> +<use id='g2-99' transform='scale(0.714)' xlink:href='#g0-99'/> +<use id='g2-100' transform='scale(0.714)' xlink:href='#g0-100'/> +<use id='g2-101' transform='scale(0.714)' xlink:href='#g0-101'/> +<use id='g2-103' transform='scale(0.714)' xlink:href='#g0-103'/> +<use id='g2-104' transform='scale(0.714)' xlink:href='#g0-104'/> +<use id='g2-108' transform='scale(0.714)' xlink:href='#g0-108'/> +<use id='g2-109' transform='scale(0.714)' xlink:href='#g0-109'/> +<use id='g2-110' transform='scale(0.714)' xlink:href='#g0-110'/> +<use id='g2-111' transform='scale(0.714)' xlink:href='#g0-111'/> +<use id='g2-112' transform='scale(0.714)' xlink:href='#g0-112'/> +<use id='g2-114' transform='scale(0.714)' xlink:href='#g0-114'/> +<use id='g2-115' transform='scale(0.714)' xlink:href='#g0-115'/> +<use id='g2-116' transform='scale(0.714)' xlink:href='#g0-116'/> +<use id='g2-117' transform='scale(0.714)' xlink:href='#g0-117'/> +<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/> +<use id='g2-122' transform='scale(0.714)' xlink:href='#g0-122'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/> +<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/> +<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/> +<path d='M1.339 -0.007V-0.628H0.711V0H0.907L0.704 0.893H1.018L1.339 -0.007Z' id='g0-44'/> +<path d='M2.05 -1.332V-1.771H0.084V-1.332H2.05Z' id='g0-45'/> +<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/> +<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/> +<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/> +<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/> +<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/> +<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/> +<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/> +<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/> +<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/> +<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/> +<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/> +<path d='M1.339 -3.096H0.711V-2.469H1.339V-3.096ZM0.711 -0.628V0H1.339V-0.628H0.711Z' id='g0-58'/> +<path d='M4.142 -0.614C4.038 -0.614 4.024 -0.614 3.968 -0.586C3.626 -0.467 3.271 -0.391 2.901 -0.391C1.778 -0.391 0.976 -1.339 0.976 -2.42C0.976 -3.592 1.883 -4.449 2.859 -4.449C3.055 -4.449 3.515 -4.4 3.745 -3.843C3.55 -3.954 3.333 -4.003 3.152 -4.003C2.406 -4.003 1.778 -3.306 1.778 -2.42C1.778 -1.513 2.427 -0.837 3.145 -0.837C3.689 -0.837 4.519 -1.276 4.519 -2.518C4.519 -3.222 4.47 -4.91 2.866 -4.91C1.541 -4.91 0.411 -3.815 0.411 -2.42C0.411 -1.039 1.527 0.07 2.873 0.07C3.515 0.07 4.115 -0.195 4.519 -0.614H4.142ZM3.152 -1.297C2.72 -1.297 2.343 -1.778 2.343 -2.42C2.343 -3.082 2.734 -3.543 3.145 -3.543C3.578 -3.543 3.954 -3.062 3.954 -2.42C3.954 -1.757 3.564 -1.297 3.152 -1.297Z' id='g0-64'/> +<path d='M4.317 -0.851C3.829 -0.551 3.605 -0.418 2.908 -0.418C1.827 -0.418 1.172 -1.43 1.172 -2.434C1.172 -3.466 1.89 -4.435 2.908 -4.435C3.368 -4.435 3.843 -4.289 4.163 -4.045L4.275 -4.679C3.787 -4.861 3.396 -4.917 2.887 -4.917C1.506 -4.917 0.474 -3.773 0.474 -2.427C0.474 -0.99 1.569 0.07 2.929 0.07C3.612 0.07 3.898 -0.07 4.359 -0.321L4.317 -0.851Z' id='g0-67'/> +<path d='M4.442 -2.085H2.88V-1.625H3.829V-0.558C3.522 -0.481 3.222 -0.418 2.908 -0.418C1.834 -0.418 1.172 -1.43 1.172 -2.427C1.172 -3.382 1.82 -4.435 2.873 -4.435C3.515 -4.435 3.919 -4.24 4.268 -3.947L4.38 -4.582C3.898 -4.812 3.473 -4.924 2.943 -4.924C1.534 -4.924 0.474 -3.822 0.474 -2.427C0.474 -1.067 1.527 0.07 2.901 0.07C3.403 0.07 3.996 -0.042 4.442 -0.272V-2.085Z' id='g0-71'/> +<path d='M1.381 -4.84H0.676V0H1.381V-4.84Z' id='g0-73'/> +<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/> +<path d='M4.4 -4.84H3.794V-1.625C3.794 -0.69 3.166 -0.265 2.566 -0.265S1.381 -0.697 1.381 -1.618V-4.84H0.676V-1.632C0.676 -0.607 1.555 0.146 2.559 0.146C3.557 0.146 4.4 -0.614 4.4 -1.632V-4.84Z' id='g0-85'/> +<path d='M2.755 -2.552L4.519 -4.84H3.759L2.413 -3.055L1.039 -4.84H0.209L2.071 -2.552L0.105 0H0.865L2.413 -2.099L3.996 0H4.826L2.755 -2.552Z' id='g0-88'/> +<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/> +<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/> +<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/> +<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/> +<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/> +<path d='M3.508 -3.166C3.354 -3.166 2.887 -3.159 2.357 -2.957L2.343 -2.95C2.092 -3.117 1.848 -3.166 1.646 -3.166C0.962 -3.166 0.453 -2.629 0.453 -2.029C0.453 -1.785 0.537 -1.534 0.697 -1.339C0.6 -1.22 0.495 -1.025 0.495 -0.76C0.495 -0.488 0.607 -0.314 0.669 -0.23C0.286 -0.007 0.209 0.314 0.209 0.481C0.209 1.011 0.941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 0.481C3.487 -0.502 2.267 -0.502 1.967 -0.502H1.318C1.206 -0.502 0.907 -0.502 0.907 -0.865C0.907 -1.004 0.955 -1.074 0.962 -1.088C1.206 -0.934 1.451 -0.886 1.639 -0.886C2.322 -0.886 2.831 -1.423 2.831 -2.022C2.831 -2.246 2.769 -2.448 2.643 -2.636C2.615 -2.678 2.615 -2.685 2.615 -2.692C2.615 -2.72 3.034 -2.72 3.068 -2.72C3.075 -2.72 3.34 -2.72 3.592 -2.692L3.508 -3.166ZM1.646 -1.318C1.269 -1.318 0.99 -1.555 0.99 -2.022C0.99 -2.566 1.339 -2.734 1.639 -2.734C2.015 -2.734 2.294 -2.497 2.294 -2.029C2.294 -1.485 1.946 -1.318 1.646 -1.318ZM1.974 0.042C2.134 0.042 2.957 0.042 2.957 0.488C2.957 0.788 2.434 0.997 1.848 0.997S0.739 0.788 0.739 0.488C0.739 0.453 0.739 0.042 1.304 0.042H1.974Z' id='g0-103'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.625 -3.166 1.304 -2.817 1.165 -2.671V-4.84H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-104'/> +<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/> +<path d='M1.381 -4.784H0.676V-4.08H1.381V-4.784ZM-0.453 1.186C-0.133 1.36 0.181 1.423 0.446 1.423C0.928 1.423 1.381 1.053 1.381 0.411V-3.096H0.795V0.46C0.795 0.586 0.795 0.697 0.649 0.816C0.488 0.934 0.293 0.934 0.23 0.934C-0.063 0.934 -0.244 0.802 -0.328 0.725L-0.453 1.186Z' id='g0-106'/> +<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/> +<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/> +<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/> +<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/> +<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/> +<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/> +<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/> +<path d='M3.243 -3.096H2.636V-1.074C2.636 -0.516 2.162 -0.342 1.757 -0.342C1.241 -0.342 1.186 -0.481 1.186 -0.802V-3.096H0.579V-0.76C0.579 -0.139 0.851 0.07 1.339 0.07C1.625 0.07 2.239 0.014 2.657 -0.321V0H3.243V-3.096Z' id='g0-117'/> +<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/> +<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/> +<path d='M2.957 -2.803V-3.096H0.307V-2.65H1.332C1.416 -2.65 1.499 -2.657 1.583 -2.657H2.127L0.209 -0.307V0H2.978V-0.467H1.897C1.813 -0.467 1.73 -0.46 1.646 -0.46H1.039L2.957 -2.803Z' id='g0-122'/> +</defs> +<g id='page8'> +<path d='M194.617 258.141V249.281M253.285 258.141V249.281M311.953 258.141V249.281M370.625 258.141V249.281M429.293 258.141V249.281M194.617 72.66V81.519M253.285 72.66V81.519M311.953 72.66V81.519M370.625 72.66V81.519M429.293 72.66V81.519' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.266V81.519M223.953 77.266V81.519M282.621 77.266V81.519M341.289 77.266V81.519M399.957 77.266V81.519M458.629 77.266V81.519' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.519H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.519H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 249.281V81.519H487.961V249.281H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 74.992)'> +<use x='168.285' xlink:href='#g3-97' y='188.688'/> +<use x='172.353' xlink:href='#g3-108' y='188.688'/> +<use x='174.373' xlink:href='#g3-108' y='188.688'/> +<use x='176.393' xlink:href='#g3-111' y='188.688'/> +<use x='180.863' xlink:href='#g3-99' y='188.688'/> +<use x='184.627' xlink:href='#g3-45' y='188.688'/> +<use x='187.449' xlink:href='#g3-116' y='188.688'/> +<use x='190.507' xlink:href='#g3-101' y='188.688'/> +<use x='194.271' xlink:href='#g3-115' y='188.688'/> +<use x='197.517' xlink:href='#g3-116' y='188.688'/> +<use x='200.575' xlink:href='#g3-49' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 36.532 74.992)'> +<use x='168.285' xlink:href='#g3-97' y='188.688'/> +<use x='172.353' xlink:href='#g3-108' y='188.688'/> +<use x='174.373' xlink:href='#g3-108' y='188.688'/> +<use x='176.393' xlink:href='#g3-111' y='188.688'/> +<use x='180.863' xlink:href='#g3-99' y='188.688'/> +<use x='184.627' xlink:href='#g3-45' y='188.688'/> +<use x='187.449' xlink:href='#g3-116' y='188.688'/> +<use x='190.507' xlink:href='#g3-101' y='188.688'/> +<use x='194.271' xlink:href='#g3-115' y='188.688'/> +<use x='197.517' xlink:href='#g3-116' y='188.688'/> +<use x='200.575' xlink:href='#g3-78' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 94.98 74.992)'> +<use x='168.285' xlink:href='#g3-115' y='188.688'/> +<use x='171.531' xlink:href='#g3-104' y='188.688'/> +<use x='175.904' xlink:href='#g3-54' y='188.688'/> +<use x='180.138' xlink:href='#g3-98' y='188.688'/> +<use x='184.746' xlink:href='#g3-101' y='188.688'/> +<use x='188.509' xlink:href='#g3-110' y='188.688'/> +<use x='192.882' xlink:href='#g3-99' y='188.688'/> +<use x='196.646' xlink:href='#g3-104' y='188.688'/> +<use x='201.018' xlink:href='#g3-78' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 153.649 74.992)'> +<use x='168.285' xlink:href='#g3-115' y='188.688'/> +<use x='171.531' xlink:href='#g3-104' y='188.688'/> +<use x='175.904' xlink:href='#g3-56' y='188.688'/> +<use x='180.138' xlink:href='#g3-98' y='188.688'/> +<use x='184.746' xlink:href='#g3-101' y='188.688'/> +<use x='188.509' xlink:href='#g3-110' y='188.688'/> +<use x='192.882' xlink:href='#g3-99' y='188.688'/> +<use x='196.646' xlink:href='#g3-104' y='188.688'/> +<use x='201.018' xlink:href='#g3-78' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 207.225 74.992)'> +<use x='168.285' xlink:href='#g3-120' y='188.688'/> +<use x='172.187' xlink:href='#g3-109' y='188.688'/> +<use x='178.912' xlink:href='#g3-97' y='188.688'/> +<use x='182.98' xlink:href='#g3-108' y='188.688'/> +<use x='185' xlink:href='#g3-108' y='188.688'/> +<use x='187.02' xlink:href='#g3-111' y='188.688'/> +<use x='191.49' xlink:href='#g3-99' y='188.688'/> +<use x='195.254' xlink:href='#g3-45' y='188.688'/> +<use x='198.076' xlink:href='#g3-116' y='188.688'/> +<use x='201.134' xlink:href='#g3-101' y='188.688'/> +<use x='204.898' xlink:href='#g3-115' y='188.688'/> +<use x='208.144' xlink:href='#g3-116' y='188.688'/> +<use x='211.202' xlink:href='#g3-78' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 263.494 74.992)'> +<use x='168.285' xlink:href='#g3-99' y='188.688'/> +<use x='172.049' xlink:href='#g3-97' y='188.688'/> +<use x='176.117' xlink:href='#g3-99' y='188.688'/> +<use x='179.88' xlink:href='#g3-104' y='188.688'/> +<use x='184.253' xlink:href='#g3-101' y='188.688'/> +<use x='188.017' xlink:href='#g3-45' y='188.688'/> +<use x='190.839' xlink:href='#g3-115' y='188.688'/> +<use x='194.086' xlink:href='#g3-99' y='188.688'/> +<use x='197.849' xlink:href='#g3-114' y='188.688'/> +<use x='200.741' xlink:href='#g3-97' y='188.688'/> +<use x='204.81' xlink:href='#g3-116' y='188.688'/> +<use x='207.868' xlink:href='#g3-99' y='188.688'/> +<use x='211.631' xlink:href='#g3-104' y='188.688'/> +<use x='216.004' xlink:href='#g3-78' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 62.23)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.677)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -4.876)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -38.43)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.983)'> +<use x='168.285' xlink:href='#g2-50' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -105.536)'> +<use x='168.285' xlink:href='#g2-50' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-120' y='188.688'/> +</g> +<path clip-path='url(#clip8)' d='M135.949 182.176H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M142.742 249.281H145.981V182.176H142.742ZM201.41 249.281H204.649V182.176H201.41ZM260.078 249.281H263.317V182.176H260.078ZM318.75 249.281H321.988V182.176H318.75ZM377.418 249.281H380.656V182.176H377.418ZM436.086 249.281H439.324V182.176H436.086Z' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M142.742 249.281H145.981V182.176H142.742ZM201.41 249.281H204.649V182.176H201.41ZM260.078 249.281H263.317V182.176H260.078ZM318.75 249.281H321.988V182.176H318.75ZM377.418 249.281H380.656V182.176H377.418ZM436.086 249.281H439.324V182.176H436.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M144.359 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M142.367 182.176H146.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M144.359 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M142.367 182.176H146.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M203.031 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M201.035 182.176H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M203.031 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M201.035 182.176H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M261.699 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M259.707 182.176H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M261.699 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M259.707 182.176H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M320.367 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M318.375 182.176H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M320.367 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M318.375 182.176H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M379.035 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M377.043 182.176H381.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M379.035 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M377.043 182.176H381.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M437.707 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M435.711 182.176H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M437.707 182.176V182.176' fill='#ffffff'/> +<path clip-path='url(#clip8)' d='M435.711 182.176H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M147.973 249.281H151.211V164.73H147.973ZM206.641 249.281H209.879V161.977H206.641ZM265.309 249.281H268.547V183.25H265.309ZM323.981 249.281H327.219V209.891H323.981ZM382.649 249.281H385.887V224.184H382.649ZM441.317 249.281H444.555V141.242H441.317Z' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M147.973 249.281H151.211V164.73H147.973ZM206.641 249.281H209.879V161.977H206.641ZM265.309 249.281H268.547V183.25H265.309ZM323.981 249.281H327.219V209.891H323.981ZM382.649 249.281H385.887V224.184H382.649ZM441.317 249.281H444.555V141.242H441.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M149.59 164.73V164.73' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M147.598 164.73H151.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M149.59 164.73V164.73' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M147.598 164.73H151.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M208.262 161.977V161.977' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M206.266 161.976H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M208.262 161.977V161.977' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M206.266 161.976H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M266.93 183.25V183.25' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M264.938 183.25H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M266.93 183.25V183.25' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M264.938 183.25H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M325.598 209.891V209.891' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M323.606 209.891H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M325.598 209.891V209.891' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M323.606 209.891H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M384.266 224.184V224.184' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M382.274 224.183H386.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M384.266 224.184V224.184' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M382.274 224.183H386.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M442.938 141.242V141.242' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M440.942 141.242H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M442.938 141.242V141.242' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M440.942 141.242H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M153.203 249.281H156.442V185.129H153.203ZM211.871 249.281H215.11V177.883H211.871ZM270.539 249.281H273.777V181.437H270.539ZM329.211 249.281H332.449V192.848H329.211ZM387.879 249.281H391.117V183.719H387.879ZM446.547 249.281H449.785V145H446.547Z' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M153.203 249.281H156.442V185.129H153.203ZM211.871 249.281H215.11V177.883H211.871ZM270.539 249.281H273.777V181.437H270.539ZM329.211 249.281H332.449V192.848H329.211ZM387.879 249.281H391.117V183.719H387.879ZM446.547 249.281H449.785V145H446.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M154.82 185.129V185.129' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M152.828 185.129H156.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M154.82 185.129V185.129' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M152.828 185.129H156.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M213.492 177.883V177.883' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M211.496 177.883H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M213.492 177.883V177.883' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M211.496 177.883H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M272.16 181.437V181.437' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M270.168 181.438H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M272.16 181.437V181.437' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M270.168 181.438H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M330.828 192.848V192.848' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M328.836 192.848H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M330.828 192.848V192.848' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M328.836 192.848H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M389.496 183.719V183.719' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M387.504 183.718H391.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M389.496 183.719V183.719' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M387.504 183.718H391.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M448.168 145V145' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M446.172 145H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M448.168 145V145' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M446.172 145H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M158.434 249.281H161.672V180.969H158.434ZM217.102 249.281H220.34V172.043H217.102ZM275.77 249.281H279.008V172.312H275.77ZM334.442 249.281H337.68V194.996H334.442ZM393.109 249.281H396.348V195.531H393.109ZM451.777 249.281H455.016V180.098H451.777Z' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M158.434 249.281H161.672V180.969H158.434ZM217.102 249.281H220.34V172.043H217.102ZM275.77 249.281H279.008V172.312H275.77ZM334.442 249.281H337.68V194.996H334.442ZM393.109 249.281H396.348V195.531H393.109ZM451.777 249.281H455.016V180.098H451.777Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M160.051 180.969V180.969' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M158.058 180.969H162.042' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M160.051 180.969V180.969' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M158.058 180.969H162.042' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M218.723 172.043V172.043' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M216.726 172.043H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M218.723 172.043V172.043' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M216.726 172.043H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M277.391 172.312V172.312' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M275.398 172.312H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M277.391 172.312V172.312' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M275.398 172.312H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M336.059 194.996V194.996' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M334.066 194.996H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M336.059 194.996V194.996' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M334.066 194.996H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M394.727 195.531V195.531' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M392.734 195.531H396.718' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M394.727 195.531V195.531' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M392.734 195.531H396.718' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M453.399 180.098V180.098' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M451.402 180.098H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M453.399 180.098V180.098' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M451.402 180.098H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M163.664 249.281H166.903V180.363H163.664ZM222.332 249.281H225.57V144.465H222.332ZM281 249.281H284.238V171.707H281ZM339.672 249.281H342.91V191.641H339.672ZM398.34 249.281H401.578V81.519H398.34ZM457.008 249.281H460.246V190.027H457.008Z' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M163.664 249.281H166.903V180.363H163.664ZM222.332 249.281H225.57V144.465H222.332ZM281 249.281H284.238V171.707H281ZM339.672 249.281H342.91V191.641H339.672ZM398.34 249.281H401.578V81.519H398.34ZM457.008 249.281H460.246V190.027H457.008Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M165.281 180.363V180.363' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M163.289 180.363H167.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M165.281 180.363V180.363' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M163.289 180.363H167.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M223.953 144.465V144.465' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M221.957 144.464H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M223.953 144.465V144.465' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M221.957 144.464H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M282.621 171.707V171.707' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M280.629 171.707H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M282.621 171.707V171.707' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M280.629 171.707H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M341.289 191.641V191.641' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M339.297 191.641H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M341.289 191.641V191.641' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M339.297 191.641H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M399.957 81.519V81.519' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M397.965 81.52H401.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M399.957 81.519V81.519' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M397.965 81.52H401.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M458.629 190.027V190.027' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M456.633 190.027H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M458.629 190.027V190.027' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M456.633 190.027H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M168.895 249.281H172.133V157.348H168.895ZM227.563 249.281H230.801V81.519H227.563ZM286.231 249.281H289.469V141.711H286.231ZM344.902 249.281H348.141V124.601H344.902ZM403.57 249.281H406.809V132.25H403.57ZM462.238 249.281H465.477V189.894H462.238Z' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M168.895 249.281H172.133V157.348H168.895ZM227.563 249.281H230.801V81.519H227.563ZM286.231 249.281H289.469V141.711H286.231ZM344.902 249.281H348.141V124.601H344.902ZM403.57 249.281H406.809V132.25H403.57ZM462.238 249.281H465.477V189.894H462.238Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M170.512 157.348V157.348' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M168.519 157.348H172.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M170.512 157.348V157.348' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M168.519 157.348H172.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M229.184 81.519V81.519' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M227.187 81.52H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M229.184 81.519V81.519' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M227.187 81.52H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M287.852 141.711V141.711' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M285.859 141.711H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M287.852 141.711V141.711' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M285.859 141.711H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M346.52 124.601V124.601' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M344.527 124.602H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M346.52 124.601V124.601' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M344.527 124.602H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M405.188 132.25V132.25' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M403.195 132.25H407.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M405.188 132.25V132.25' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M403.195 132.25H407.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M463.859 189.894V189.894' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M461.863 189.894H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M463.859 189.894V189.894' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M461.863 189.894H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M174.125 249.281H177.363V171.574H174.125ZM232.793 249.281H236.031V146.344H232.793ZM291.461 249.281H294.699V169.426H291.461ZM350.133 249.281H353.371V204.254H350.133ZM408.801 249.281H412.039V224.992H408.801ZM467.469 249.281H470.707V163.254H467.469Z' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M174.125 249.281H177.363V171.574H174.125ZM232.793 249.281H236.031V146.344H232.793ZM291.461 249.281H294.699V169.426H291.461ZM350.133 249.281H353.371V204.254H350.133ZM408.801 249.281H412.039V224.992H408.801ZM467.469 249.281H470.707V163.254H467.469Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M175.742 171.574V171.574' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M173.75 171.574H177.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M175.742 171.574V171.574' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M173.75 171.574H177.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M234.414 146.344V146.344' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M232.418 146.343H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M234.414 146.344V146.344' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M232.418 146.343H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M293.082 169.426V169.426' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M291.09 169.426H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M293.082 169.426V169.426' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M291.09 169.426H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M351.75 204.254V204.254' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M349.758 204.254H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M351.75 204.254V204.254' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M349.758 204.254H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M410.418 224.992V224.992' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M408.426 224.992H412.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M410.418 224.992V224.992' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M408.426 224.992H412.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M469.09 163.254V163.254' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M467.094 163.254H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M469.09 163.254V163.254' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M467.094 163.254H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M179.356 249.281H182.594V176.004H179.356ZM238.024 249.281H241.262V169.16H238.024ZM296.692 249.281H299.93V149.699H296.692ZM355.363 249.281H358.602V121.043H355.363ZM414.031 249.281H417.27V214.051H414.031ZM472.699 249.281H475.938V194.121H472.699Z' fill='#942994'/> +<path clip-path='url(#clip8)' d='M179.356 249.281H182.594V176.004H179.356ZM238.024 249.281H241.262V169.16H238.024ZM296.692 249.281H299.93V149.699H296.692ZM355.363 249.281H358.602V121.043H355.363ZM414.031 249.281H417.27V214.051H414.031ZM472.699 249.281H475.938V194.121H472.699Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M180.973 176.004V176.004' fill='#942994'/> +<path clip-path='url(#clip8)' d='M178.98 176.004H182.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M180.973 176.004V176.004' fill='#942994'/> +<path clip-path='url(#clip8)' d='M178.98 176.004H182.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M239.645 169.16V169.16' fill='#942994'/> +<path clip-path='url(#clip8)' d='M237.648 169.16H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M239.645 169.16V169.16' fill='#942994'/> +<path clip-path='url(#clip8)' d='M237.648 169.16H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M298.313 149.699V149.699' fill='#942994'/> +<path clip-path='url(#clip8)' d='M296.32 149.7H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M298.313 149.699V149.699' fill='#942994'/> +<path clip-path='url(#clip8)' d='M296.32 149.7H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M356.981 121.043V121.043' fill='#942994'/> +<path clip-path='url(#clip8)' d='M354.988 121.043H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M356.981 121.043V121.043' fill='#942994'/> +<path clip-path='url(#clip8)' d='M354.988 121.043H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M415.649 214.051V214.051' fill='#942994'/> +<path clip-path='url(#clip8)' d='M413.656 214.05H417.64' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M415.649 214.051V214.051' fill='#942994'/> +<path clip-path='url(#clip8)' d='M413.656 214.05H417.64' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M474.32 194.121V194.121' fill='#942994'/> +<path clip-path='url(#clip8)' d='M472.324 194.121H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M474.32 194.121V194.121' fill='#942994'/> +<path clip-path='url(#clip8)' d='M472.324 194.121H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M184.586 249.281H187.824V181.641H184.586ZM243.254 249.281H246.492V115.137H243.254ZM301.922 249.281H305.16V176.605H301.922ZM360.594 249.281H363.832V185.734H360.594ZM419.262 249.281H422.5V164.125H419.262ZM477.93 249.281H481.168V179.828H477.93Z' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M184.586 249.281H187.824V181.641H184.586ZM243.254 249.281H246.492V115.137H243.254ZM301.922 249.281H305.16V176.605H301.922ZM360.594 249.281H363.832V185.734H360.594ZM419.262 249.281H422.5V164.125H419.262ZM477.93 249.281H481.168V179.828H477.93Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M186.203 181.641V181.641' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M184.211 181.64H188.196' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M186.203 181.641V181.641' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M184.211 181.64H188.196' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M244.875 115.137V115.137' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M242.879 115.137H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M244.875 115.137V115.137' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M242.879 115.137H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M303.543 176.605V176.605' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M301.551 176.605H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M303.543 176.605V176.605' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M301.551 176.605H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M362.211 185.734V185.734' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M360.219 185.735H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M362.211 185.734V185.734' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M360.219 185.735H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M420.879 164.125V164.125' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M418.887 164.125H422.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M420.879 164.125V164.125' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M418.887 164.125H422.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M479.551 179.828V179.828' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M477.555 179.828H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M479.551 179.828V179.828' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M477.555 179.828H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M420.539 310.336H487.762V276.324H420.539Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 255.575 118.327)'> +<use x='168.285' xlink:href='#g2-99' y='164.777'/> +<use x='170.637' xlink:href='#g2-53' y='164.777'/> +<use x='173.284' xlink:href='#g2-45' y='164.777'/> +<use x='175.048' xlink:href='#g2-49' y='164.777'/> +<use x='177.694' xlink:href='#g2-56' y='164.777'/> +<use x='180.341' xlink:href='#g2-120' y='164.777'/> +<use x='182.779' xlink:href='#g2-108' y='164.777'/> +<use x='184.042' xlink:href='#g2-97' y='164.777'/> +<use x='186.438' xlink:href='#g2-114' y='164.777'/> +<use x='188.245' xlink:href='#g2-103' y='164.777'/> +<use x='190.891' xlink:href='#g2-101' y='164.777'/> +<use x='193.244' xlink:href='#g2-44' y='164.777'/> +<use x='196.478' xlink:href='#g2-49' y='164.777'/> +<use x='199.124' xlink:href='#g2-52' y='164.777'/> +<use x='201.771' xlink:href='#g2-52' y='164.777'/> +<use x='204.417' xlink:href='#g2-71' y='164.777'/> +<use x='207.946' xlink:href='#g2-98' y='164.777'/> +<use x='168.285' xlink:href='#g2-55' y='170.755'/> +<use x='170.931' xlink:href='#g2-50' y='170.755'/> +<use x='175.342' xlink:href='#g2-112' y='170.755'/> +<use x='177.928' xlink:href='#g2-114' y='170.755'/> +<use x='179.735' xlink:href='#g2-111' y='170.755'/> +<use x='182.529' xlink:href='#g2-99' y='170.755'/> +<use x='186.645' xlink:href='#g2-73' y='170.755'/> +<use x='188.115' xlink:href='#g2-110' y='170.755'/> +<use x='190.848' xlink:href='#g2-116' y='170.755'/> +<use x='192.759' xlink:href='#g2-101' y='170.755'/> +<use x='195.112' xlink:href='#g2-108' y='170.755'/> +<use x='198.139' xlink:href='#g2-88' y='170.755'/> +<use x='201.667' xlink:href='#g2-101' y='170.755'/> +<use x='204.019' xlink:href='#g2-111' y='170.755'/> +<use x='206.666' xlink:href='#g2-110' y='170.755'/> +<use x='211.163' xlink:href='#g2-64' y='170.755'/> +<use x='214.691' xlink:href='#g2-51' y='170.755'/> +<use x='217.338' xlink:href='#g2-71' y='170.755'/> +<use x='220.866' xlink:href='#g2-104' y='170.755'/> +<use x='223.599' xlink:href='#g2-122' y='170.755'/> +<use x='168.285' xlink:href='#g2-85' y='176.733'/> +<use x='171.917' xlink:href='#g2-98' y='176.733'/> +<use x='174.65' xlink:href='#g2-117' y='176.733'/> +<use x='177.383' xlink:href='#g2-110' y='176.733'/> +<use x='180.116' xlink:href='#g2-116' y='176.733'/> +<use x='182.027' xlink:href='#g2-117' y='176.733'/> +<use x='186.524' xlink:href='#g2-49' y='176.733'/> +<use x='189.17' xlink:href='#g2-56' y='176.733'/> +<use x='191.817' xlink:href='#g2-46' y='176.733'/> +<use x='193.287' xlink:href='#g2-48' y='176.733'/> +<use x='195.933' xlink:href='#g2-52' y='176.733'/> +<use x='198.58' xlink:href='#g2-46' y='176.733'/> +<use x='200.05' xlink:href='#g2-49' y='176.733'/> +<use x='202.696' xlink:href='#g2-44' y='176.733'/> +<use x='205.931' xlink:href='#g2-71' y='176.733'/> +<use x='209.459' xlink:href='#g2-67' y='176.733'/> +<use x='212.841' xlink:href='#g2-67' y='176.733'/> +<use x='217.986' xlink:href='#g2-55' y='176.733'/> +<use x='220.633' xlink:href='#g2-46' y='176.733'/> +<use x='222.103' xlink:href='#g2-52' y='176.733'/> +<use x='224.749' xlink:href='#g2-46' y='176.733'/> +<use x='226.219' xlink:href='#g2-48' y='176.733'/> +<use x='168.285' xlink:href='#g2-51' y='182.71'/> +<use x='170.931' xlink:href='#g2-54' y='182.71'/> +<use x='175.342' xlink:href='#g2-99' y='182.71'/> +<use x='177.694' xlink:href='#g2-111' y='182.71'/> +<use x='180.193' xlink:href='#g2-114' y='182.71'/> +<use x='182.001' xlink:href='#g2-101' y='182.71'/> +<use x='184.353' xlink:href='#g2-115' y='182.71'/> +<use x='188.146' xlink:href='#g2-111' y='182.71'/> +<use x='190.793' xlink:href='#g2-110' y='182.71'/> +<use x='195.29' xlink:href='#g2-50' y='182.71'/> +<use x='199.7' xlink:href='#g2-110' y='182.71'/> +<use x='202.433' xlink:href='#g2-117' y='182.71'/> +<use x='205.166' xlink:href='#g2-109' y='182.71'/> +<use x='209.369' xlink:href='#g2-97' y='182.71'/> +<use x='213.676' xlink:href='#g2-110' y='182.71'/> +<use x='216.409' xlink:href='#g2-111' y='182.71'/> +<use x='219.202' xlink:href='#g2-100' y='182.71'/> +<use x='221.935' xlink:href='#g2-101' y='182.71'/> +<use x='224.287' xlink:href='#g2-115' y='182.71'/> +<use x='168.285' xlink:href='#g2-50' y='188.688'/> +<use x='170.931' xlink:href='#g2-48' y='188.688'/> +<use x='173.578' xlink:href='#g2-50' y='188.688'/> +<use x='176.224' xlink:href='#g2-48' y='188.688'/> +<use x='178.87' xlink:href='#g2-45' y='188.688'/> +<use x='180.635' xlink:href='#g2-48' y='188.688'/> +<use x='183.281' xlink:href='#g2-49' y='188.688'/> +<use x='185.927' xlink:href='#g2-45' y='188.688'/> +<use x='187.692' xlink:href='#g2-49' y='188.688'/> +<use x='190.338' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -42.693 344.258)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 15.976 344.258)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 74.645 344.258)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 133.314 344.258)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 191.983 344.258)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 250.652 344.258)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -37.462 326.81)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-50' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 21.207 324.059)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-51' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 79.876 345.332)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-57' y='188.688'/> +<use x='175.048' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 138.545 371.973)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-57' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 197.214 386.266)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-51' y='188.688'/> +<use x='175.048' xlink:href='#g2-55' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 255.882 303.323)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-54' y='188.688'/> +<use x='175.048' xlink:href='#g2-49' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -32.232 347.211)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-57' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 26.437 339.963)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 85.106 343.52)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-49' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 143.775 354.928)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-52' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 202.444 345.801)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-57' y='188.688'/> +<use x='175.048' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 261.113 307.081)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-53' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -27.002 343.05)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-50' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 31.667 334.125)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-49' y='188.688'/> +<use x='175.048' xlink:href='#g2-53' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 90.336 334.393)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-49' y='188.688'/> +<use x='175.048' xlink:href='#g2-53' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 149.005 357.075)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-49' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 207.674 357.612)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 266.343 342.178)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-51' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -21.771 342.446)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-51' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 36.898 306.544)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 95.567 333.789)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-49' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 154.236 353.72)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 212.905 243.599)'> +<use x='163.396' xlink:href='#g4-1' y='188.688'/> +<use x='166.901' xlink:href='#g4-1' y='188.688'/> +<use x='170.407' xlink:href='#g4-1' y='188.688'/> +<use x='173.912' xlink:href='#g2-50' y='188.688'/> +<use x='176.558' xlink:href='#g2-55' y='188.688'/> +<use x='179.205' xlink:href='#g2-46' y='188.688'/> +<use x='180.675' xlink:href='#g2-51' y='188.688'/> +<use x='183.321' xlink:href='#g2-51' y='188.688'/> +<use x='185.968' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 271.574 352.109)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -16.541 319.429)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-51' y='188.688'/> +<use x='175.048' xlink:href='#g2-55' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 42.128 243.599)'> +<use x='163.396' xlink:href='#g4-1' y='188.688'/> +<use x='166.901' xlink:href='#g4-1' y='188.688'/> +<use x='170.407' xlink:href='#g4-1' y='188.688'/> +<use x='173.912' xlink:href='#g2-51' y='188.688'/> +<use x='176.558' xlink:href='#g2-46' y='188.688'/> +<use x='178.029' xlink:href='#g2-51' y='188.688'/> +<use x='180.675' xlink:href='#g2-54' y='188.688'/> +<use x='183.321' xlink:href='#g2-120' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 100.797 303.793)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-54' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 159.466 286.681)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 218.135 294.331)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-55' y='188.688'/> +<use x='175.048' xlink:href='#g2-52' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 276.804 351.975)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-57' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -11.31 333.655)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-49' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 47.359 308.423)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-51' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 106.028 331.508)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-49' y='188.688'/> +<use x='175.048' xlink:href='#g2-57' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 164.697 366.336)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-54' y='188.688'/> +<use x='175.048' xlink:href='#g2-55' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 223.366 387.072)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-51' y='188.688'/> +<use x='175.048' xlink:href='#g2-54' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 282.035 325.334)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-50' y='188.688'/> +<use x='175.048' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -6.08 338.084)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-57' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 52.589 331.239)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-49' y='188.688'/> +<use x='175.048' xlink:href='#g2-57' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 111.258 311.779)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-52' y='188.688'/> +<use x='175.048' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 169.927 283.124)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-57' y='188.688'/> +<use x='175.048' xlink:href='#g2-49' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 228.596 376.133)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-53' y='188.688'/> +<use x='175.048' xlink:href='#g2-50' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 287.265 356.203)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-56' y='188.688'/> +<use x='175.048' xlink:href='#g2-50' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -0.849 343.721)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-49' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 57.82 277.219)'> +<use x='168.285' xlink:href='#g2-50' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-48' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 116.489 338.688)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-56' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 175.158 347.815)'> +<use x='168.285' xlink:href='#g2-48' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-57' y='188.688'/> +<use x='175.048' xlink:href='#g2-53' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 233.827 326.206)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-50' y='188.688'/> +<use x='175.048' xlink:href='#g2-55' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 292.496 341.909)'> +<use x='168.285' xlink:href='#g2-49' y='188.688'/> +<use x='170.931' xlink:href='#g2-46' y='188.688'/> +<use x='172.401' xlink:href='#g2-48' y='188.688'/> +<use x='175.048' xlink:href='#g2-52' y='188.688'/> +</g> +<g transform='matrix(0 -1 1 0 -75.53 385.58)'> +<use x='168.285' xlink:href='#g1-82' y='188.688'/> +<use x='174.255' xlink:href='#g1-101' y='188.688'/> +<use x='178.351' xlink:href='#g1-108' y='188.688'/> +<use x='180.551' xlink:href='#g1-97' y='188.688'/> +<use x='184.979' xlink:href='#g1-116' y='188.688'/> +<use x='188.307' xlink:href='#g1-105' y='188.688'/> +<use x='190.507' xlink:href='#g1-118' y='188.688'/> +<use x='194.755' xlink:href='#g1-101' y='188.688'/> +<use x='201.922' xlink:href='#g1-114' y='188.688'/> +<use x='205.07' xlink:href='#g1-115' y='188.688'/> +<use x='208.603' xlink:href='#g1-115' y='188.688'/> +<use x='215.207' xlink:href='#g3-40' y='188.688'/> +<use x='218.5' xlink:href='#g3-108' y='188.688'/> +<use x='220.521' xlink:href='#g3-111' y='188.688'/> +<use x='224.52' xlink:href='#g3-119' y='188.688'/> +<use x='230.068' xlink:href='#g3-101' y='188.688'/> +<use x='233.832' xlink:href='#g3-114' y='188.688'/> +<use x='239.547' xlink:href='#g3-105' y='188.688'/> +<use x='241.567' xlink:href='#g3-115' y='188.688'/> +<use x='247.636' xlink:href='#g3-98' y='188.688'/> +<use x='252.244' xlink:href='#g3-101' y='188.688'/> +<use x='256.008' xlink:href='#g3-116' y='188.688'/> +<use x='259.066' xlink:href='#g3-116' y='188.688'/> +<use x='262.124' xlink:href='#g3-101' y='188.688'/> +<use x='265.887' xlink:href='#g3-114' y='188.688'/> +<use x='268.779' xlink:href='#g3-41' y='188.688'/> +</g> +<path d='M136.149 309.68H341.363V279.68H136.149Z' fill='#ffffff'/> +<path d='M136.149 309.68H341.363V279.68H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#ffffff'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -40.354 114.479)'> +<use x='195.372' xlink:href='#g3-120' y='175.681'/> +<use x='199.274' xlink:href='#g3-109' y='175.681'/> +<use x='205.999' xlink:href='#g3-105' y='175.681'/> +<use x='208.019' xlink:href='#g3-58' y='175.681'/> +<use x='210.371' xlink:href='#g0-54' y='175.681'/> +<use x='214.076' xlink:href='#g0-57' y='175.681'/> +</g> +<path d='M184.145 290.168H187.133V282.199H184.145ZM190.121 290.168H193.109V284.191H190.121Z' fill='#f0e0f0'/> +<path d='M184.145 290.168H187.133V282.199H184.145ZM190.121 290.168H193.109V284.191H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.441 114.036)'> +<use x='239.382' xlink:href='#g3-116' y='175.681'/> +<use x='242.44' xlink:href='#g3-99' y='175.681'/> +<use x='246.204' xlink:href='#g3-58' y='175.681'/> +<use x='248.556' xlink:href='#g0-54' y='175.681'/> +<use x='252.261' xlink:href='#g0-54' y='175.681'/> +</g> +<path d='M227.356 290.168H230.344V282.199H227.356ZM233.332 290.168H236.32V284.191H233.332Z' fill='#e1c2e1'/> +<path d='M227.356 290.168H230.344V282.199H227.356ZM233.332 290.168H236.32V284.191H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.04 114.479)'> +<use x='281.863' xlink:href='#g3-106' y='175.681'/> +<use x='284.119' xlink:href='#g3-101' y='175.681'/> +<use x='287.882' xlink:href='#g3-58' y='175.681'/> +<use x='290.235' xlink:href='#g0-54' y='175.681'/> +<use x='293.94' xlink:href='#g0-54' y='175.681'/> +</g> +<path d='M269.106 290.168H272.094V282.199H269.106ZM275.086 290.168H278.074V284.191H275.086Z' fill='#d1a3d1'/> +<path d='M269.106 290.168H272.094V282.199H269.106ZM275.086 290.168H278.074V284.191H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.932 114.515)'> +<use x='321.287' xlink:href='#g3-116' y='175.681'/> +<use x='324.345' xlink:href='#g3-98' y='175.681'/> +<use x='328.717' xlink:href='#g3-98' y='175.681'/> +<use x='333.09' xlink:href='#g3-58' y='175.681'/> +<use x='335.442' xlink:href='#g0-54' y='175.681'/> +<use x='339.147' xlink:href='#g0-53' y='175.681'/> +</g> +<path d='M306.203 290.168H309.191V282.199H306.203ZM312.18 290.168H315.168V284.191H312.18Z' fill='#c285c2'/> +<path d='M306.203 290.168H309.191V282.199H306.203ZM312.18 290.168H315.168V284.191H312.18Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.662 114.036)'> +<use x='356.019' xlink:href='#g3-114' y='175.681'/> +<use x='358.911' xlink:href='#g3-112' y='175.681'/> +<use x='363.284' xlink:href='#g3-58' y='175.681'/> +<use x='365.636' xlink:href='#g0-52' y='175.681'/> +<use x='369.341' xlink:href='#g0-52' y='175.681'/> +</g> +<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' fill='#b366b3'/> +<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -43.882 114.515)'> +<use x='195.372' xlink:href='#g3-104' y='188.688'/> +<use x='199.744' xlink:href='#g3-111' y='188.688'/> +<use x='203.978' xlink:href='#g3-97' y='188.688'/> +<use x='207.811' xlink:href='#g3-114' y='188.688'/> +<use x='210.703' xlink:href='#g3-100' y='188.688'/> +<use x='215.076' xlink:href='#g3-58' y='188.688'/> +<use x='217.428' xlink:href='#g0-51' y='188.688'/> +<use x='221.133' xlink:href='#g0-54' y='188.688'/> +</g> +<path d='M184.145 303.176H187.133V295.207H184.145ZM190.121 303.176H193.109V297.199H190.121Z' fill='#a447a4'/> +<path d='M184.145 303.176H187.133V295.207H184.145ZM190.121 303.176H193.109V297.199H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -43.084 114.515)'> +<use x='239.382' xlink:href='#g3-109' y='188.688'/> +<use x='246.107' xlink:href='#g3-101' y='188.688'/> +<use x='249.871' xlink:href='#g3-115' y='188.688'/> +<use x='253.117' xlink:href='#g3-104' y='188.688'/> +<use x='257.489' xlink:href='#g3-58' y='188.688'/> +<use x='259.842' xlink:href='#g0-54' y='188.688'/> +<use x='263.547' xlink:href='#g0-49' y='188.688'/> +</g> +<path d='M227.356 303.176H230.344V295.207H227.356ZM233.332 303.176H236.32V297.199H233.332Z' fill='#942994'/> +<path d='M227.356 303.176H230.344V295.207H227.356ZM233.332 303.176H236.32V297.199H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -42.353 114.515)'> +<use x='281.863' xlink:href='#g3-103' y='188.688'/> +<use x='286.097' xlink:href='#g3-108' y='188.688'/> +<use x='288.118' xlink:href='#g3-105' y='188.688'/> +<use x='290.138' xlink:href='#g3-98' y='188.688'/> +<use x='294.746' xlink:href='#g3-99' y='188.688'/> +<use x='298.509' xlink:href='#g3-58' y='188.688'/> +<use x='300.862' xlink:href='#g0-54' y='188.688'/> +<use x='304.567' xlink:href='#g0-52' y='188.688'/> +</g> +<path d='M269.106 303.176H272.094V295.207H269.106ZM275.086 303.176H278.074V297.199H275.086Z' fill='#850a85'/> +<path d='M269.106 303.176H272.094V295.207H269.106ZM275.086 303.176H278.074V297.199H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -40.026 114.479)'> +<use x='321.287' xlink:href='#g3-115' y='188.688'/> +<use x='324.533' xlink:href='#g3-109' y='188.688'/> +<use x='331.258' xlink:href='#g3-105' y='188.688'/> +<use x='333.278' xlink:href='#g3-58' y='188.688'/> +<use x='335.63' xlink:href='#g0-52' y='188.688'/> +<use x='339.335' xlink:href='#g0-53' y='188.688'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-1.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-1.svg new file mode 100644 index 0000000..c296a04 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-1.svg @@ -0,0 +1,769 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip1'> +<path d='M82.148 203.937H434.164V78.691H82.148Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page1'> +<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 33.989)'> +<use x='114.487' xlink:href='#g2-99' y='183.949'/> +<use x='118.25' xlink:href='#g2-102' y='183.949'/> +<use x='120.838' xlink:href='#g2-114' y='183.949'/> +<use x='123.73' xlink:href='#g2-97' y='183.949'/> +<use x='127.798' xlink:href='#g2-99' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 41.401 33.989)'> +<use x='114.487' xlink:href='#g2-101' y='183.949'/> +<use x='118.25' xlink:href='#g2-115' y='183.949'/> +<use x='121.497' xlink:href='#g2-112' y='183.949'/> +<use x='125.634' xlink:href='#g2-114' y='183.949'/> +<use x='128.526' xlink:href='#g2-101' y='183.949'/> +<use x='132.29' xlink:href='#g2-115' y='183.949'/> +<use x='135.536' xlink:href='#g2-115' y='183.949'/> +<use x='138.782' xlink:href='#g2-111' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 103.095 33.989)'> +<use x='114.487' xlink:href='#g2-98' y='183.949'/> +<use x='118.859' xlink:href='#g2-97' y='183.949'/> +<use x='122.692' xlink:href='#g2-114' y='183.949'/> +<use x='125.584' xlink:href='#g2-110' y='183.949'/> +<use x='129.957' xlink:href='#g2-101' y='183.949'/> +<use x='133.72' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 162.903 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-101' y='183.949'/> +<use x='120.271' xlink:href='#g2-97' y='183.949'/> +<use x='124.339' xlink:href='#g2-110' y='183.949'/> +<use x='128.711' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 223.526 33.989)'> +<use x='114.487' xlink:href='#g2-114' y='183.949'/> +<use x='117.379' xlink:href='#g2-101' y='183.949'/> +<use x='121.142' xlink:href='#g2-100' y='183.949'/> +<use x='125.515' xlink:href='#g2-105' y='183.949'/> +<use x='127.535' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 277.054 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-97' y='183.949'/> +<use x='120.34' xlink:href='#g2-114' y='183.949'/> +<use x='123.232' xlink:href='#g2-115' y='183.949'/> +<use x='126.478' xlink:href='#g2-111' y='183.949'/> +<use x='130.712' xlink:href='#g2-110' y='183.949'/> +<use x='135.085' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 21.624)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.688)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.999)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -72.311)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.622)'> +<use x='114.487' xlink:href='#g1-50' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<path clip-path='url(#clip1)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M93.18 141.316V141.191' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M93.18 141.316V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M91.184 141.191H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M93.18 141.316V141.441' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M93.18 141.316V141.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M95.172 141.442H91.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M151.848 141.316V141.316' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M151.848 141.316V141.316' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M210.516 141.316V141.004' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M210.516 141.316V141.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M208.523 141.004H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M210.516 141.316V141.629' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M210.516 141.316V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M212.508 141.629H208.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M269.184 141.316V141.066' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M269.184 141.316V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M267.191 141.067H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M269.184 141.316V141.566' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M269.184 141.316V141.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M271.179 141.567H267.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M327.856 141.316V140.625' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M327.856 141.316V140.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M325.859 140.625H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M327.856 141.316V142.004' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M327.856 141.316V142.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M329.847 142.004H325.863' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M386.524 141.316V141.004' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M386.524 141.316V141.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M384.531 141.004H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M386.524 141.316V141.629' fill='#e0e0f0'/> +<path clip-path='url(#clip1)' d='M386.524 141.316V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M388.515 141.629H384.531' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M96.789 203.937H100.027V138.937H96.789ZM155.457 203.937H158.695V139.312H155.457ZM214.129 203.937H217.363V141.004H214.129ZM272.797 203.937H276.035V136.179H272.797ZM331.465 203.937H334.703V136.617H331.465ZM390.133 203.937H393.371V78.691H390.133Z' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M96.789 203.937H100.027V138.937H96.789ZM155.457 203.937H158.695V139.312H155.457ZM214.129 203.937H217.363V141.004H214.129ZM272.797 203.937H276.035V136.179H272.797ZM331.465 203.937H334.703V136.617H331.465ZM390.133 203.937H393.371V78.691H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M98.41 138.937V138.683' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M98.41 138.937V138.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M96.414 138.683H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M98.41 138.937V139.187' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M98.41 138.937V139.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M100.402 139.187H96.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M157.078 139.312V139.312' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M155.086 139.312H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M157.078 139.312V139.312' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M155.086 139.312H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M215.746 141.004V140.625' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M215.746 141.004V140.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M213.754 140.625H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M215.746 141.004V141.379' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M215.746 141.004V141.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M217.739 141.379H213.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M274.414 136.179V135.992' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M274.414 136.179V135.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M272.422 135.992H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M274.414 136.179V136.367' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M274.414 136.179V136.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M276.41 136.367H272.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M333.086 136.617V136.429' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M333.086 136.617V136.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M331.09 136.43H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M333.086 136.617V136.804' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M333.086 136.617V136.804' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M335.078 136.804H331.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M391.754 78.691V78.691' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M389.762 78.691H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M391.754 78.691V78.691' fill='#c2c2e1'/> +<path clip-path='url(#clip1)' d='M389.762 78.691H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M102.02 203.937H105.258V138.433H102.02ZM160.688 203.937H163.926V136.742H160.688ZM219.359 203.937H222.594V141.004H219.359ZM278.027 203.937H281.266V137.933H278.027ZM336.695 203.937H339.934V132.234H336.695ZM395.363 203.937H398.602V78.691H395.363Z' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M102.02 203.937H105.258V138.433H102.02ZM160.688 203.937H163.926V136.742H160.688ZM219.359 203.937H222.594V141.004H219.359ZM278.027 203.937H281.266V137.933H278.027ZM336.695 203.937H339.934V132.234H336.695ZM395.363 203.937H398.602V78.691H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M103.641 138.433V138.121' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M103.641 138.433V138.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M101.644 138.122H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M103.641 138.433V138.746' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M103.641 138.433V138.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M105.633 138.746H101.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M162.309 136.742V135.867' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M162.309 136.742V135.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M160.316 135.867H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M162.309 136.742V137.621' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M162.309 136.742V137.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M164.301 137.622H160.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M220.977 141.004V140.562' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M220.977 141.004V140.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M218.984 140.563H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M220.977 141.004V141.441' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M220.977 141.004V141.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M222.969 141.442H218.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M279.645 137.933V137.496' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M279.645 137.933V137.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M277.652 137.496H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M279.645 137.933V138.371' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M279.645 137.933V138.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M281.64 138.371H277.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M338.317 132.234V131.859' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M338.317 132.234V131.859' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M336.32 131.859H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M338.317 132.234V132.609' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M338.317 132.234V132.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M340.308 132.61H336.324' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M396.984 78.691V78.691' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M394.992 78.691H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M396.984 78.691V78.691' fill='#a3a3d1'/> +<path clip-path='url(#clip1)' d='M394.992 78.691H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M107.25 203.937H110.488V130.48H107.25ZM165.918 203.937H169.156V133.238H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V137.308H283.258ZM341.926 203.937H345.164V135.742H341.926ZM400.594 203.937H403.832V78.691H400.594Z' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M107.25 203.937H110.488V130.48H107.25ZM165.918 203.937H169.156V133.238H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V137.308H283.258ZM341.926 203.937H345.164V135.742H341.926ZM400.594 203.937H403.832V78.691H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M108.871 130.48V130.168' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M108.871 130.48V130.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M106.875 130.168H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M108.871 130.48V130.793' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M108.871 130.48V130.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M110.864 130.793H106.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M167.539 133.238V133.238' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M165.547 133.238H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M167.539 133.238V133.238' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M165.547 133.238H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M226.207 141.254V140.75' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M226.207 141.254V140.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M224.215 140.75H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M226.207 141.254V141.754' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M226.207 141.254V141.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M228.2 141.754H224.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M284.875 137.308V136.933' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M284.875 137.308V136.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M282.883 136.934H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M284.875 137.308V137.683' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M284.875 137.308V137.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M286.868 137.683H282.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M343.547 135.742V135.617' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M343.547 135.742V135.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M341.551 135.618H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M343.547 135.742V135.867' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M343.547 135.742V135.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M345.539 135.867H341.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M402.215 78.691V78.691' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M400.223 78.691H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M402.215 78.691V78.691' fill='#8585c2'/> +<path clip-path='url(#clip1)' d='M400.223 78.691H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M112.481 203.937H115.719V137.871H112.481ZM171.149 203.937H174.387V133.238H171.149ZM229.82 203.937H233.055V141.254H229.82ZM288.488 203.937H291.727V132.797H288.488ZM347.156 203.937H350.395V136.554H347.156ZM405.824 203.937H409.063V103.742H405.824Z' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M112.481 203.937H115.719V137.871H112.481ZM171.149 203.937H174.387V133.238H171.149ZM229.82 203.937H233.055V141.254H229.82ZM288.488 203.937H291.727V132.797H288.488ZM347.156 203.937H350.395V136.554H347.156ZM405.824 203.937H409.063V103.742H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M114.098 137.871V137.683' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M114.098 137.871V137.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M112.105 137.683H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M114.098 137.871V138.058' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M114.098 137.871V138.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M116.094 138.059H112.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M172.77 133.238V133.238' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M170.777 133.238H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M172.77 133.238V133.238' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M170.777 133.238H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M231.438 141.254V141.129' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M231.438 141.254V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M229.445 141.128H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M231.438 141.254V141.379' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M231.438 141.254V141.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M233.43 141.379H229.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M290.106 132.797V132.547' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M290.106 132.797V132.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M288.113 132.547H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M290.106 132.797V133.051' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M290.106 132.797V133.051' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M292.098 133.051H288.113' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M348.777 136.554V134.992' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M348.777 136.554V134.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M346.781 134.992H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M348.777 136.554V138.121' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M348.777 136.554V138.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M350.769 138.122H346.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M407.445 103.742V102.363' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M407.445 103.742V102.363' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M405.453 102.364H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M407.445 103.742V105.121' fill='#6666b3'/> +<path clip-path='url(#clip1)' d='M407.445 103.742V105.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M409.437 105.121H405.453' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M117.711 203.937H120.949V135.867H117.711ZM176.379 203.937H179.617V134.238H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V132.734H293.719ZM352.387 203.937H355.625V116.203H352.387ZM411.055 203.937H414.293V84.39H411.055Z' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M117.711 203.937H120.949V135.867H117.711ZM176.379 203.937H179.617V134.238H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V132.734H293.719ZM352.387 203.937H355.625V116.203H352.387ZM411.055 203.937H414.293V84.39H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M119.328 135.867V135.554' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M119.328 135.867V135.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M117.336 135.555H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M119.328 135.867V136.179' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M119.328 135.867V136.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M121.325 136.179H117.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M178 134.238V133.238' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M178 134.238V133.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M176.008 133.238H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M178 134.238V135.242' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M178 134.238V135.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M179.993 135.242H176.008' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M236.668 140.941V140.687' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M236.668 140.941V140.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M234.676 140.687H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M236.668 140.941V141.191' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M236.668 140.941V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M238.66 141.191H234.675' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M295.336 132.734V132.609' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M295.336 132.734V132.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M293.344 132.61H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M295.336 132.734V132.859' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M295.336 132.734V132.859' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M297.328 132.859H293.343' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M354.008 116.203V115.39' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M354.008 116.203V115.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M352.012 115.39H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M354.008 116.203V117.015' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M354.008 116.203V117.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M355.999 117.016H352.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M412.676 84.39V83.89' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M412.676 84.39V83.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M410.684 83.891H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M412.676 84.39V84.89' fill='#4747a4'/> +<path clip-path='url(#clip1)' d='M412.676 84.39V84.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M414.667 84.891H410.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M122.941 203.937H126.18V138.183H122.941ZM181.609 203.937H184.848V133.238H181.609ZM240.281 203.937H243.516V140.312H240.281ZM298.949 203.937H302.188V132.422H298.949ZM357.617 203.937H360.856V135.179H357.617ZM416.285 203.937H419.524V102.675H416.285Z' fill='#292994'/> +<path clip-path='url(#clip1)' d='M122.941 203.937H126.18V138.183H122.941ZM181.609 203.937H184.848V133.238H181.609ZM240.281 203.937H243.516V140.312H240.281ZM298.949 203.937H302.188V132.422H298.949ZM357.617 203.937H360.856V135.179H357.617ZM416.285 203.937H419.524V102.675H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M124.559 138.183V137.996' fill='#292994'/> +<path clip-path='url(#clip1)' d='M124.559 138.183V137.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M122.566 137.996H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M124.559 138.183V138.371' fill='#292994'/> +<path clip-path='url(#clip1)' d='M124.559 138.183V138.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M126.555 138.371H122.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M183.231 133.238V133.238' fill='#292994'/> +<path clip-path='url(#clip1)' d='M181.238 133.238H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M183.231 133.238V133.238' fill='#292994'/> +<path clip-path='url(#clip1)' d='M181.238 133.238H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M241.899 140.312V138.871' fill='#292994'/> +<path clip-path='url(#clip1)' d='M241.899 140.312V138.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M239.906 138.871H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M241.899 140.312V141.754' fill='#292994'/> +<path clip-path='url(#clip1)' d='M241.899 140.312V141.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M243.891 141.754H239.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M300.567 132.422V132.109' fill='#292994'/> +<path clip-path='url(#clip1)' d='M300.567 132.422V132.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M298.574 132.11H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M300.567 132.422V132.734' fill='#292994'/> +<path clip-path='url(#clip1)' d='M300.567 132.422V132.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M302.559 132.734H298.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M359.238 135.179V134.801' fill='#292994'/> +<path clip-path='url(#clip1)' d='M359.238 135.179V134.801' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M357.242 134.8H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M359.238 135.179V135.554' fill='#292994'/> +<path clip-path='url(#clip1)' d='M359.238 135.179V135.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M361.23 135.555H357.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M417.906 102.675V102.55' fill='#292994'/> +<path clip-path='url(#clip1)' d='M417.906 102.675V102.55' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M415.914 102.551H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M417.906 102.675V102.8' fill='#292994'/> +<path clip-path='url(#clip1)' d='M417.906 102.675V102.8' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M419.898 102.801H415.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M128.172 203.937H131.41V123.969H128.172ZM186.84 203.937H190.078V127.851H186.84ZM245.512 203.937H248.746V141.504H245.512ZM304.18 203.937H307.418V137.746H304.18ZM362.848 203.937H366.086V104.492H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M128.172 203.937H131.41V123.969H128.172ZM186.84 203.937H190.078V127.851H186.84ZM245.512 203.937H248.746V141.504H245.512ZM304.18 203.937H307.418V137.746H304.18ZM362.848 203.937H366.086V104.492H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M129.789 123.969V123.781' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M129.789 123.969V123.781' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M127.797 123.781H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M129.789 123.969V124.156' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M129.789 123.969V124.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M131.785 124.157H127.8' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M188.461 127.851V126.91' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M188.461 127.851V126.91' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M186.469 126.91H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M188.461 127.851V128.789' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M188.461 127.851V128.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M190.453 128.789H186.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M247.129 141.504V141.254' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M247.129 141.504V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M245.137 141.254H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M247.129 141.504V141.754' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M247.129 141.504V141.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M249.121 141.754H245.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M305.797 137.746V137.558' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M305.797 137.746V137.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M303.804 137.559H307.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M305.797 137.746V137.933' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M305.797 137.746V137.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M307.789 137.934H303.804' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M364.469 104.492V103.742' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M364.469 104.492V103.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M362.473 103.742H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M364.469 104.492V105.246' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M364.469 104.492V105.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M366.46 105.246H362.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M423.137 78.691V78.691' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip1)' d='M423.137 78.691V78.691' fill='#0a0a85'/> +<path clip-path='url(#clip1)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -89.137 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -30.468 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 28.201 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 86.87 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 145.539 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 204.208 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -83.906 247.398)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -25.237 247.774)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 33.432 249.464)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 92.101 244.642)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 150.77 245.081)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 209.439 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-50' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-56' y='183.949'/> +<use x='126.877' xlink:href='#g1-52' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -78.676 246.897)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -20.007 245.206)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 38.662 249.464)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 97.331 246.396)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 156 240.697)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 214.669 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-51' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-49' y='183.949'/> +<use x='126.877' xlink:href='#g1-52' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -73.445 238.944)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -14.776 241.699)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 43.893 249.715)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 102.562 245.77)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 161.231 244.204)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 219.9 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-50' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-48' y='183.949'/> +<use x='126.877' xlink:href='#g1-55' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -68.215 246.333)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -9.546 241.699)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 49.123 249.715)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 107.792 241.261)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 166.461 245.018)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 225.13 212.204)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-54' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -62.984 244.329)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -4.315 242.701)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 54.354 249.402)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 113.023 241.198)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 171.692 224.666)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 230.361 192.853)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -57.754 246.646)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 0.915 241.699)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 59.584 248.776)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 118.253 240.885)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 176.922 243.64)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 235.591 211.139)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-54' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -52.524 232.431)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 6.145 236.314)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 64.814 249.965)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 123.483 246.208)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 182.152 212.955)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 240.821 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-50' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-49' y='183.949'/> +<use x='126.877' xlink:href='#g1-49' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -124.589 311.062)'> +<use x='114.487' xlink:href='#g0-82' y='183.949'/> +<use x='120.457' xlink:href='#g0-101' y='183.949'/> +<use x='124.553' xlink:href='#g0-108' y='183.949'/> +<use x='126.753' xlink:href='#g0-97' y='183.949'/> +<use x='131.181' xlink:href='#g0-116' y='183.949'/> +<use x='134.509' xlink:href='#g0-105' y='183.949'/> +<use x='136.709' xlink:href='#g0-118' y='183.949'/> +<use x='140.957' xlink:href='#g0-101' y='183.949'/> +<use x='148.124' xlink:href='#g0-116' y='183.949'/> +<use x='151.452' xlink:href='#g0-105' y='183.949'/> +<use x='153.652' xlink:href='#g0-109' y='183.949'/> +<use x='160.972' xlink:href='#g0-101' y='183.949'/> +<use x='168.139' xlink:href='#g2-40' y='183.949'/> +<use x='171.432' xlink:href='#g2-108' y='183.949'/> +<use x='173.453' xlink:href='#g2-111' y='183.949'/> +<use x='177.452' xlink:href='#g2-119' y='183.949'/> +<use x='183' xlink:href='#g2-101' y='183.949'/> +<use x='186.764' xlink:href='#g2-114' y='183.949'/> +<use x='192.479' xlink:href='#g2-105' y='183.949'/> +<use x='194.499' xlink:href='#g2-115' y='183.949'/> +<use x='200.568' xlink:href='#g2-98' y='183.949'/> +<use x='205.176' xlink:href='#g2-101' y='183.949'/> +<use x='208.94' xlink:href='#g2-116' y='183.949'/> +<use x='211.998' xlink:href='#g2-116' y='183.949'/> +<use x='215.056' xlink:href='#g2-101' y='183.949'/> +<use x='218.819' xlink:href='#g2-114' y='183.949'/> +<use x='221.711' xlink:href='#g2-41' y='183.949'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg new file mode 100644 index 0000000..b8a2f20 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg @@ -0,0 +1,868 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='165.084pt' version='1.1' viewBox='52.938 54.996 381.624 165.084' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip5'> +<path d='M82.148 203.937H434.164V78.691H82.148Z'/> +</clipPath> +<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/> +<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/> +<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/> +<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/> +<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/> +<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/> +<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/> +<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/> +<use id='g3-102' transform='scale(1.143)' xlink:href='#g0-102'/> +<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/> +<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/> +<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/> +<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/> +<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/> +<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/> +<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/> +<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/> +<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/> +<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/> +<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/> +<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/> +<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/> +<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/> +<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/> +<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/> +<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/> +<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/> +<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/> +<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/> +<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/> +<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/> +<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/> +<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/> +<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/> +<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/> +<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/> +<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/> +<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/> +<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/> +<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/> +<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/> +<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/> +<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/> +<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/> +<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/> +<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/> +<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/> +<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/> +<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/> +<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/> +<path d='M1.325 -2.657H2.12V-3.096H1.304V-3.898C1.304 -4.38 1.743 -4.449 1.974 -4.449C2.12 -4.449 2.308 -4.428 2.566 -4.331V-4.84C2.385 -4.882 2.169 -4.91 1.981 -4.91C1.262 -4.91 0.739 -4.394 0.739 -3.703V-3.096H0.202V-2.657H0.739V0H1.325V-2.657Z' id='g0-102'/> +<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/> +<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/> +<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/> +<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/> +<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/> +<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/> +<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/> +<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/> +<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/> +<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/> +</defs> +<g id='page5'> +<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 34.954)'> +<use x='114.487' xlink:href='#g3-99' y='183.381'/> +<use x='118.25' xlink:href='#g3-102' y='183.381'/> +<use x='120.838' xlink:href='#g3-114' y='183.381'/> +<use x='123.73' xlink:href='#g3-97' y='183.381'/> +<use x='127.798' xlink:href='#g3-99' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 45.565 34.954)'> +<use x='114.487' xlink:href='#g3-108' y='183.381'/> +<use x='116.507' xlink:href='#g3-101' y='183.381'/> +<use x='120.271' xlink:href='#g3-97' y='183.381'/> +<use x='124.339' xlink:href='#g3-110' y='183.381'/> +<use x='128.711' xlink:href='#g3-78' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 106.188 34.954)'> +<use x='114.487' xlink:href='#g3-114' y='183.381'/> +<use x='117.379' xlink:href='#g3-101' y='183.381'/> +<use x='121.142' xlink:href='#g3-100' y='183.381'/> +<use x='125.515' xlink:href='#g3-105' y='183.381'/> +<use x='127.535' xlink:href='#g3-115' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 159.716 34.954)'> +<use x='114.487' xlink:href='#g3-108' y='183.381'/> +<use x='116.507' xlink:href='#g3-97' y='183.381'/> +<use x='120.34' xlink:href='#g3-114' y='183.381'/> +<use x='123.232' xlink:href='#g3-115' y='183.381'/> +<use x='126.478' xlink:href='#g3-111' y='183.381'/> +<use x='130.712' xlink:href='#g3-110' y='183.381'/> +<use x='135.085' xlink:href='#g3-78' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 215.596 34.954)'> +<use x='114.487' xlink:href='#g3-109' y='183.381'/> +<use x='121.211' xlink:href='#g3-115' y='183.381'/> +<use x='124.458' xlink:href='#g3-116' y='183.381'/> +<use x='127.516' xlink:href='#g3-114' y='183.381'/> +<use x='130.408' xlink:href='#g3-101' y='183.381'/> +<use x='134.171' xlink:href='#g3-115' y='183.381'/> +<use x='137.418' xlink:href='#g3-115' y='183.381'/> +<use x='140.664' xlink:href='#g3-78' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 277.158 34.954)'> +<use x='114.487' xlink:href='#g3-114' y='183.381'/> +<use x='117.379' xlink:href='#g3-112' y='183.381'/> +<use x='121.751' xlink:href='#g3-116' y='183.381'/> +<use x='124.809' xlink:href='#g3-101' y='183.381'/> +<use x='128.573' xlink:href='#g3-115' y='183.381'/> +<use x='131.819' xlink:href='#g3-116' y='183.381'/> +<use x='134.877' xlink:href='#g3-78' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 22.192)'> +<use x='114.487' xlink:href='#g2-48' y='183.381'/> +<use x='117.133' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.12)'> +<use x='114.487' xlink:href='#g2-48' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-53' y='183.381'/> +<use x='121.25' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.431)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.743)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-53' y='183.381'/> +<use x='121.25' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.054)'> +<use x='114.487' xlink:href='#g2-50' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-120' y='183.381'/> +</g> +<path clip-path='url(#clip5)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M88.945 203.937H92.18V141.316H88.945ZM147.613 203.937H150.852V141.316H147.613ZM206.281 203.937H209.52V141.316H206.281ZM264.949 203.937H268.188V141.316H264.949ZM323.621 203.937H326.859V141.316H323.621ZM382.289 203.937H385.527V141.316H382.289Z' fill='#993333'/> +<path clip-path='url(#clip5)' d='M88.945 203.937H92.18V141.316H88.945ZM147.613 203.937H150.852V141.316H147.613ZM206.281 203.937H209.52V141.316H206.281ZM264.949 203.937H268.188V141.316H264.949ZM323.621 203.937H326.859V141.316H323.621ZM382.289 203.937H385.527V141.316H382.289Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M90.563 141.316V141.129' fill='#993333'/> +<path clip-path='url(#clip5)' d='M90.563 141.316V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M88.57 141.129H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M90.563 141.316V141.504' fill='#993333'/> +<path clip-path='url(#clip5)' d='M90.563 141.316V141.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M92.555 141.504H88.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M149.231 141.316V140.937' fill='#993333'/> +<path clip-path='url(#clip5)' d='M149.231 141.316V140.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M147.238 140.937H151.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M149.231 141.316V141.691' fill='#993333'/> +<path clip-path='url(#clip5)' d='M149.231 141.316V141.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M151.223 141.692H147.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M207.902 141.316V139.562' fill='#993333'/> +<path clip-path='url(#clip5)' d='M207.902 141.316V139.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M205.906 139.563H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M207.902 141.316V143.07' fill='#993333'/> +<path clip-path='url(#clip5)' d='M207.902 141.316V143.07' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M209.895 143.071H205.91' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M266.57 141.316V140.25' fill='#993333'/> +<path clip-path='url(#clip5)' d='M266.57 141.316V140.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M264.578 140.25H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M266.57 141.316V142.379' fill='#993333'/> +<path clip-path='url(#clip5)' d='M266.57 141.316V142.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M268.562 142.379H264.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M325.238 141.316V139.312' fill='#993333'/> +<path clip-path='url(#clip5)' d='M325.238 141.316V139.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M323.246 139.312H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M325.238 141.316V143.32' fill='#993333'/> +<path clip-path='url(#clip5)' d='M325.238 141.316V143.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M327.231 143.32H323.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M383.906 141.316V139.875' fill='#993333'/> +<path clip-path='url(#clip5)' d='M383.906 141.316V139.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M381.914 139.875H385.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M383.906 141.316V142.754' fill='#993333'/> +<path clip-path='url(#clip5)' d='M383.906 141.316V142.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M385.902 142.753H381.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M94.176 203.937H97.41V140.875H94.176ZM152.844 203.937H156.082V135.617H152.844ZM211.512 203.937H214.75V136.805H211.512ZM270.18 203.937H273.418V78.691H270.18ZM328.852 203.937H332.09V139.625H328.852ZM387.52 203.937H390.758V105.746H387.52Z' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M94.176 203.937H97.41V140.875H94.176ZM152.844 203.937H156.082V135.617H152.844ZM211.512 203.937H214.75V136.805H211.512ZM270.18 203.937H273.418V78.691H270.18ZM328.852 203.937H332.09V139.625H328.852ZM387.52 203.937H390.758V105.746H387.52Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M95.793 140.875V140.625' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M95.793 140.875V140.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M93.801 140.625H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M95.793 140.875V141.129' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M95.793 140.875V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M97.785 141.129H93.801' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M154.461 135.617V135.242' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M154.461 135.617V135.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M152.469 135.242H156.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M154.461 135.617V135.992' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M154.461 135.617V135.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M156.453 135.992H152.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M213.133 136.805V135.68' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M213.133 136.805V135.68' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M211.137 135.68H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M213.133 136.805V137.934' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M213.133 136.805V137.934' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M215.125 137.934H211.14' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M271.801 78.691V78.691' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M269.809 78.691H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M271.801 78.691V78.691' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M269.809 78.691H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M330.469 139.625V139.312' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M330.469 139.625V139.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M328.477 139.312H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M330.469 139.625V139.937' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M330.469 139.625V139.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M332.461 139.937H328.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M389.137 105.746V99.609' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M389.137 105.746V99.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M387.145 99.609H391.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M389.137 105.746V111.883' fill='#8080bf'/> +<path clip-path='url(#clip5)' d='M389.137 105.746V111.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M391.132 111.883H387.144' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M99.406 203.937H102.641V139.437H99.406ZM158.074 203.937H161.313V140.437H158.074ZM216.742 203.937H219.981V132.922H216.742ZM275.41 203.937H278.649V78.691H275.41ZM334.082 203.937H337.32V106.996H334.082ZM392.75 203.937H395.988V78.691H392.75Z' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M99.406 203.937H102.641V139.437H99.406ZM158.074 203.937H161.313V140.437H158.074ZM216.742 203.937H219.981V132.922H216.742ZM275.41 203.937H278.649V78.691H275.41ZM334.082 203.937H337.32V106.996H334.082ZM392.75 203.937H395.988V78.691H392.75Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M101.024 139.437V139.25' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M101.024 139.437V139.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M99.031 139.25H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M101.024 139.437V139.625' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M101.024 139.437V139.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M103.016 139.625H99.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M159.691 140.437V140.062' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M159.691 140.437V140.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M157.699 140.063H161.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M159.691 140.437V140.812' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M159.691 140.437V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M161.684 140.812H157.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M218.363 132.922V131.547' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M218.363 132.922V131.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M216.367 131.547H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M218.363 132.922V134.301' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M218.363 132.922V134.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M220.356 134.3H216.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M277.031 78.691V78.691' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M275.039 78.691H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M277.031 78.691V78.691' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M275.039 78.691H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M335.699 106.996V105.621' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M335.699 106.996V105.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M333.707 105.621H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M335.699 106.996V108.375' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M335.699 106.996V108.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M337.692 108.375H333.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M394.367 78.691V78.691' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M392.375 78.691H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M394.367 78.691V78.691' fill='#ffb733'/> +<path clip-path='url(#clip5)' d='M392.375 78.691H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M104.637 203.937H107.871V124.344H104.637ZM163.305 203.937H166.543V135.742H163.305ZM221.973 203.937H225.211V105.996H221.973ZM280.641 203.937H283.879V98.168H280.641ZM339.313 203.937H342.551V122.715H339.313ZM397.981 203.937H401.219V120.336H397.981Z' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M104.637 203.937H107.871V124.344H104.637ZM163.305 203.937H166.543V135.742H163.305ZM221.973 203.937H225.211V105.996H221.973ZM280.641 203.937H283.879V98.168H280.641ZM339.313 203.937H342.551V122.715H339.313ZM397.981 203.937H401.219V120.336H397.981Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M106.254 124.344V124.031' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M106.254 124.344V124.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M104.261 124.031H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M106.254 124.344V124.656' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M106.254 124.344V124.656' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M108.246 124.656H104.261' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M164.922 135.742V135.555' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M164.922 135.742V135.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M162.929 135.555H166.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M164.922 135.742V135.93' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M164.922 135.742V135.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M166.914 135.93H162.929' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M223.594 105.996V104.805' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M223.594 105.996V104.805' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M221.597 104.805H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M223.594 105.996V107.187' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M223.594 105.996V107.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M225.586 107.188H221.601' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M282.262 98.168V96.289' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M282.262 98.168V96.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M280.269 96.289H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M282.262 98.168V100.047' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M282.262 98.168V100.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M284.254 100.047H280.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M340.93 122.715V121.527' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M340.93 122.715V121.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M338.937 121.527H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M340.93 122.715V123.906' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M340.93 122.715V123.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M342.922 123.906H338.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M399.598 120.336V114.137' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M399.598 120.336V114.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M397.605 114.137H401.589' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M399.598 120.336V126.535' fill='#bf80bf'/> +<path clip-path='url(#clip5)' d='M399.598 120.336V126.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M401.593 126.535H397.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M109.867 203.937H113.102V140.687H109.867ZM168.535 203.937H171.774V141.316H168.535ZM227.203 203.937H230.442V140.625H227.203ZM285.871 203.937H289.109V136.555H285.871ZM344.543 203.937H347.781V115.453H344.543ZM403.211 203.937H406.449V135.242H403.211Z' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M109.867 203.937H113.102V140.687H109.867ZM168.535 203.937H171.774V141.316H168.535ZM227.203 203.937H230.442V140.625H227.203ZM285.871 203.937H289.109V136.555H285.871ZM344.543 203.937H347.781V115.453H344.543ZM403.211 203.937H406.449V135.242H403.211Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M111.484 140.687V140.562' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M111.484 140.687V140.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M109.492 140.563H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M111.484 140.687V140.812' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M111.484 140.687V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M113.477 140.812H109.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M170.152 141.316V140.937' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M170.152 141.316V140.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M168.16 140.937H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M170.152 141.316V141.691' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M170.152 141.316V141.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M172.145 141.692H168.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M228.824 140.625V139.25' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M228.824 140.625V139.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M226.828 139.25H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M228.824 140.625V142.004' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M228.824 140.625V142.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M230.817 142.004H226.832' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M287.492 136.555V134.801' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M287.492 136.555V134.801' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M285.5 134.8H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M287.492 136.555V138.309' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M287.492 136.555V138.309' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M289.485 138.308H285.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M346.16 115.453V114.074' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M346.16 115.453V114.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M344.168 114.074H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M346.16 115.453V116.828' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M346.16 115.453V116.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M348.153 116.829H344.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M404.828 135.242V128.539' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M404.828 135.242V128.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M402.836 128.539H406.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M404.828 135.242V141.941' fill='#dfbf9f'/> +<path clip-path='url(#clip5)' d='M404.828 135.242V141.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M406.824 141.941H402.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M115.098 203.937H118.332V136.055H115.098ZM173.766 203.937H177.004V128.539H173.766ZM232.434 203.937H235.672V116.016H232.434ZM291.102 203.937H294.34V78.691H291.102ZM349.774 203.937H353.012V78.691H349.774ZM408.442 203.937H411.68V78.691H408.442Z' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M115.098 203.937H118.332V136.055H115.098ZM173.766 203.937H177.004V128.539H173.766ZM232.434 203.937H235.672V116.016H232.434ZM291.102 203.937H294.34V78.691H291.102ZM349.774 203.937H353.012V78.691H349.774ZM408.442 203.937H411.68V78.691H408.442Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M116.715 136.055V135.93' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M116.715 136.055V135.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M114.722 135.93H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M116.715 136.055V136.18' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M116.715 136.055V136.18' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M118.707 136.18H114.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M175.383 128.539V126.723' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M175.383 128.539V126.723' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M173.39 126.723H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M175.383 128.539V130.355' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M175.383 128.539V130.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M177.375 130.355H173.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M234.055 116.016V114.449' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M234.055 116.016V114.449' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M232.058 114.449H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M234.055 116.016V117.582' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M234.055 116.016V117.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M236.047 117.582H232.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M292.723 78.691V78.691' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M290.73 78.691H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M292.723 78.691V78.691' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M290.73 78.691H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M351.391 78.691V78.691' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M349.398 78.691H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M351.391 78.691V78.691' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M349.398 78.691H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M410.059 78.691V78.691' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M408.066 78.691H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M410.059 78.691V78.691' fill='#80bf80'/> +<path clip-path='url(#clip5)' d='M408.066 78.691H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M120.328 203.937H123.563V137.621H120.328ZM178.996 203.937H182.234V197.676H178.996ZM237.664 203.937H240.902V136.43H237.664ZM296.332 203.937H299.57V116.953H296.332ZM355.004 203.937H358.238V197.676H355.004ZM413.672 203.937H416.91V78.691H413.672Z' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M120.328 203.937H123.563V137.621H120.328ZM178.996 203.937H182.234V197.676H178.996ZM237.664 203.937H240.902V136.43H237.664ZM296.332 203.937H299.57V116.953H296.332ZM355.004 203.937H358.238V197.676H355.004ZM413.672 203.937H416.91V78.691H413.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M121.945 137.621V137.371' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M121.945 137.621V137.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M119.953 137.371H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M121.945 137.621V137.871' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M121.945 137.621V137.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M123.938 137.871H119.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M180.613 197.676V197.676' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M178.621 197.676H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M180.613 197.676V197.676' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M178.621 197.676H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M239.285 136.43V134.988' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M239.285 136.43V134.988' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M237.289 134.988H241.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M239.285 136.43V137.871' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M239.285 136.43V137.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M241.278 137.871H237.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M297.953 116.953V115.391' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M297.953 116.953V115.391' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M295.961 115.39H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M297.953 116.953V118.519' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M297.953 116.953V118.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M299.946 118.519H295.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M356.621 197.676V197.676' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M354.629 197.676H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M356.621 197.676V197.676' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M354.629 197.676H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M415.289 78.691V78.691' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M413.297 78.691H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M415.289 78.691V78.691' fill='#bfbf80'/> +<path clip-path='url(#clip5)' d='M413.297 78.691H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M125.559 203.937H128.793V138.121H125.559ZM184.227 203.937H187.465V132.047H184.227ZM242.895 203.937H246.133V134.426H242.895ZM301.563 203.937H304.801V78.691H301.563ZM360.234 203.937H363.469V78.691H360.234ZM418.902 203.937H422.141V109.254H418.902Z' fill='#339999'/> +<path clip-path='url(#clip5)' d='M125.559 203.937H128.793V138.121H125.559ZM184.227 203.937H187.465V132.047H184.227ZM242.895 203.937H246.133V134.426H242.895ZM301.563 203.937H304.801V78.691H301.563ZM360.234 203.937H363.469V78.691H360.234ZM418.902 203.937H422.141V109.254H418.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M127.176 138.121V137.934' fill='#339999'/> +<path clip-path='url(#clip5)' d='M127.176 138.121V137.934' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M125.183 137.934H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M127.176 138.121V138.309' fill='#339999'/> +<path clip-path='url(#clip5)' d='M127.176 138.121V138.309' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M129.168 138.308H125.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M185.844 132.047V131.672' fill='#339999'/> +<path clip-path='url(#clip5)' d='M185.844 132.047V131.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M183.851 131.672H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M185.844 132.047V132.422' fill='#339999'/> +<path clip-path='url(#clip5)' d='M185.844 132.047V132.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M187.836 132.422H183.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M244.516 134.426V133.488' fill='#339999'/> +<path clip-path='url(#clip5)' d='M244.516 134.426V133.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M242.519 133.488H246.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M244.516 134.426V135.367' fill='#339999'/> +<path clip-path='url(#clip5)' d='M244.516 134.426V135.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M246.508 135.367H242.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M303.184 78.691V78.691' fill='#339999'/> +<path clip-path='url(#clip5)' d='M301.191 78.691H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M303.184 78.691V78.691' fill='#339999'/> +<path clip-path='url(#clip5)' d='M301.191 78.691H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M361.852 78.691V78.691' fill='#339999'/> +<path clip-path='url(#clip5)' d='M359.859 78.691H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M361.852 78.691V78.691' fill='#339999'/> +<path clip-path='url(#clip5)' d='M359.859 78.691H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M420.52 109.254V107.25' fill='#339999'/> +<path clip-path='url(#clip5)' d='M420.52 109.254V107.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M418.527 107.25H422.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M420.52 109.254V111.258' fill='#339999'/> +<path clip-path='url(#clip5)' d='M420.52 109.254V111.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M422.512 111.258H418.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M130.789 203.937H134.024V139.187H130.789ZM189.457 203.937H192.695V139.312H189.457ZM248.125 203.937H251.363V140.062H248.125ZM306.793 203.937H310.031V126.035H306.793ZM365.465 203.937H368.699V103.176H365.465ZM424.133 203.937H427.371V113.762H424.133Z' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M130.789 203.937H134.024V139.187H130.789ZM189.457 203.937H192.695V139.312H189.457ZM248.125 203.937H251.363V140.062H248.125ZM306.793 203.937H310.031V126.035H306.793ZM365.465 203.937H368.699V103.176H365.465ZM424.133 203.937H427.371V113.762H424.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M132.406 139.187V138.934' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M132.406 139.187V138.934' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M130.414 138.933H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M132.406 139.187V139.437' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M132.406 139.187V139.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M134.399 139.437H130.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M191.074 139.312V139.062' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M191.074 139.312V139.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M189.082 139.063H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M191.074 139.312V139.562' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M191.074 139.312V139.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M193.067 139.563H189.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M249.746 140.062V138.871' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M249.746 140.062V138.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M247.75 138.871H251.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M249.746 140.062V141.254' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M249.746 140.062V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M251.739 141.254H247.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M308.414 126.035V125.031' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M308.414 126.035V125.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M306.422 125.031H310.407' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M308.414 126.035V127.035' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M308.414 126.035V127.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M310.407 127.035H306.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M367.082 103.176V101.613' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M367.082 103.176V101.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M365.09 101.613H369.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M367.082 103.176V104.742' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M367.082 103.176V104.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M369.075 104.742H365.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M425.75 113.762V105.184' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M425.75 113.762V105.184' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M423.758 105.184H427.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M425.75 113.762V122.34' fill='#bf8080'/> +<path clip-path='url(#clip5)' d='M425.75 113.762V122.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M427.743 122.34H423.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -91.184 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -32.515 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 26.154 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 84.823 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 143.492 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 202.161 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -85.954 249.339)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -27.284 244.079)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-57' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 31.385 245.269)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-55' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 90.054 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-52' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-57' y='183.381'/> +<use x='126.877' xlink:href='#g2-52' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 148.723 248.087)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-51' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 207.392 214.208)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-53' y='183.381'/> +<use x='121.25' xlink:href='#g2-55' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -80.723 247.899)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-51' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -22.054 248.901)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 36.615 241.386)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-49' y='183.381'/> +<use x='121.25' xlink:href='#g2-51' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 95.284 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-53' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-50' y='183.381'/> +<use x='126.877' xlink:href='#g2-50' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 153.953 215.46)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-53' y='183.381'/> +<use x='121.25' xlink:href='#g2-53' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 212.622 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-51' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-55' y='183.381'/> +<use x='126.877' xlink:href='#g2-56' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -75.493 232.807)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-50' y='183.381'/> +<use x='121.25' xlink:href='#g2-55' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -16.824 244.204)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-57' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 41.845 214.458)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-53' y='183.381'/> +<use x='121.25' xlink:href='#g2-54' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 100.514 206.63)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-54' y='183.381'/> +<use x='121.25' xlink:href='#g2-57' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 159.183 231.178)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-51' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 217.852 228.799)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-51' y='183.381'/> +<use x='121.25' xlink:href='#g2-52' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -70.262 249.151)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -11.593 249.777)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 47.076 249.089)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 105.745 245.018)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-56' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 164.414 223.914)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-52' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 223.083 243.703)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-49' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -65.032 244.517)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-56' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -6.363 237.002)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-50' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 52.306 224.478)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-52' y='183.381'/> +<use x='121.25' xlink:href='#g2-48' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 110.975 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-51' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-48' y='183.381'/> +<use x='126.877' xlink:href='#g2-50' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 169.644 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-50' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-51' y='183.381'/> +<use x='126.877' xlink:href='#g2-49' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 228.313 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-52' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-54' y='183.381'/> +<use x='126.877' xlink:href='#g2-51' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -59.801 246.083)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-54' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -1.66 306.138)'> +<use x='114.487' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 57.537 244.893)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-56' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 116.206 225.417)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-51' y='183.381'/> +<use x='121.25' xlink:href='#g2-57' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 174.347 306.138)'> +<use x='114.487' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 233.544 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-51' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-56' y='183.381'/> +<use x='126.877' xlink:href='#g2-53' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -54.571 246.584)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-53' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 4.098 240.509)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-49' y='183.381'/> +<use x='121.25' xlink:href='#g2-53' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 62.767 242.889)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-49' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 121.436 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-51' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-50' y='183.381'/> +<use x='126.877' xlink:href='#g2-50' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 180.105 187.154)'> +<use x='109.598' xlink:href='#g4-1' y='183.381'/> +<use x='113.103' xlink:href='#g4-1' y='183.381'/> +<use x='116.608' xlink:href='#g4-1' y='183.381'/> +<use x='120.114' xlink:href='#g2-50' y='183.381'/> +<use x='122.76' xlink:href='#g2-46' y='183.381'/> +<use x='124.23' xlink:href='#g2-56' y='183.381'/> +<use x='126.877' xlink:href='#g2-56' y='183.381'/> +<use x='129.523' xlink:href='#g2-120' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 238.774 217.714)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-53' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -49.34 247.648)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-51' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 9.329 247.773)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-51' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 67.998 248.525)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-48' y='183.381'/> +<use x='121.25' xlink:href='#g2-50' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 126.667 234.497)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-50' y='183.381'/> +<use x='121.25' xlink:href='#g2-52' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 185.336 211.64)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-54' y='183.381'/> +<use x='121.25' xlink:href='#g2-49' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 244.005 222.223)'> +<use x='114.487' xlink:href='#g2-49' y='183.381'/> +<use x='117.133' xlink:href='#g2-46' y='183.381'/> +<use x='118.603' xlink:href='#g2-52' y='183.381'/> +<use x='121.25' xlink:href='#g2-52' y='183.381'/> +</g> +<g transform='matrix(0 -1 1 0 -124.021 311.062)'> +<use x='114.487' xlink:href='#g1-82' y='183.381'/> +<use x='120.457' xlink:href='#g1-101' y='183.381'/> +<use x='124.553' xlink:href='#g1-108' y='183.381'/> +<use x='126.753' xlink:href='#g1-97' y='183.381'/> +<use x='131.181' xlink:href='#g1-116' y='183.381'/> +<use x='134.509' xlink:href='#g1-105' y='183.381'/> +<use x='136.709' xlink:href='#g1-118' y='183.381'/> +<use x='140.957' xlink:href='#g1-101' y='183.381'/> +<use x='148.124' xlink:href='#g1-116' y='183.381'/> +<use x='151.452' xlink:href='#g1-105' y='183.381'/> +<use x='153.652' xlink:href='#g1-109' y='183.381'/> +<use x='160.972' xlink:href='#g1-101' y='183.381'/> +<use x='168.139' xlink:href='#g3-40' y='183.381'/> +<use x='171.432' xlink:href='#g3-108' y='183.381'/> +<use x='173.453' xlink:href='#g3-111' y='183.381'/> +<use x='177.452' xlink:href='#g3-119' y='183.381'/> +<use x='183' xlink:href='#g3-101' y='183.381'/> +<use x='186.764' xlink:href='#g3-114' y='183.381'/> +<use x='192.479' xlink:href='#g3-105' y='183.381'/> +<use x='194.499' xlink:href='#g3-115' y='183.381'/> +<use x='200.568' xlink:href='#g3-98' y='183.381'/> +<use x='205.176' xlink:href='#g3-101' y='183.381'/> +<use x='208.94' xlink:href='#g3-116' y='183.381'/> +<use x='211.998' xlink:href='#g3-116' y='183.381'/> +<use x='215.056' xlink:href='#g3-101' y='183.381'/> +<use x='218.819' xlink:href='#g3-114' y='183.381'/> +<use x='221.711' xlink:href='#g3-41' y='183.381'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg new file mode 100644 index 0000000..4a7e21e --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg @@ -0,0 +1,1157 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='258.383pt' version='1.1' viewBox='106.736 54.996 381.623 258.383' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip6'> +<path d='M135.949 251.93H487.961V84.164H135.949Z'/> +</clipPath> +<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/> +<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/> +<use id='g3-45' transform='scale(1.143)' xlink:href='#g0-45'/> +<use id='g3-49' transform='scale(1.143)' xlink:href='#g0-49'/> +<use id='g3-54' transform='scale(1.143)' xlink:href='#g0-54'/> +<use id='g3-56' transform='scale(1.143)' xlink:href='#g0-56'/> +<use id='g3-58' transform='scale(1.143)' xlink:href='#g0-58'/> +<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/> +<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/> +<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/> +<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/> +<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/> +<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/> +<use id='g3-103' transform='scale(1.143)' xlink:href='#g0-103'/> +<use id='g3-104' transform='scale(1.143)' xlink:href='#g0-104'/> +<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/> +<use id='g3-106' transform='scale(1.143)' xlink:href='#g0-106'/> +<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/> +<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/> +<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/> +<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/> +<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/> +<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/> +<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/> +<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/> +<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/> +<use id='g3-120' transform='scale(1.143)' xlink:href='#g0-120'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/> +<use id='g2-44' transform='scale(0.714)' xlink:href='#g0-44'/> +<use id='g2-45' transform='scale(0.714)' xlink:href='#g0-45'/> +<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/> +<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/> +<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/> +<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/> +<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/> +<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/> +<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/> +<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/> +<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/> +<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/> +<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/> +<use id='g2-64' transform='scale(0.714)' xlink:href='#g0-64'/> +<use id='g2-65' transform='scale(0.714)' xlink:href='#g0-65'/> +<use id='g2-67' transform='scale(0.714)' xlink:href='#g0-67'/> +<use id='g2-68' transform='scale(0.714)' xlink:href='#g0-68'/> +<use id='g2-71' transform='scale(0.714)' xlink:href='#g0-71'/> +<use id='g2-77' transform='scale(0.714)' xlink:href='#g0-77'/> +<use id='g2-85' transform='scale(0.714)' xlink:href='#g0-85'/> +<use id='g2-97' transform='scale(0.714)' xlink:href='#g0-97'/> +<use id='g2-98' transform='scale(0.714)' xlink:href='#g0-98'/> +<use id='g2-99' transform='scale(0.714)' xlink:href='#g0-99'/> +<use id='g2-100' transform='scale(0.714)' xlink:href='#g0-100'/> +<use id='g2-101' transform='scale(0.714)' xlink:href='#g0-101'/> +<use id='g2-103' transform='scale(0.714)' xlink:href='#g0-103'/> +<use id='g2-104' transform='scale(0.714)' xlink:href='#g0-104'/> +<use id='g2-108' transform='scale(0.714)' xlink:href='#g0-108'/> +<use id='g2-109' transform='scale(0.714)' xlink:href='#g0-109'/> +<use id='g2-110' transform='scale(0.714)' xlink:href='#g0-110'/> +<use id='g2-111' transform='scale(0.714)' xlink:href='#g0-111'/> +<use id='g2-112' transform='scale(0.714)' xlink:href='#g0-112'/> +<use id='g2-114' transform='scale(0.714)' xlink:href='#g0-114'/> +<use id='g2-115' transform='scale(0.714)' xlink:href='#g0-115'/> +<use id='g2-116' transform='scale(0.714)' xlink:href='#g0-116'/> +<use id='g2-117' transform='scale(0.714)' xlink:href='#g0-117'/> +<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/> +<use id='g2-122' transform='scale(0.714)' xlink:href='#g0-122'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/> +<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/> +<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/> +<path d='M1.339 -0.007V-0.628H0.711V0H0.907L0.704 0.893H1.018L1.339 -0.007Z' id='g0-44'/> +<path d='M2.05 -1.332V-1.771H0.084V-1.332H2.05Z' id='g0-45'/> +<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/> +<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/> +<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/> +<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/> +<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/> +<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/> +<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/> +<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/> +<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/> +<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/> +<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/> +<path d='M1.339 -3.096H0.711V-2.469H1.339V-3.096ZM0.711 -0.628V0H1.339V-0.628H0.711Z' id='g0-58'/> +<path d='M4.142 -0.614C4.038 -0.614 4.024 -0.614 3.968 -0.586C3.626 -0.467 3.271 -0.391 2.901 -0.391C1.778 -0.391 0.976 -1.339 0.976 -2.42C0.976 -3.592 1.883 -4.449 2.859 -4.449C3.055 -4.449 3.515 -4.4 3.745 -3.843C3.55 -3.954 3.333 -4.003 3.152 -4.003C2.406 -4.003 1.778 -3.306 1.778 -2.42C1.778 -1.513 2.427 -0.837 3.145 -0.837C3.689 -0.837 4.519 -1.276 4.519 -2.518C4.519 -3.222 4.47 -4.91 2.866 -4.91C1.541 -4.91 0.411 -3.815 0.411 -2.42C0.411 -1.039 1.527 0.07 2.873 0.07C3.515 0.07 4.115 -0.195 4.519 -0.614H4.142ZM3.152 -1.297C2.72 -1.297 2.343 -1.778 2.343 -2.42C2.343 -3.082 2.734 -3.543 3.145 -3.543C3.578 -3.543 3.954 -3.062 3.954 -2.42C3.954 -1.757 3.564 -1.297 3.152 -1.297Z' id='g0-64'/> +<path d='M2.803 -4.84H2.127L0.209 0H0.781L1.325 -1.381H3.445L3.989 0H4.721L2.803 -4.84ZM2.392 -4.31L3.271 -1.792H1.499L2.392 -4.31Z' id='g0-65'/> +<path d='M4.317 -0.851C3.829 -0.551 3.605 -0.418 2.908 -0.418C1.827 -0.418 1.172 -1.43 1.172 -2.434C1.172 -3.466 1.89 -4.435 2.908 -4.435C3.368 -4.435 3.843 -4.289 4.163 -4.045L4.275 -4.679C3.787 -4.861 3.396 -4.917 2.887 -4.917C1.506 -4.917 0.474 -3.773 0.474 -2.427C0.474 -0.99 1.569 0.07 2.929 0.07C3.612 0.07 3.898 -0.07 4.359 -0.321L4.317 -0.851Z' id='g0-67'/> +<path d='M0.683 -4.84V0H2.664C3.919 0 4.931 -1.06 4.931 -2.378C4.931 -3.745 3.912 -4.84 2.664 -4.84H0.683ZM1.367 -0.411V-4.428H2.476C3.431 -4.428 4.247 -3.668 4.247 -2.385C4.247 -1.088 3.396 -0.411 2.476 -0.411H1.367Z' id='g0-68'/> +<path d='M4.442 -2.085H2.88V-1.625H3.829V-0.558C3.522 -0.481 3.222 -0.418 2.908 -0.418C1.834 -0.418 1.172 -1.43 1.172 -2.427C1.172 -3.382 1.82 -4.435 2.873 -4.435C3.515 -4.435 3.919 -4.24 4.268 -3.947L4.38 -4.582C3.898 -4.812 3.473 -4.924 2.943 -4.924C1.534 -4.924 0.474 -3.822 0.474 -2.427C0.474 -1.067 1.527 0.07 2.901 0.07C3.403 0.07 3.996 -0.042 4.442 -0.272V-2.085Z' id='g0-71'/> +<path d='M3.884 -2.42C3.801 -2.211 3.299 -0.983 3.229 -0.69H3.222C3.173 -0.893 2.852 -1.695 2.783 -1.876L1.583 -4.84H0.732V0H1.318V-4.282H1.325C1.381 -4.038 1.743 -3.117 1.778 -3.041L2.943 -0.146H3.494L4.533 -2.713C4.533 -2.72 5.014 -3.905 5.133 -4.289H5.14V0H5.726V-4.84H4.868L3.884 -2.42Z' id='g0-77'/> +<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/> +<path d='M4.4 -4.84H3.794V-1.625C3.794 -0.69 3.166 -0.265 2.566 -0.265S1.381 -0.697 1.381 -1.618V-4.84H0.676V-1.632C0.676 -0.607 1.555 0.146 2.559 0.146C3.557 0.146 4.4 -0.614 4.4 -1.632V-4.84Z' id='g0-85'/> +<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/> +<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/> +<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/> +<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/> +<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/> +<path d='M3.508 -3.166C3.354 -3.166 2.887 -3.159 2.357 -2.957L2.343 -2.95C2.092 -3.117 1.848 -3.166 1.646 -3.166C0.962 -3.166 0.453 -2.629 0.453 -2.029C0.453 -1.785 0.537 -1.534 0.697 -1.339C0.6 -1.22 0.495 -1.025 0.495 -0.76C0.495 -0.488 0.607 -0.314 0.669 -0.23C0.286 -0.007 0.209 0.314 0.209 0.481C0.209 1.011 0.941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 0.481C3.487 -0.502 2.267 -0.502 1.967 -0.502H1.318C1.206 -0.502 0.907 -0.502 0.907 -0.865C0.907 -1.004 0.955 -1.074 0.962 -1.088C1.206 -0.934 1.451 -0.886 1.639 -0.886C2.322 -0.886 2.831 -1.423 2.831 -2.022C2.831 -2.246 2.769 -2.448 2.643 -2.636C2.615 -2.678 2.615 -2.685 2.615 -2.692C2.615 -2.72 3.034 -2.72 3.068 -2.72C3.075 -2.72 3.34 -2.72 3.592 -2.692L3.508 -3.166ZM1.646 -1.318C1.269 -1.318 0.99 -1.555 0.99 -2.022C0.99 -2.566 1.339 -2.734 1.639 -2.734C2.015 -2.734 2.294 -2.497 2.294 -2.029C2.294 -1.485 1.946 -1.318 1.646 -1.318ZM1.974 0.042C2.134 0.042 2.957 0.042 2.957 0.488C2.957 0.788 2.434 0.997 1.848 0.997S0.739 0.788 0.739 0.488C0.739 0.453 0.739 0.042 1.304 0.042H1.974Z' id='g0-103'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.625 -3.166 1.304 -2.817 1.165 -2.671V-4.84H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-104'/> +<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/> +<path d='M1.381 -4.784H0.676V-4.08H1.381V-4.784ZM-0.453 1.186C-0.133 1.36 0.181 1.423 0.446 1.423C0.928 1.423 1.381 1.053 1.381 0.411V-3.096H0.795V0.46C0.795 0.586 0.795 0.697 0.649 0.816C0.488 0.934 0.293 0.934 0.23 0.934C-0.063 0.934 -0.244 0.802 -0.328 0.725L-0.453 1.186Z' id='g0-106'/> +<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/> +<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/> +<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/> +<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/> +<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/> +<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/> +<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/> +<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/> +<path d='M3.243 -3.096H2.636V-1.074C2.636 -0.516 2.162 -0.342 1.757 -0.342C1.241 -0.342 1.186 -0.481 1.186 -0.802V-3.096H0.579V-0.76C0.579 -0.139 0.851 0.07 1.339 0.07C1.625 0.07 2.239 0.014 2.657 -0.321V0H3.243V-3.096Z' id='g0-117'/> +<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/> +<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/> +<path d='M2.957 -2.803V-3.096H0.307V-2.65H1.332C1.416 -2.65 1.499 -2.657 1.583 -2.657H2.127L0.209 -0.307V0H2.978V-0.467H1.897C1.813 -0.467 1.73 -0.46 1.646 -0.46H1.039L2.957 -2.803Z' id='g0-122'/> +</defs> +<g id='page6'> +<path d='M194.617 260.785V251.93M253.285 260.785V251.93M311.953 260.785V251.93M370.625 260.785V251.93M429.293 260.785V251.93M194.617 75.308V84.164M253.285 75.308V84.164M311.953 75.308V84.164M370.625 75.308V84.164M429.293 75.308V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 256.18V251.93M223.953 256.18V251.93M282.621 256.18V251.93M341.289 256.18V251.93M399.957 256.18V251.93M458.629 256.18V251.93M165.281 79.91V84.164M223.953 79.91V84.164M282.621 79.91V84.164M341.289 79.91V84.164M399.957 79.91V84.164M458.629 79.91V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 251.93H140.199M135.949 218.375H140.199M135.949 184.824H140.199M135.949 151.269H140.199M135.949 117.719H140.199M135.949 84.164H140.199M487.961 251.93H483.711M487.961 218.375H483.711M487.961 184.824H483.711M487.961 151.269H483.711M487.961 117.719H483.711M487.961 84.164H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 251.93V84.164H487.961V251.93H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 74.992)'> +<use x='168.285' xlink:href='#g3-97' y='191.334'/> +<use x='172.353' xlink:href='#g3-108' y='191.334'/> +<use x='174.373' xlink:href='#g3-108' y='191.334'/> +<use x='176.393' xlink:href='#g3-111' y='191.334'/> +<use x='180.863' xlink:href='#g3-99' y='191.334'/> +<use x='184.627' xlink:href='#g3-45' y='191.334'/> +<use x='187.449' xlink:href='#g3-116' y='191.334'/> +<use x='190.507' xlink:href='#g3-101' y='191.334'/> +<use x='194.271' xlink:href='#g3-115' y='191.334'/> +<use x='197.517' xlink:href='#g3-116' y='191.334'/> +<use x='200.575' xlink:href='#g3-49' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 36.532 74.992)'> +<use x='168.285' xlink:href='#g3-97' y='191.334'/> +<use x='172.353' xlink:href='#g3-108' y='191.334'/> +<use x='174.373' xlink:href='#g3-108' y='191.334'/> +<use x='176.393' xlink:href='#g3-111' y='191.334'/> +<use x='180.863' xlink:href='#g3-99' y='191.334'/> +<use x='184.627' xlink:href='#g3-45' y='191.334'/> +<use x='187.449' xlink:href='#g3-116' y='191.334'/> +<use x='190.507' xlink:href='#g3-101' y='191.334'/> +<use x='194.271' xlink:href='#g3-115' y='191.334'/> +<use x='197.517' xlink:href='#g3-116' y='191.334'/> +<use x='200.575' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 94.98 74.992)'> +<use x='168.285' xlink:href='#g3-115' y='191.334'/> +<use x='171.531' xlink:href='#g3-104' y='191.334'/> +<use x='175.904' xlink:href='#g3-54' y='191.334'/> +<use x='180.138' xlink:href='#g3-98' y='191.334'/> +<use x='184.746' xlink:href='#g3-101' y='191.334'/> +<use x='188.509' xlink:href='#g3-110' y='191.334'/> +<use x='192.882' xlink:href='#g3-99' y='191.334'/> +<use x='196.646' xlink:href='#g3-104' y='191.334'/> +<use x='201.018' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 153.649 74.992)'> +<use x='168.285' xlink:href='#g3-115' y='191.334'/> +<use x='171.531' xlink:href='#g3-104' y='191.334'/> +<use x='175.904' xlink:href='#g3-56' y='191.334'/> +<use x='180.138' xlink:href='#g3-98' y='191.334'/> +<use x='184.746' xlink:href='#g3-101' y='191.334'/> +<use x='188.509' xlink:href='#g3-110' y='191.334'/> +<use x='192.882' xlink:href='#g3-99' y='191.334'/> +<use x='196.646' xlink:href='#g3-104' y='191.334'/> +<use x='201.018' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 207.225 74.992)'> +<use x='168.285' xlink:href='#g3-120' y='191.334'/> +<use x='172.187' xlink:href='#g3-109' y='191.334'/> +<use x='178.912' xlink:href='#g3-97' y='191.334'/> +<use x='182.98' xlink:href='#g3-108' y='191.334'/> +<use x='185' xlink:href='#g3-108' y='191.334'/> +<use x='187.02' xlink:href='#g3-111' y='191.334'/> +<use x='191.49' xlink:href='#g3-99' y='191.334'/> +<use x='195.254' xlink:href='#g3-45' y='191.334'/> +<use x='198.076' xlink:href='#g3-116' y='191.334'/> +<use x='201.134' xlink:href='#g3-101' y='191.334'/> +<use x='204.898' xlink:href='#g3-115' y='191.334'/> +<use x='208.144' xlink:href='#g3-116' y='191.334'/> +<use x='211.202' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 263.494 74.992)'> +<use x='168.285' xlink:href='#g3-99' y='191.334'/> +<use x='172.049' xlink:href='#g3-97' y='191.334'/> +<use x='176.117' xlink:href='#g3-99' y='191.334'/> +<use x='179.88' xlink:href='#g3-104' y='191.334'/> +<use x='184.253' xlink:href='#g3-101' y='191.334'/> +<use x='188.017' xlink:href='#g3-45' y='191.334'/> +<use x='190.839' xlink:href='#g3-115' y='191.334'/> +<use x='194.086' xlink:href='#g3-99' y='191.334'/> +<use x='197.849' xlink:href='#g3-114' y='191.334'/> +<use x='200.741' xlink:href='#g3-97' y='191.334'/> +<use x='204.81' xlink:href='#g3-116' y='191.334'/> +<use x='207.868' xlink:href='#g3-99' y='191.334'/> +<use x='211.631' xlink:href='#g3-104' y='191.334'/> +<use x='216.004' xlink:href='#g3-78' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 62.23)'> +<use x='168.285' xlink:href='#g2-48' y='191.334'/> +<use x='170.931' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.677)'> +<use x='168.285' xlink:href='#g2-48' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -4.876)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -38.43)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.983)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -105.536)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-120' y='191.334'/> +</g> +<path clip-path='url(#clip6)' d='M135.949 184.824H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='#993333'/> +<path clip-path='url(#clip6)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M144.359 184.824V184.488' fill='#993333'/> +<path clip-path='url(#clip6)' d='M144.359 184.824V184.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M142.367 184.489H146.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M144.359 184.824V185.16' fill='#993333'/> +<path clip-path='url(#clip6)' d='M144.359 184.824V185.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M146.352 185.161H142.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M203.031 184.824V184.488' fill='#993333'/> +<path clip-path='url(#clip6)' d='M203.031 184.824V184.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M201.039 184.489H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M203.031 184.824V185.16' fill='#993333'/> +<path clip-path='url(#clip6)' d='M203.031 184.824V185.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M205.023 185.161H201.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M261.699 184.824V182.742' fill='#993333'/> +<path clip-path='url(#clip6)' d='M261.699 184.824V182.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M259.707 182.742H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M261.699 184.824V186.902' fill='#993333'/> +<path clip-path='url(#clip6)' d='M261.699 184.824V186.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M263.691 186.902H259.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M320.367 184.824V183.012' fill='#993333'/> +<path clip-path='url(#clip6)' d='M320.367 184.824V183.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M318.375 183.012H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M320.367 184.824V186.637' fill='#993333'/> +<path clip-path='url(#clip6)' d='M320.367 184.824V186.637' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M322.359 186.637H318.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M379.035 184.824V184.352' fill='#993333'/> +<path clip-path='url(#clip6)' d='M379.035 184.824V184.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M377.043 184.351H381.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M379.035 184.824V185.293' fill='#993333'/> +<path clip-path='url(#clip6)' d='M379.035 184.824V185.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M381.027 185.293H377.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M437.707 184.824V183.949' fill='#993333'/> +<path clip-path='url(#clip6)' d='M437.707 184.824V183.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M435.715 183.95H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M437.707 184.824V185.695' fill='#993333'/> +<path clip-path='url(#clip6)' d='M437.707 184.824V185.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M439.699 185.695H435.711' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M147.973 251.93H151.211V184.285H147.973ZM206.641 251.93H209.879V179.926H206.641ZM265.309 251.93H268.547V98.523H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M147.973 251.93H151.211V184.285H147.973ZM206.641 251.93H209.879V179.926H206.641ZM265.309 251.93H268.547V98.523H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M149.59 184.285V183.949' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M149.59 184.285V183.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M147.598 183.95H151.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M149.59 184.285V184.621' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M149.59 184.285V184.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M151.582 184.621H147.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M208.262 179.926V179.523' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M208.262 179.926V179.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M206.27 179.524H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M208.262 179.926V180.328' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M208.262 179.926V180.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M210.253 180.328H206.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M266.93 98.523V94.902' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M266.93 98.523V94.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M264.938 94.902H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M266.93 98.523V102.148' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M266.93 98.523V102.148' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M268.921 102.148H264.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M325.598 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M325.598 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M384.266 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M384.266 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M442.938 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M442.938 84.164V84.164' fill='#8080bf'/> +<path clip-path='url(#clip6)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M153.203 251.93H156.442V178.715H153.203ZM211.871 251.93H215.11V178.047H211.871ZM270.539 251.93H273.777V85.773H270.539ZM329.211 251.93H332.449V88.996H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M153.203 251.93H156.442V178.715H153.203ZM211.871 251.93H215.11V178.047H211.871ZM270.539 251.93H273.777V85.773H270.539ZM329.211 251.93H332.449V88.996H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M154.82 178.715V178.047' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M154.82 178.715V178.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M152.828 178.047H156.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M154.82 178.715V179.387' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M154.82 178.715V179.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M156.813 179.386H152.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M213.492 178.047V177.574' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M213.492 178.047V177.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M211.5 177.575H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M213.492 178.047V178.516' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M213.492 178.047V178.516' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M215.484 178.516H211.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M272.16 85.773V83.558' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M272.16 85.773V83.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M270.168 83.559H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M272.16 85.773V87.988' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M272.16 85.773V87.988' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M274.152 87.988H270.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M330.828 88.996V86.715' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M330.828 88.996V86.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M328.836 86.715H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M330.828 88.996V91.277' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M330.828 88.996V91.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M332.82 91.277H328.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M389.496 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M389.496 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M448.168 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M448.168 84.164V84.164' fill='#ffb733'/> +<path clip-path='url(#clip6)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M158.434 251.93H161.672V155.164H158.434ZM217.102 251.93H220.34V156.305H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V84.164H334.442ZM393.109 251.93H396.348V131.609H393.109ZM451.777 251.93H455.016V183.949H451.777Z' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M158.434 251.93H161.672V155.164H158.434ZM217.102 251.93H220.34V156.305H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V84.164H334.442ZM393.109 251.93H396.348V131.609H393.109ZM451.777 251.93H455.016V183.949H451.777Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M160.051 155.164V154.758' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M160.051 155.164V154.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M158.058 154.758H162.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M160.051 155.164V155.566' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M160.051 155.164V155.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M162.043 155.567H158.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M218.723 156.305V156.102' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M218.723 156.305V156.102' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M216.73 156.102H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M218.723 156.305V156.504' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M218.723 156.305V156.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M220.714 156.504H216.726' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M277.391 84.164V84.164' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M277.391 84.164V84.164' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M336.059 84.164V84.164' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M334.066 84.164H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M336.059 84.164V84.164' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M334.066 84.164H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M394.727 131.609V131.406' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M394.727 131.609V131.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M392.734 131.407H396.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M394.727 131.609V131.808' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M394.727 131.609V131.808' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M396.718 131.808H392.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M453.399 183.949V182.809' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M453.399 183.949V182.809' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M451.406 182.809H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M453.399 183.949V185.09' fill='#bf80bf'/> +<path clip-path='url(#clip6)' d='M453.399 183.949V185.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M455.39 185.089H451.402' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M163.664 251.93H166.903V180.664H163.664ZM222.332 251.93H225.57V183.078H222.332ZM281 251.93H284.238V174.355H281ZM339.672 251.93H342.91V183.144H339.672ZM398.34 251.93H401.578V198.914H398.34ZM457.008 251.93H460.246V184.555H457.008Z' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M163.664 251.93H166.903V180.664H163.664ZM222.332 251.93H225.57V183.078H222.332ZM281 251.93H284.238V174.355H281ZM339.672 251.93H342.91V183.144H339.672ZM398.34 251.93H401.578V198.914H398.34ZM457.008 251.93H460.246V184.555H457.008Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M165.281 180.664V180.461' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M165.281 180.664V180.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M163.289 180.461H167.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M165.281 180.664V180.863' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M165.281 180.664V180.863' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M167.274 180.864H163.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M223.953 183.078V182.809' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M223.953 183.078V182.809' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M221.961 182.809H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M223.953 183.078V183.348' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M223.953 183.078V183.348' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M225.945 183.348H221.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M282.621 174.355V174.355' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M280.629 174.355H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M282.621 174.355V174.355' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M280.629 174.355H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M341.289 183.144V182.473' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M341.289 183.144V182.473' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M339.297 182.472H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M341.289 183.144V183.816' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M341.289 183.144V183.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M343.281 183.816H339.297' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M399.957 198.914V197.977' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M399.957 198.914V197.977' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M397.965 197.977H401.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M399.957 198.914V199.855' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M399.957 198.914V199.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M401.949 199.856H397.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M458.629 184.555V184.555' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M456.637 184.555H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M458.629 184.555V184.555' fill='#dfbf9f'/> +<path clip-path='url(#clip6)' d='M456.637 184.555H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M168.895 251.93H172.133V173.684H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M168.895 251.93H172.133V173.684H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M170.512 173.684V173.348' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M170.512 173.684V173.348' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M168.519 173.348H172.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M170.512 173.684V174.019' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M170.512 173.684V174.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M172.504 174.02H168.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M229.184 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M229.184 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M287.852 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M287.852 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M346.52 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M346.52 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M405.188 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M405.188 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M463.859 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M463.859 84.164V84.164' fill='#80bf80'/> +<path clip-path='url(#clip6)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M174.125 251.93H177.363V147.109H174.125ZM232.793 251.93H236.031V139.93H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V245.219H350.133ZM408.801 251.93H412.039V245.219H408.801ZM467.469 251.93H470.707V183.144H467.469Z' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M174.125 251.93H177.363V147.109H174.125ZM232.793 251.93H236.031V139.93H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V245.219H350.133ZM408.801 251.93H412.039V245.219H408.801ZM467.469 251.93H470.707V183.144H467.469Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M175.742 147.109V144.289' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M175.742 147.109V144.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M173.75 144.289H177.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M175.742 147.109V149.93' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M175.742 147.109V149.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M177.735 149.93H173.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M234.414 139.93V130.937' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M234.414 139.93V130.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M232.422 130.938H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M234.414 139.93V148.922' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M234.414 139.93V148.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M236.403 148.922H232.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M293.082 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M293.082 84.164V84.164' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M351.75 245.219V245.219' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M349.758 245.219H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M351.75 245.219V245.219' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M349.758 245.219H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M410.418 245.219V245.219' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M408.426 245.219H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M410.418 245.219V245.219' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M408.426 245.219H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M469.09 183.144V181.734' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M469.09 183.144V181.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M467.098 181.734H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M469.09 183.144V184.555' fill='#bfbf80'/> +<path clip-path='url(#clip6)' d='M469.09 183.144V184.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M471.082 184.555H467.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M179.356 251.93H182.594V169.254H179.356ZM238.024 251.93H241.262V169.387H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='#339999'/> +<path clip-path='url(#clip6)' d='M179.356 251.93H182.594V169.254H179.356ZM238.024 251.93H241.262V169.387H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M180.973 169.254V168.719' fill='#339999'/> +<path clip-path='url(#clip6)' d='M180.973 169.254V168.719' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M178.98 168.719H182.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M180.973 169.254V169.793' fill='#339999'/> +<path clip-path='url(#clip6)' d='M180.973 169.254V169.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M182.965 169.793H178.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M239.645 169.387V169.187' fill='#339999'/> +<path clip-path='url(#clip6)' d='M239.645 169.387V169.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M237.652 169.187H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M239.645 169.387V169.59' fill='#339999'/> +<path clip-path='url(#clip6)' d='M239.645 169.387V169.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M241.633 169.59H237.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M298.313 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M298.313 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M356.981 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M356.981 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M415.649 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M415.649 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M474.32 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M474.32 84.164V84.164' fill='#339999'/> +<path clip-path='url(#clip6)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M184.586 251.93H187.824V180.328H184.586ZM243.254 251.93H246.492V179.59H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V107.516H360.594ZM419.262 251.93H422.5V175.43H419.262ZM477.93 251.93H481.168V182.406H477.93Z' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M184.586 251.93H187.824V180.328H184.586ZM243.254 251.93H246.492V179.59H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V107.516H360.594ZM419.262 251.93H422.5V175.43H419.262ZM477.93 251.93H481.168V182.406H477.93Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M186.203 180.328V179.992' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M186.203 180.328V179.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M184.211 179.992H188.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M186.203 180.328V180.664' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M186.203 180.328V180.664' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M188.196 180.664H184.211' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M244.875 179.59V179.187' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M244.875 179.59V179.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M242.883 179.187H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M244.875 179.59V179.992' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M244.875 179.59V179.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M246.864 179.992H242.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M303.543 84.164V84.164' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M303.543 84.164V84.164' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M362.211 107.516V104.094' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M362.211 107.516V104.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M360.219 104.093H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M362.211 107.516V110.937' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M362.211 107.516V110.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M364.203 110.937H360.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M420.879 175.43V175.16' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M420.879 175.43V175.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M418.887 175.16H422.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M420.879 175.43V175.695' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M420.879 175.43V175.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M422.871 175.696H418.887' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M479.551 182.406V181.199' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M479.551 182.406V181.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M477.559 181.199H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M479.551 182.406V183.613' fill='#bf8080'/> +<path clip-path='url(#clip6)' d='M479.551 182.406V183.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M481.543 183.613H477.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M420.539 312.98H487.762V278.973H420.539Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 255.575 118.327)'> +<use x='168.285' xlink:href='#g2-114' y='167.424'/> +<use x='170.092' xlink:href='#g2-53' y='167.424'/> +<use x='172.739' xlink:href='#g2-97' y='167.424'/> +<use x='175.281' xlink:href='#g2-45' y='167.424'/> +<use x='177.046' xlink:href='#g2-49' y='167.424'/> +<use x='179.692' xlink:href='#g2-50' y='167.424'/> +<use x='182.338' xlink:href='#g2-120' y='167.424'/> +<use x='184.777' xlink:href='#g2-108' y='167.424'/> +<use x='186.04' xlink:href='#g2-97' y='167.424'/> +<use x='188.435' xlink:href='#g2-114' y='167.424'/> +<use x='190.243' xlink:href='#g2-103' y='167.424'/> +<use x='192.889' xlink:href='#g2-101' y='167.424'/> +<use x='195.241' xlink:href='#g2-44' y='167.424'/> +<use x='198.476' xlink:href='#g2-51' y='167.424'/> +<use x='201.122' xlink:href='#g2-56' y='167.424'/> +<use x='203.769' xlink:href='#g2-52' y='167.424'/> +<use x='206.415' xlink:href='#g2-71' y='167.424'/> +<use x='209.943' xlink:href='#g2-98' y='167.424'/> +<use x='168.285' xlink:href='#g2-52' y='173.401'/> +<use x='170.931' xlink:href='#g2-56' y='173.401'/> +<use x='175.342' xlink:href='#g2-112' y='173.401'/> +<use x='177.928' xlink:href='#g2-114' y='173.401'/> +<use x='179.735' xlink:href='#g2-111' y='173.401'/> +<use x='182.529' xlink:href='#g2-99' y='173.401'/> +<use x='186.645' xlink:href='#g2-65' y='173.401'/> +<use x='190.174' xlink:href='#g2-77' y='173.401'/> +<use x='194.792' xlink:href='#g2-68' y='173.401'/> +<use x='200.378' xlink:href='#g2-64' y='173.401'/> +<use x='203.907' xlink:href='#g2-50' y='173.401'/> +<use x='206.553' xlink:href='#g2-46' y='173.401'/> +<use x='208.024' xlink:href='#g2-53' y='173.401'/> +<use x='210.67' xlink:href='#g2-71' y='173.401'/> +<use x='214.198' xlink:href='#g2-104' y='173.401'/> +<use x='216.931' xlink:href='#g2-122' y='173.401'/> +<use x='168.285' xlink:href='#g2-85' y='179.379'/> +<use x='171.917' xlink:href='#g2-98' y='179.379'/> +<use x='174.65' xlink:href='#g2-117' y='179.379'/> +<use x='177.383' xlink:href='#g2-110' y='179.379'/> +<use x='180.116' xlink:href='#g2-116' y='179.379'/> +<use x='182.027' xlink:href='#g2-117' y='179.379'/> +<use x='186.524' xlink:href='#g2-49' y='179.379'/> +<use x='189.17' xlink:href='#g2-56' y='179.379'/> +<use x='191.817' xlink:href='#g2-46' y='179.379'/> +<use x='193.287' xlink:href='#g2-48' y='179.379'/> +<use x='195.933' xlink:href='#g2-52' y='179.379'/> +<use x='198.58' xlink:href='#g2-46' y='179.379'/> +<use x='200.05' xlink:href='#g2-49' y='179.379'/> +<use x='202.696' xlink:href='#g2-44' y='179.379'/> +<use x='205.931' xlink:href='#g2-71' y='179.379'/> +<use x='209.459' xlink:href='#g2-67' y='179.379'/> +<use x='212.841' xlink:href='#g2-67' y='179.379'/> +<use x='217.986' xlink:href='#g2-55' y='179.379'/> +<use x='220.633' xlink:href='#g2-46' y='179.379'/> +<use x='222.103' xlink:href='#g2-52' y='179.379'/> +<use x='224.749' xlink:href='#g2-46' y='179.379'/> +<use x='226.219' xlink:href='#g2-48' y='179.379'/> +<use x='168.285' xlink:href='#g2-50' y='185.357'/> +<use x='170.931' xlink:href='#g2-52' y='185.357'/> +<use x='175.342' xlink:href='#g2-99' y='185.357'/> +<use x='177.694' xlink:href='#g2-111' y='185.357'/> +<use x='180.193' xlink:href='#g2-114' y='185.357'/> +<use x='182.001' xlink:href='#g2-101' y='185.357'/> +<use x='184.353' xlink:href='#g2-115' y='185.357'/> +<use x='188.146' xlink:href='#g2-111' y='185.357'/> +<use x='190.793' xlink:href='#g2-110' y='185.357'/> +<use x='195.29' xlink:href='#g2-51' y='185.357'/> +<use x='199.7' xlink:href='#g2-110' y='185.357'/> +<use x='202.433' xlink:href='#g2-117' y='185.357'/> +<use x='205.166' xlink:href='#g2-109' y='185.357'/> +<use x='209.369' xlink:href='#g2-97' y='185.357'/> +<use x='213.676' xlink:href='#g2-110' y='185.357'/> +<use x='216.409' xlink:href='#g2-111' y='185.357'/> +<use x='219.202' xlink:href='#g2-100' y='185.357'/> +<use x='221.935' xlink:href='#g2-101' y='185.357'/> +<use x='224.287' xlink:href='#g2-115' y='185.357'/> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-48' y='191.334'/> +<use x='173.578' xlink:href='#g2-50' y='191.334'/> +<use x='176.224' xlink:href='#g2-48' y='191.334'/> +<use x='178.87' xlink:href='#g2-45' y='191.334'/> +<use x='180.635' xlink:href='#g2-48' y='191.334'/> +<use x='183.281' xlink:href='#g2-49' y='191.334'/> +<use x='185.927' xlink:href='#g2-45' y='191.334'/> +<use x='187.692' xlink:href='#g2-49' y='191.334'/> +<use x='190.338' xlink:href='#g2-54' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -45.339 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 13.33 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 71.999 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 130.668 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 189.337 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 248.006 346.904)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -40.108 346.367)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-49' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 18.561 342.005)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-55' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 77.23 260.606)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-50' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 135.899 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-53' y='191.334'/> +<use x='176.558' xlink:href='#g2-54' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-54' y='191.334'/> +<use x='183.321' xlink:href='#g2-52' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 194.568 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-55' y='191.334'/> +<use x='179.205' xlink:href='#g2-50' y='191.334'/> +<use x='181.851' xlink:href='#g2-46' y='191.334'/> +<use x='183.321' xlink:href='#g2-48' y='191.334'/> +<use x='185.968' xlink:href='#g2-51' y='191.334'/> +<use x='188.614' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 253.236 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-55' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-50' y='191.334'/> +<use x='183.321' xlink:href='#g2-57' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -34.878 340.797)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 23.791 340.126)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 82.46 247.855)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-52' y='191.334'/> +<use x='175.048' xlink:href='#g2-56' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 141.129 251.077)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-52' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 199.798 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-52' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-55' y='191.334'/> +<use x='180.675' xlink:href='#g2-55' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 258.467 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-55' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-49' y='191.334'/> +<use x='183.321' xlink:href='#g2-48' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -29.648 317.243)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-52' y='191.334'/> +<use x='175.048' xlink:href='#g2-52' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 29.021 318.384)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-52' y='191.334'/> +<use x='175.048' xlink:href='#g2-50' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 87.69 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-52' y='191.334'/> +<use x='180.675' xlink:href='#g2-56' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 146.359 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-57' y='191.334'/> +<use x='180.675' xlink:href='#g2-51' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 205.028 293.689)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-55' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 263.697 346.032)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-49' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -24.417 342.743)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-54' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 34.252 345.159)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 92.921 336.435)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-54' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 151.59 345.226)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-50' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 210.259 360.996)'> +<use x='168.285' xlink:href='#g2-48' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-55' y='191.334'/> +<use x='175.048' xlink:href='#g2-57' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 268.928 346.636)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-48' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -19.187 335.764)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-55' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 39.482 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-53' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-51' y='191.334'/> +<use x='180.675' xlink:href='#g2-53' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 98.151 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-51' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-57' y='191.334'/> +<use x='183.321' xlink:href='#g2-50' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 156.82 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-53' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-54' y='191.334'/> +<use x='180.675' xlink:href='#g2-48' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 215.489 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-55' y='191.334'/> +<use x='176.558' xlink:href='#g2-49' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-54' y='191.334'/> +<use x='183.321' xlink:href='#g2-57' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 274.158 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-53' y='191.334'/> +<use x='180.675' xlink:href='#g2-54' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -13.956 309.19)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-53' y='191.334'/> +<use x='175.048' xlink:href='#g2-54' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 44.713 302.01)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-54' y='191.334'/> +<use x='175.048' xlink:href='#g2-55' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 103.382 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-51' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-51' y='191.334'/> +<use x='183.321' xlink:href='#g2-55' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 161.523 407.299)'> +<use x='168.285' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 220.192 407.299)'> +<use x='168.285' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 279.389 345.226)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -8.726 331.335)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-50' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 49.943 331.47)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-50' y='191.334'/> +<use x='175.048' xlink:href='#g2-51' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 108.612 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-49' y='191.334'/> +<use x='176.558' xlink:href='#g2-55' y='191.334'/> +<use x='179.205' xlink:href='#g2-46' y='191.334'/> +<use x='180.675' xlink:href='#g2-55' y='191.334'/> +<use x='183.321' xlink:href='#g2-52' y='191.334'/> +<use x='185.968' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 167.281 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-52' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-57' y='191.334'/> +<use x='180.675' xlink:href='#g2-57' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 225.95 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-53' y='191.334'/> +<use x='180.675' xlink:href='#g2-53' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 284.619 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-53' y='191.334'/> +<use x='180.675' xlink:href='#g2-57' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -3.495 342.408)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-55' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 55.174 341.67)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-56' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 113.843 246.245)'> +<use x='163.396' xlink:href='#g4-1' y='191.334'/> +<use x='166.901' xlink:href='#g4-1' y='191.334'/> +<use x='170.407' xlink:href='#g4-1' y='191.334'/> +<use x='173.912' xlink:href='#g2-51' y='191.334'/> +<use x='176.558' xlink:href='#g2-46' y='191.334'/> +<use x='178.029' xlink:href='#g2-50' y='191.334'/> +<use x='180.675' xlink:href='#g2-48' y='191.334'/> +<use x='183.321' xlink:href='#g2-120' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 172.512 269.598)'> +<use x='168.285' xlink:href='#g2-50' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-53' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 231.181 337.509)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-49' y='191.334'/> +<use x='175.048' xlink:href='#g2-52' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 289.85 344.488)'> +<use x='168.285' xlink:href='#g2-49' y='191.334'/> +<use x='170.931' xlink:href='#g2-46' y='191.334'/> +<use x='172.401' xlink:href='#g2-48' y='191.334'/> +<use x='175.048' xlink:href='#g2-52' y='191.334'/> +</g> +<g transform='matrix(0 -1 1 0 -78.176 391.591)'> +<use x='168.285' xlink:href='#g1-82' y='191.334'/> +<use x='174.255' xlink:href='#g1-101' y='191.334'/> +<use x='178.351' xlink:href='#g1-108' y='191.334'/> +<use x='180.551' xlink:href='#g1-97' y='191.334'/> +<use x='184.979' xlink:href='#g1-116' y='191.334'/> +<use x='188.307' xlink:href='#g1-105' y='191.334'/> +<use x='190.507' xlink:href='#g1-118' y='191.334'/> +<use x='194.755' xlink:href='#g1-101' y='191.334'/> +<use x='201.922' xlink:href='#g1-116' y='191.334'/> +<use x='205.25' xlink:href='#g1-105' y='191.334'/> +<use x='207.45' xlink:href='#g1-109' y='191.334'/> +<use x='214.77' xlink:href='#g1-101' y='191.334'/> +<use x='221.937' xlink:href='#g3-40' y='191.334'/> +<use x='225.231' xlink:href='#g3-108' y='191.334'/> +<use x='227.251' xlink:href='#g3-111' y='191.334'/> +<use x='231.25' xlink:href='#g3-119' y='191.334'/> +<use x='236.799' xlink:href='#g3-101' y='191.334'/> +<use x='240.562' xlink:href='#g3-114' y='191.334'/> +<use x='246.277' xlink:href='#g3-105' y='191.334'/> +<use x='248.297' xlink:href='#g3-115' y='191.334'/> +<use x='254.366' xlink:href='#g3-98' y='191.334'/> +<use x='258.974' xlink:href='#g3-101' y='191.334'/> +<use x='262.738' xlink:href='#g3-116' y='191.334'/> +<use x='265.796' xlink:href='#g3-116' y='191.334'/> +<use x='268.854' xlink:href='#g3-101' y='191.334'/> +<use x='272.618' xlink:href='#g3-114' y='191.334'/> +<use x='275.51' xlink:href='#g3-41' y='191.334'/> +</g> +<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='#ffffff'/> +<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='#993333'/> +<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -40.354 114.479)'> +<use x='195.372' xlink:href='#g3-120' y='178.327'/> +<use x='199.274' xlink:href='#g3-109' y='178.327'/> +<use x='205.999' xlink:href='#g3-105' y='178.327'/> +<use x='208.019' xlink:href='#g3-58' y='178.327'/> +<use x='210.371' xlink:href='#g0-57' y='178.327'/> +<use x='214.076' xlink:href='#g0-57' y='178.327'/> +</g> +<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='#8080bf'/> +<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.441 114.036)'> +<use x='239.382' xlink:href='#g3-116' y='178.327'/> +<use x='242.44' xlink:href='#g3-99' y='178.327'/> +<use x='246.204' xlink:href='#g3-58' y='178.327'/> +<use x='248.556' xlink:href='#g0-53' y='178.327'/> +<use x='252.261' xlink:href='#g0-54' y='178.327'/> +</g> +<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='#ffb733'/> +<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.04 114.479)'> +<use x='281.863' xlink:href='#g3-106' y='178.327'/> +<use x='284.119' xlink:href='#g3-101' y='178.327'/> +<use x='287.882' xlink:href='#g3-58' y='178.327'/> +<use x='290.235' xlink:href='#g0-53' y='178.327'/> +<use x='293.94' xlink:href='#g0-50' y='178.327'/> +</g> +<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='#bf80bf'/> +<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.932 114.515)'> +<use x='321.287' xlink:href='#g3-116' y='178.327'/> +<use x='324.345' xlink:href='#g3-98' y='178.327'/> +<use x='328.717' xlink:href='#g3-98' y='178.327'/> +<use x='333.09' xlink:href='#g3-58' y='178.327'/> +<use x='335.442' xlink:href='#g0-53' y='178.327'/> +<use x='339.147' xlink:href='#g0-51' y='178.327'/> +</g> +<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='#dfbf9f'/> +<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.662 114.036)'> +<use x='356.019' xlink:href='#g3-114' y='178.327'/> +<use x='358.911' xlink:href='#g3-112' y='178.327'/> +<use x='363.284' xlink:href='#g3-58' y='178.327'/> +<use x='365.636' xlink:href='#g0-56' y='178.327'/> +<use x='369.341' xlink:href='#g0-54' y='178.327'/> +</g> +<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='#80bf80'/> +<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -43.882 114.515)'> +<use x='195.372' xlink:href='#g3-104' y='191.334'/> +<use x='199.744' xlink:href='#g3-111' y='191.334'/> +<use x='203.978' xlink:href='#g3-97' y='191.334'/> +<use x='207.811' xlink:href='#g3-114' y='191.334'/> +<use x='210.703' xlink:href='#g3-100' y='191.334'/> +<use x='215.076' xlink:href='#g3-58' y='191.334'/> +<use x='217.428' xlink:href='#g0-51' y='191.334'/> +<use x='221.133' xlink:href='#g0-51' y='191.334'/> +</g> +<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='#bfbf80'/> +<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -43.084 114.515)'> +<use x='239.382' xlink:href='#g3-109' y='191.334'/> +<use x='246.107' xlink:href='#g3-101' y='191.334'/> +<use x='249.871' xlink:href='#g3-115' y='191.334'/> +<use x='253.117' xlink:href='#g3-104' y='191.334'/> +<use x='257.489' xlink:href='#g3-58' y='191.334'/> +<use x='259.842' xlink:href='#g0-51' y='191.334'/> +<use x='263.547' xlink:href='#g0-52' y='191.334'/> +</g> +<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='#339999'/> +<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -42.353 114.515)'> +<use x='281.863' xlink:href='#g3-103' y='191.334'/> +<use x='286.097' xlink:href='#g3-108' y='191.334'/> +<use x='288.118' xlink:href='#g3-105' y='191.334'/> +<use x='290.138' xlink:href='#g3-98' y='191.334'/> +<use x='294.746' xlink:href='#g3-99' y='191.334'/> +<use x='298.509' xlink:href='#g3-58' y='191.334'/> +<use x='300.862' xlink:href='#g0-52' y='191.334'/> +<use x='304.567' xlink:href='#g0-51' y='191.334'/> +</g> +<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='#bf8080'/> +<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -40.026 114.479)'> +<use x='321.287' xlink:href='#g3-115' y='191.334'/> +<use x='324.533' xlink:href='#g3-109' y='191.334'/> +<use x='331.258' xlink:href='#g3-105' y='191.334'/> +<use x='333.278' xlink:href='#g3-58' y='191.334'/> +<use x='335.63' xlink:href='#g0-54' y='191.334'/> +<use x='339.335' xlink:href='#g0-57' y='191.334'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-2.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-2.svg new file mode 100644 index 0000000..917ea57 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-2.svg @@ -0,0 +1,983 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='243.704pt' version='1.1' viewBox='106.737 54.995 381.623 243.704' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip2'> +<path d='M135.949 249.281H487.961V81.515H135.949Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/> +<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/> +<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/> +<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/> +<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/> +<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/> +<path d='M2.002 -3.457H1.519L0.149 0H0.558L0.946 -0.986H2.461L2.849 0H3.372L2.002 -3.457ZM1.709 -3.078L2.336 -1.28H1.071L1.709 -3.078Z' id='g1-65'/> +<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/> +<path d='M0.488 -3.457V0H1.903C2.8 0 3.522 -0.757 3.522 -1.699C3.522 -2.675 2.795 -3.457 1.903 -3.457H0.488ZM0.976 -0.294V-3.163H1.768C2.451 -3.163 3.034 -2.62 3.034 -1.704C3.034 -0.777 2.426 -0.294 1.768 -0.294H0.976Z' id='g1-68'/> +<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/> +<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/> +<path d='M2.775 -1.729C2.715 -1.579 2.356 -0.702 2.306 -0.493H2.301C2.267 -0.638 2.037 -1.21 1.988 -1.34L1.131 -3.457H0.523V0H0.941V-3.059H0.946C0.986 -2.884 1.245 -2.227 1.27 -2.172L2.102 -0.105H2.496L3.238 -1.938C3.238 -1.943 3.582 -2.79 3.666 -3.064H3.671V0H4.09V-3.457H3.477L2.775 -1.729Z' id='g1-77'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M2.361 -2.212H1.958C1.554 -1.26 1.275 -0.618 1.255 -0.314C1.245 -0.453 1.156 -0.702 1.066 -0.936C0.986 -1.136 0.907 -1.335 0.817 -1.529L0.503 -2.212H0.075L1.106 0C1.046 0.144 0.946 0.374 0.917 0.438C0.812 0.648 0.742 0.717 0.608 0.717C0.588 0.717 0.403 0.717 0.189 0.628L0.219 0.976C0.264 0.986 0.448 1.016 0.603 1.016C0.802 1.016 0.981 0.941 1.191 0.463L2.361 -2.212Z' id='g1-121'/> +<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page2'> +<path d='M194.617 258.136V249.281M253.285 258.136V249.281M311.953 258.136V249.281M370.625 258.136V249.281M429.293 258.136V249.281M194.617 72.66V81.515M253.285 72.66V81.515M311.953 72.66V81.515M370.625 72.66V81.515M429.293 72.66V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.265V81.515M223.953 77.265V81.515M282.621 77.265V81.515M341.289 77.265V81.515M399.957 77.265V81.515M458.629 77.265V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.515H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.515H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 249.281V81.515H487.961V249.281H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 61.588)'> +<use x='168.285' xlink:href='#g2-97' y='201.694'/> +<use x='172.353' xlink:href='#g2-108' y='201.694'/> +<use x='174.373' xlink:href='#g2-108' y='201.694'/> +<use x='176.393' xlink:href='#g2-111' y='201.694'/> +<use x='180.863' xlink:href='#g2-99' y='201.694'/> +<use x='184.627' xlink:href='#g2-45' y='201.694'/> +<use x='187.449' xlink:href='#g2-116' y='201.694'/> +<use x='190.507' xlink:href='#g2-101' y='201.694'/> +<use x='194.271' xlink:href='#g2-115' y='201.694'/> +<use x='197.517' xlink:href='#g2-116' y='201.694'/> +<use x='200.575' xlink:href='#g2-49' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 36.532 61.588)'> +<use x='168.285' xlink:href='#g2-97' y='201.694'/> +<use x='172.353' xlink:href='#g2-108' y='201.694'/> +<use x='174.373' xlink:href='#g2-108' y='201.694'/> +<use x='176.393' xlink:href='#g2-111' y='201.694'/> +<use x='180.863' xlink:href='#g2-99' y='201.694'/> +<use x='184.627' xlink:href='#g2-45' y='201.694'/> +<use x='187.449' xlink:href='#g2-116' y='201.694'/> +<use x='190.507' xlink:href='#g2-101' y='201.694'/> +<use x='194.271' xlink:href='#g2-115' y='201.694'/> +<use x='197.517' xlink:href='#g2-116' y='201.694'/> +<use x='200.575' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 94.98 61.588)'> +<use x='168.285' xlink:href='#g2-115' y='201.694'/> +<use x='171.531' xlink:href='#g2-104' y='201.694'/> +<use x='175.904' xlink:href='#g2-54' y='201.694'/> +<use x='180.138' xlink:href='#g2-98' y='201.694'/> +<use x='184.746' xlink:href='#g2-101' y='201.694'/> +<use x='188.509' xlink:href='#g2-110' y='201.694'/> +<use x='192.882' xlink:href='#g2-99' y='201.694'/> +<use x='196.646' xlink:href='#g2-104' y='201.694'/> +<use x='201.018' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 153.649 61.588)'> +<use x='168.285' xlink:href='#g2-115' y='201.694'/> +<use x='171.531' xlink:href='#g2-104' y='201.694'/> +<use x='175.904' xlink:href='#g2-56' y='201.694'/> +<use x='180.138' xlink:href='#g2-98' y='201.694'/> +<use x='184.746' xlink:href='#g2-101' y='201.694'/> +<use x='188.509' xlink:href='#g2-110' y='201.694'/> +<use x='192.882' xlink:href='#g2-99' y='201.694'/> +<use x='196.646' xlink:href='#g2-104' y='201.694'/> +<use x='201.018' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 207.225 61.588)'> +<use x='168.285' xlink:href='#g2-120' y='201.694'/> +<use x='172.187' xlink:href='#g2-109' y='201.694'/> +<use x='178.912' xlink:href='#g2-97' y='201.694'/> +<use x='182.98' xlink:href='#g2-108' y='201.694'/> +<use x='185' xlink:href='#g2-108' y='201.694'/> +<use x='187.02' xlink:href='#g2-111' y='201.694'/> +<use x='191.49' xlink:href='#g2-99' y='201.694'/> +<use x='195.254' xlink:href='#g2-45' y='201.694'/> +<use x='198.076' xlink:href='#g2-116' y='201.694'/> +<use x='201.134' xlink:href='#g2-101' y='201.694'/> +<use x='204.898' xlink:href='#g2-115' y='201.694'/> +<use x='208.144' xlink:href='#g2-116' y='201.694'/> +<use x='211.202' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 263.494 61.588)'> +<use x='168.285' xlink:href='#g2-99' y='201.694'/> +<use x='172.049' xlink:href='#g2-97' y='201.694'/> +<use x='176.117' xlink:href='#g2-99' y='201.694'/> +<use x='179.88' xlink:href='#g2-104' y='201.694'/> +<use x='184.253' xlink:href='#g2-101' y='201.694'/> +<use x='188.017' xlink:href='#g2-45' y='201.694'/> +<use x='190.839' xlink:href='#g2-115' y='201.694'/> +<use x='194.086' xlink:href='#g2-99' y='201.694'/> +<use x='197.849' xlink:href='#g2-114' y='201.694'/> +<use x='200.741' xlink:href='#g2-97' y='201.694'/> +<use x='204.81' xlink:href='#g2-116' y='201.694'/> +<use x='207.868' xlink:href='#g2-99' y='201.694'/> +<use x='211.631' xlink:href='#g2-104' y='201.694'/> +<use x='216.004' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 49.223)'> +<use x='168.285' xlink:href='#g1-48' y='201.694'/> +<use x='170.931' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 15.67)'> +<use x='168.285' xlink:href='#g1-48' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -17.883)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -51.436)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -84.989)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -118.543)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<path clip-path='url(#clip2)' d='M135.949 182.176H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M145.356 249.281H148.594V182.176H145.356ZM204.028 249.281H207.266V182.176H204.028ZM262.695 249.281H265.934V182.176H262.695ZM321.363 249.281H324.602V182.176H321.363ZM380.031 249.281H383.27V182.176H380.031ZM438.703 249.281H441.942V182.176H438.703Z' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M145.356 249.281H148.594V182.176H145.356ZM204.028 249.281H207.266V182.176H204.028ZM262.695 249.281H265.934V182.176H262.695ZM321.363 249.281H324.602V182.176H321.363ZM380.031 249.281H383.27V182.176H380.031ZM438.703 249.281H441.942V182.176H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M146.977 182.176V182.043' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M146.977 182.176V182.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M144.984 182.043H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M146.977 182.176V182.308' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M146.977 182.176V182.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M148.969 182.308H144.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M205.645 182.176V182.043' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M205.645 182.176V182.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M203.652 182.043H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M205.645 182.176V182.308' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M205.645 182.176V182.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M207.636 182.308H203.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M264.313 182.176V180.429' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M264.313 182.176V180.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M262.32 180.429H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M264.313 182.176V183.922' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M264.313 182.176V183.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M266.304 183.922H262.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M322.984 182.176V181.504' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M322.984 182.176V181.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M320.992 181.504H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M322.984 182.176V182.847' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M322.984 182.176V182.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M324.976 182.847H320.988' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M381.652 182.176V181.84' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M381.652 182.176V181.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M379.66 181.84H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M381.652 182.176V182.512' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M381.652 182.176V182.512' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M383.644 182.512H379.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M440.32 182.176V181.371' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M440.32 182.176V181.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M438.328 181.371H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M440.32 182.176V182.98' fill='#e0e0f0'/> +<path clip-path='url(#clip2)' d='M440.32 182.176V182.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M442.312 182.98H438.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M150.586 249.281H153.824V180.765H150.586ZM209.258 249.281H212.496V173.117H209.258ZM267.926 249.281H271.164V158.086H267.926ZM326.594 249.281H329.832V81.515H326.594ZM385.262 249.281H388.5V81.515H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M150.586 249.281H153.824V180.765H150.586ZM209.258 249.281H212.496V173.117H209.258ZM267.926 249.281H271.164V158.086H267.926ZM326.594 249.281H329.832V81.515H326.594ZM385.262 249.281H388.5V81.515H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M152.207 180.765V180.633' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M152.207 180.765V180.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M150.215 180.633H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M152.207 180.765V180.902' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M152.207 180.765V180.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M154.2 180.902H150.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M210.875 173.117V172.914' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M210.875 173.117V172.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M208.883 172.915H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M210.875 173.117V173.316' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M210.875 173.117V173.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M212.867 173.316H208.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M269.543 158.086V157.48' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M269.543 158.086V157.48' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M267.551 157.48H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M269.543 158.086V158.687' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M269.543 158.086V158.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M271.535 158.687H267.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M328.215 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M326.223 81.516H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M328.215 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M326.223 81.516H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M386.883 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M384.891 81.516H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M386.883 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M384.891 81.516H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M445.551 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M445.551 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip2)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M155.817 249.281H159.055V175.668H155.817ZM214.488 249.281H217.727V172.648H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V148.152H331.824ZM390.492 249.281H393.731V130.57H390.492ZM449.164 249.281H452.402V81.515H449.164Z' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M155.817 249.281H159.055V175.668H155.817ZM214.488 249.281H217.727V172.648H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V148.152H331.824ZM390.492 249.281H393.731V130.57H390.492ZM449.164 249.281H452.402V81.515H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M157.438 175.668V174.39' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M157.438 175.668V174.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M155.445 174.391H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M157.438 175.668V176.941' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M157.438 175.668V176.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M159.43 176.942H155.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M216.106 172.648V172.648' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M214.113 172.648H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M216.106 172.648V172.648' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M214.113 172.648H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M274.774 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M274.774 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M333.445 148.152V146.945' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M333.445 148.152V146.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M331.453 146.945H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M333.445 148.152V149.359' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M333.445 148.152V149.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M335.437 149.359H331.449' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M392.113 130.57V129.566' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M392.113 130.57V129.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M390.121 129.566H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M392.113 130.57V131.578' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M392.113 130.57V131.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M394.105 131.578H390.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M450.781 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M448.789 81.516H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M450.781 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip2)' d='M448.789 81.516H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M161.047 249.281H164.285V157.949H161.047ZM219.719 249.281H222.957V144.664H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V156.879H337.055ZM395.723 249.281H398.961V162.984H395.723ZM454.395 249.281H457.633V179.426H454.395Z' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M161.047 249.281H164.285V157.949H161.047ZM219.719 249.281H222.957V144.664H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V156.879H337.055ZM395.723 249.281H398.961V162.984H395.723ZM454.395 249.281H457.633V179.426H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M162.668 157.949V157.883' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M162.668 157.949V157.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M160.676 157.883H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M162.668 157.949V158.019' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M162.668 157.949V158.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M164.661 158.02H160.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M221.336 144.664V144.261' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M221.336 144.664V144.261' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M219.344 144.261H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M221.336 144.664V145.066' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M221.336 144.664V145.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M223.329 145.066H219.344' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M280.004 81.515V81.515' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M280.004 81.515V81.515' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M338.676 156.879V156.004' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M338.676 156.879V156.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M336.684 156.004H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M338.676 156.879V157.75' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M338.676 156.879V157.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M340.668 157.75H336.68' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M397.344 162.984V162.582' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M397.344 162.984V162.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M395.352 162.582H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M397.344 162.984V163.387' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M397.344 162.984V163.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M399.336 163.386H395.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M456.012 179.426V178.621' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M456.012 179.426V178.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M454.02 178.622H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M456.012 179.426V180.23' fill='#8585c2'/> +<path clip-path='url(#clip2)' d='M456.012 179.426V180.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M458.004 180.23H454.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M166.278 249.281H169.516V163.992H166.278ZM224.949 249.281H228.188V159.426H224.949ZM283.617 249.281H286.856V91.047H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M166.278 249.281H169.516V163.992H166.278ZM224.949 249.281H228.188V159.426H224.949ZM283.617 249.281H286.856V91.047H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M167.899 163.992V163.722' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M167.899 163.992V163.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M165.906 163.723H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M167.899 163.992V164.258' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M167.899 163.992V164.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M169.891 164.258H165.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M226.567 159.426V159.359' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M226.567 159.426V159.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M224.574 159.359H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M226.567 159.426V159.496' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M226.567 159.426V159.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M228.559 159.496H224.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M285.234 91.047V90.777' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M285.234 91.047V90.777' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M283.242 90.777H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M285.234 91.047V91.316' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M285.234 91.047V91.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M287.227 91.316H283.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M343.906 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M343.906 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M402.574 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M402.574 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M461.242 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M461.242 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip2)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M171.508 249.281H174.746V172.648H171.508ZM230.18 249.281H233.414V132.519H230.18ZM288.848 249.281H292.086V124.867H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M171.508 249.281H174.746V172.648H171.508ZM230.18 249.281H233.414V132.519H230.18ZM288.848 249.281H292.086V124.867H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M173.129 172.648V172.312' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M173.129 172.648V172.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M171.137 172.313H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M173.129 172.648V172.984' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M173.129 172.648V172.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M175.122 172.985H171.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M231.797 132.519V131.847' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M231.797 132.519V131.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M229.805 131.848H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M231.797 132.519V133.187' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M231.797 132.519V133.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M233.79 133.188H229.805' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M290.465 124.867V124.062' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M290.465 124.867V124.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M288.473 124.062H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M290.465 124.867V125.672' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M290.465 124.867V125.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M292.458 125.672H288.473' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M349.137 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M349.137 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M407.805 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M407.805 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M466.473 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M466.473 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip2)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M176.738 249.281H179.977V163.656H176.738ZM235.41 249.281H238.645V159.359H235.41ZM294.078 249.281H297.317V90.578H294.078ZM352.746 249.281H355.984V81.515H352.746ZM411.414 249.281H414.652V81.515H411.414ZM470.086 249.281H473.324V81.515H470.086Z' fill='#292994'/> +<path clip-path='url(#clip2)' d='M176.738 249.281H179.977V163.656H176.738ZM235.41 249.281H238.645V159.359H235.41ZM294.078 249.281H297.317V90.578H294.078ZM352.746 249.281H355.984V81.515H352.746ZM411.414 249.281H414.652V81.515H411.414ZM470.086 249.281H473.324V81.515H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M178.36 163.656V163.32' fill='#292994'/> +<path clip-path='url(#clip2)' d='M178.36 163.656V163.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M176.367 163.32H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M178.36 163.656V163.992' fill='#292994'/> +<path clip-path='url(#clip2)' d='M178.36 163.656V163.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M180.352 163.992H176.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M237.027 159.359V159.359' fill='#292994'/> +<path clip-path='url(#clip2)' d='M235.035 159.359H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M237.027 159.359V159.359' fill='#292994'/> +<path clip-path='url(#clip2)' d='M235.035 159.359H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M295.695 90.578V89.234' fill='#292994'/> +<path clip-path='url(#clip2)' d='M295.695 90.578V89.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M293.703 89.234H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M295.695 90.578V91.918' fill='#292994'/> +<path clip-path='url(#clip2)' d='M295.695 90.578V91.918' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M297.688 91.918H293.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M354.367 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip2)' d='M352.375 81.516H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M354.367 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip2)' d='M352.375 81.516H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M413.035 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip2)' d='M411.043 81.516H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M413.035 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip2)' d='M411.043 81.516H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M471.703 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip2)' d='M469.711 81.516H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M471.703 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip2)' d='M469.711 81.516H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M416.645 249.281H419.883V131.445H416.645ZM181.969 249.281H185.207V153.523H181.969ZM240.641 249.281H243.875V149.226H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V129.297H357.977ZM475.317 249.281H478.555V179.894H475.317Z' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M416.645 249.281H419.883V131.445H416.645ZM181.969 249.281H185.207V153.523H181.969ZM240.641 249.281H243.875V149.226H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V129.297H357.977ZM475.317 249.281H478.555V179.894H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M418.266 131.445V128.894' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M418.266 131.445V128.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M416.274 128.895H420.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M418.266 131.445V133.992' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M418.266 131.445V133.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M420.257 133.992H416.273' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M183.59 153.523V152.851' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M183.59 153.523V152.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M181.598 152.852H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M183.59 153.523V154.191' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M183.59 153.523V154.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M185.582 154.191H181.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M242.258 149.226V149.16' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M242.258 149.226V149.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M240.266 149.16H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M242.258 149.226V149.293' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M242.258 149.226V149.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M244.25 149.293H240.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M300.926 81.515V81.515' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M300.926 81.515V81.515' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M359.598 129.297V128.426' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M359.598 129.297V128.426' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M357.606 128.426H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M359.598 129.297V130.168' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M359.598 129.297V130.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M361.589 130.168H357.601' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M476.934 179.894V179.894' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M474.942 179.895H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M476.934 179.894V179.894' fill='#0a0a85'/> +<path clip-path='url(#clip2)' d='M474.942 179.895H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip2)' d='M418.387 298.301H487.762V276.324H418.387Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 253.422 92.648)'> +<use x='168.285' xlink:href='#g1-114' y='190.457'/> +<use x='170.092' xlink:href='#g1-53' y='190.457'/> +<use x='172.739' xlink:href='#g1-97' y='190.457'/> +<use x='175.281' xlink:href='#g1-45' y='190.457'/> +<use x='177.046' xlink:href='#g1-52' y='190.457'/> +<use x='179.692' xlink:href='#g1-120' y='190.457'/> +<use x='182.131' xlink:href='#g1-108' y='190.457'/> +<use x='183.393' xlink:href='#g1-97' y='190.457'/> +<use x='185.789' xlink:href='#g1-114' y='190.457'/> +<use x='187.596' xlink:href='#g1-103' y='190.457'/> +<use x='190.243' xlink:href='#g1-101' y='190.457'/> +<use x='192.595' xlink:href='#g1-44' y='190.457'/> +<use x='195.83' xlink:href='#g1-49' y='190.457'/> +<use x='198.476' xlink:href='#g1-50' y='190.457'/> +<use x='201.122' xlink:href='#g1-56' y='190.457'/> +<use x='203.769' xlink:href='#g1-71' y='190.457'/> +<use x='207.297' xlink:href='#g1-98' y='190.457'/> +<use x='168.285' xlink:href='#g1-49' y='196.075'/> +<use x='170.931' xlink:href='#g1-54' y='196.075'/> +<use x='173.578' xlink:href='#g1-45' y='196.075'/> +<use x='175.342' xlink:href='#g1-99' y='196.075'/> +<use x='177.694' xlink:href='#g1-111' y='196.075'/> +<use x='180.193' xlink:href='#g1-114' y='196.075'/> +<use x='182.001' xlink:href='#g1-101' y='196.075'/> +<use x='186.118' xlink:href='#g1-65' y='196.075'/> +<use x='189.646' xlink:href='#g1-77' y='196.075'/> +<use x='194.264' xlink:href='#g1-68' y='196.075'/> +<use x='199.851' xlink:href='#g1-69' y='196.075'/> +<use x='203.025' xlink:href='#g1-112' y='196.075'/> +<use x='205.611' xlink:href='#g1-121' y='196.075'/> +<use x='208.049' xlink:href='#g1-99' y='196.075'/> +<use x='212.166' xlink:href='#g1-64' y='196.075'/> +<use x='215.695' xlink:href='#g1-50' y='196.075'/> +<use x='218.341' xlink:href='#g1-46' y='196.075'/> +<use x='219.811' xlink:href='#g1-53' y='196.075'/> +<use x='222.457' xlink:href='#g1-71' y='196.075'/> +<use x='225.986' xlink:href='#g1-104' y='196.075'/> +<use x='228.719' xlink:href='#g1-122' y='196.075'/> +<use x='168.285' xlink:href='#g1-85' y='201.694'/> +<use x='171.917' xlink:href='#g1-98' y='201.694'/> +<use x='174.65' xlink:href='#g1-117' y='201.694'/> +<use x='177.383' xlink:href='#g1-110' y='201.694'/> +<use x='180.116' xlink:href='#g1-116' y='201.694'/> +<use x='182.027' xlink:href='#g1-117' y='201.694'/> +<use x='186.524' xlink:href='#g1-49' y='201.694'/> +<use x='189.17' xlink:href='#g1-56' y='201.694'/> +<use x='191.817' xlink:href='#g1-46' y='201.694'/> +<use x='193.287' xlink:href='#g1-48' y='201.694'/> +<use x='195.933' xlink:href='#g1-52' y='201.694'/> +<use x='198.58' xlink:href='#g1-46' y='201.694'/> +<use x='200.05' xlink:href='#g1-49' y='201.694'/> +<use x='202.696' xlink:href='#g1-44' y='201.694'/> +<use x='205.931' xlink:href='#g1-71' y='201.694'/> +<use x='209.459' xlink:href='#g1-67' y='201.694'/> +<use x='212.841' xlink:href='#g1-67' y='201.694'/> +<use x='217.986' xlink:href='#g1-55' y='201.694'/> +<use x='220.633' xlink:href='#g1-46' y='201.694'/> +<use x='222.103' xlink:href='#g1-51' y='201.694'/> +<use x='224.749' xlink:href='#g1-46' y='201.694'/> +<use x='226.219' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -53.084 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 5.585 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 64.254 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 122.923 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 181.592 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 240.261 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -47.853 342.848)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-50' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 10.816 335.198)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-49' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 69.485 320.166)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 128.154 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-56' y='201.694'/> +<use x='180.675' xlink:href='#g1-50' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 186.823 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-56' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-50' y='201.694'/> +<use x='180.675' xlink:href='#g1-50' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 245.492 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-57' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-50' y='201.694'/> +<use x='183.321' xlink:href='#g1-51' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -42.623 337.748)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-49' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 16.046 334.728)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-49' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 74.715 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-56' y='201.694'/> +<use x='180.675' xlink:href='#g1-51' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 133.384 310.234)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 192.053 292.653)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-55' y='201.694'/> +<use x='175.048' xlink:href='#g1-55' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 250.722 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-56' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-48' y='201.694'/> +<use x='183.321' xlink:href='#g1-57' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -37.392 320.032)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 21.277 306.745)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 79.946 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-55' y='201.694'/> +<use x='180.675' xlink:href='#g1-52' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 138.615 318.958)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-56' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 197.284 325.065)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-57' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 255.953 341.506)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -32.162 326.071)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-55' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 26.507 321.508)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 85.176 253.127)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 143.845 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-57' y='201.694'/> +<use x='180.675' xlink:href='#g1-52' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 202.514 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-50' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-53' y='201.694'/> +<use x='183.321' xlink:href='#g1-50' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 261.183 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-52' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-50' y='201.694'/> +<use x='180.675' xlink:href='#g1-49' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -26.931 334.728)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-49' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 31.738 294.599)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-55' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 90.407 286.949)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-56' y='201.694'/> +<use x='175.048' xlink:href='#g1-53' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 149.076 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-52' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-55' y='201.694'/> +<use x='180.675' xlink:href='#g1-51' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 207.745 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-51' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-56' y='201.694'/> +<use x='183.321' xlink:href='#g1-53' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 266.414 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-57' y='201.694'/> +<use x='180.675' xlink:href='#g1-53' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -21.701 325.736)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-56' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 36.968 321.441)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 95.637 252.657)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-55' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 154.306 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-57' y='201.694'/> +<use x='180.675' xlink:href='#g1-55' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 212.975 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-49' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-55' y='201.694'/> +<use x='183.321' xlink:href='#g1-56' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 271.644 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-52' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-49' y='201.694'/> +<use x='180.675' xlink:href='#g1-56' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 218.205 293.525)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-55' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -16.471 315.603)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-51' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 42.198 311.308)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-57' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 100.867 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-52' y='201.694'/> +<use x='180.675' xlink:href='#g1-56' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 159.536 291.377)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-55' y='201.694'/> +<use x='175.048' xlink:href='#g1-57' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 276.874 341.975)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-51' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -88.536 388.944)'> +<use x='168.285' xlink:href='#g0-82' y='201.694'/> +<use x='174.255' xlink:href='#g0-101' y='201.694'/> +<use x='178.351' xlink:href='#g0-108' y='201.694'/> +<use x='180.551' xlink:href='#g0-97' y='201.694'/> +<use x='184.979' xlink:href='#g0-116' y='201.694'/> +<use x='188.307' xlink:href='#g0-105' y='201.694'/> +<use x='190.507' xlink:href='#g0-118' y='201.694'/> +<use x='194.755' xlink:href='#g0-101' y='201.694'/> +<use x='201.922' xlink:href='#g0-116' y='201.694'/> +<use x='205.25' xlink:href='#g0-105' y='201.694'/> +<use x='207.45' xlink:href='#g0-109' y='201.694'/> +<use x='214.77' xlink:href='#g0-101' y='201.694'/> +<use x='221.937' xlink:href='#g2-40' y='201.694'/> +<use x='225.231' xlink:href='#g2-108' y='201.694'/> +<use x='227.251' xlink:href='#g2-111' y='201.694'/> +<use x='231.25' xlink:href='#g2-119' y='201.694'/> +<use x='236.799' xlink:href='#g2-101' y='201.694'/> +<use x='240.562' xlink:href='#g2-114' y='201.694'/> +<use x='246.277' xlink:href='#g2-105' y='201.694'/> +<use x='248.297' xlink:href='#g2-115' y='201.694'/> +<use x='254.366' xlink:href='#g2-98' y='201.694'/> +<use x='258.974' xlink:href='#g2-101' y='201.694'/> +<use x='262.738' xlink:href='#g2-116' y='201.694'/> +<use x='265.796' xlink:href='#g2-116' y='201.694'/> +<use x='268.854' xlink:href='#g2-101' y='201.694'/> +<use x='272.618' xlink:href='#g2-114' y='201.694'/> +<use x='275.51' xlink:href='#g2-41' y='201.694'/> +</g> +<path d='M136.149 296.672H349.488V279.679H136.149Z' fill='#ffffff'/> +<path d='M136.149 296.672H349.488V279.679H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#e0e0f0'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -33.522 88.465)'> +<use x='185.011' xlink:href='#g2-109' y='201.694'/> +<use x='191.736' xlink:href='#g2-105' y='201.694'/> +</g> +<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='#c2c2e1'/> +<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.56 88.011)'> +<use x='208.137' xlink:href='#g2-116' y='201.694'/> +<use x='211.195' xlink:href='#g2-99' y='201.694'/> +</g> +<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='#a3a3d1'/> +<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.159 88.465)'> +<use x='229.9' xlink:href='#g2-106' y='201.694'/> +<use x='232.155' xlink:href='#g2-101' y='201.694'/> +</g> +<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='#8585c2'/> +<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.958 87.505)'> +<use x='252.061' xlink:href='#g2-115' y='201.694'/> +<use x='255.307' xlink:href='#g2-110' y='201.694'/> +</g> +<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='#6666b3'/> +<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.781 87.505)'> +<use x='274.845' xlink:href='#g2-114' y='201.694'/> +<use x='277.737' xlink:href='#g2-112' y='201.694'/> +</g> +<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='#4747a4'/> +<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.001 88.501)'> +<use x='303.672' xlink:href='#g2-104' y='201.694'/> +<use x='308.045' xlink:href='#g2-111' y='201.694'/> +<use x='312.279' xlink:href='#g2-97' y='201.694'/> +<use x='316.112' xlink:href='#g2-114' y='201.694'/> +<use x='319.004' xlink:href='#g2-100' y='201.694'/> +</g> +<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='#292994'/> +<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.472 88.501)'> +<use x='337.19' xlink:href='#g2-103' y='201.694'/> +<use x='341.424' xlink:href='#g2-108' y='201.694'/> +<use x='343.444' xlink:href='#g2-105' y='201.694'/> +<use x='345.464' xlink:href='#g2-98' y='201.694'/> +<use x='350.072' xlink:href='#g2-99' y='201.694'/> +</g> +<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='#0a0a85'/> +<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.051 88.501)'> +<use x='366.757' xlink:href='#g2-116' y='201.694'/> +<use x='369.815' xlink:href='#g2-98' y='201.694'/> +<use x='374.187' xlink:href='#g2-98' y='201.694'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg new file mode 100644 index 0000000..375ebd2 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg @@ -0,0 +1,683 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip7'> +<path d='M82.148 203.937H434.164V78.691H82.148Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page7'> +<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 33.989)'> +<use x='114.487' xlink:href='#g2-99' y='183.949'/> +<use x='118.25' xlink:href='#g2-102' y='183.949'/> +<use x='120.838' xlink:href='#g2-114' y='183.949'/> +<use x='123.73' xlink:href='#g2-97' y='183.949'/> +<use x='127.798' xlink:href='#g2-99' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 41.401 33.989)'> +<use x='114.487' xlink:href='#g2-101' y='183.949'/> +<use x='118.25' xlink:href='#g2-115' y='183.949'/> +<use x='121.497' xlink:href='#g2-112' y='183.949'/> +<use x='125.634' xlink:href='#g2-114' y='183.949'/> +<use x='128.526' xlink:href='#g2-101' y='183.949'/> +<use x='132.29' xlink:href='#g2-115' y='183.949'/> +<use x='135.536' xlink:href='#g2-115' y='183.949'/> +<use x='138.782' xlink:href='#g2-111' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 103.095 33.989)'> +<use x='114.487' xlink:href='#g2-98' y='183.949'/> +<use x='118.859' xlink:href='#g2-97' y='183.949'/> +<use x='122.692' xlink:href='#g2-114' y='183.949'/> +<use x='125.584' xlink:href='#g2-110' y='183.949'/> +<use x='129.957' xlink:href='#g2-101' y='183.949'/> +<use x='133.72' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 162.903 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-101' y='183.949'/> +<use x='120.271' xlink:href='#g2-97' y='183.949'/> +<use x='124.339' xlink:href='#g2-110' y='183.949'/> +<use x='128.711' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 223.526 33.989)'> +<use x='114.487' xlink:href='#g2-114' y='183.949'/> +<use x='117.379' xlink:href='#g2-101' y='183.949'/> +<use x='121.142' xlink:href='#g2-100' y='183.949'/> +<use x='125.515' xlink:href='#g2-105' y='183.949'/> +<use x='127.535' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 277.054 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-97' y='183.949'/> +<use x='120.34' xlink:href='#g2-114' y='183.949'/> +<use x='123.232' xlink:href='#g2-115' y='183.949'/> +<use x='126.478' xlink:href='#g2-111' y='183.949'/> +<use x='130.712' xlink:href='#g2-110' y='183.949'/> +<use x='135.085' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 21.624)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.688)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.999)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -72.311)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.622)'> +<use x='114.487' xlink:href='#g1-50' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<path clip-path='url(#clip7)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M93.18 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M91.184 141.316H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M93.18 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M91.184 141.316H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M151.848 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M151.848 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M210.516 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M208.523 141.316H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M210.516 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M208.523 141.316H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M269.184 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M267.191 141.316H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M269.184 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M267.191 141.316H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M327.856 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M325.859 141.316H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M327.856 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M325.859 141.316H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M386.524 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M384.531 141.316H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M386.524 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip7)' d='M384.531 141.316H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M96.789 203.937H100.027V94.222H96.789ZM155.457 203.937H158.695V78.691H155.457ZM214.129 203.937H217.363V138.246H214.129ZM272.797 203.937H276.035V154.652H272.797ZM331.465 203.937H334.703V129.793H331.465ZM390.133 203.937H393.371V138.808H390.133Z' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M96.789 203.937H100.027V94.222H96.789ZM155.457 203.937H158.695V78.691H155.457ZM214.129 203.937H217.363V138.246H214.129ZM272.797 203.937H276.035V154.652H272.797ZM331.465 203.937H334.703V129.793H331.465ZM390.133 203.937H393.371V138.808H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M98.41 94.222V94.222' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M96.414 94.223H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M98.41 94.222V94.222' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M96.414 94.223H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M157.078 78.691V78.691' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M155.086 78.691H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M157.078 78.691V78.691' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M155.086 78.691H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M215.746 138.246V138.246' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M213.754 138.246H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M215.746 138.246V138.246' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M213.754 138.246H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M274.414 154.652V154.652' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M272.422 154.652H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M274.414 154.652V154.652' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M272.422 154.652H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M333.086 129.793V129.793' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M331.09 129.793H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M333.086 129.793V129.793' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M331.09 129.793H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M391.754 138.808V138.808' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M389.762 138.808H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M391.754 138.808V138.808' fill='#e1c2e1'/> +<path clip-path='url(#clip7)' d='M389.762 138.808H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M102.02 203.937H105.258V115.828H102.02ZM160.688 203.937H163.926V108.187H160.688ZM219.359 203.937H222.594V139.625H219.359ZM278.027 203.937H281.266V141.379H278.027ZM336.695 203.937H339.934V137.246H336.695ZM395.363 203.937H398.602V122.09H395.363Z' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M102.02 203.937H105.258V115.828H102.02ZM160.688 203.937H163.926V108.187H160.688ZM219.359 203.937H222.594V139.625H219.359ZM278.027 203.937H281.266V141.379H278.027ZM336.695 203.937H339.934V137.246H336.695ZM395.363 203.937H398.602V122.09H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M103.641 115.828V115.828' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M101.644 115.828H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M103.641 115.828V115.828' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M101.644 115.828H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M162.309 108.187V108.187' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M160.316 108.188H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M162.309 108.187V108.187' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M160.316 108.188H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M220.977 139.625V139.625' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M218.984 139.625H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M220.977 139.625V139.625' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M218.984 139.625H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M279.645 141.379V141.379' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M277.652 141.379H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M279.645 141.379V141.379' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M277.652 141.379H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M338.317 137.246V137.246' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M336.32 137.246H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M338.317 137.246V137.246' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M336.32 137.246H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M396.984 122.09V122.09' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M394.992 122.09H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M396.984 122.09V122.09' fill='#d1a3d1'/> +<path clip-path='url(#clip7)' d='M394.992 122.09H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M107.25 203.937H110.488V123.469H107.25ZM165.918 203.937H169.156V112.133H165.918ZM224.59 203.937H227.824V140.187H224.59ZM283.258 203.937H286.496V140.312H283.258ZM341.926 203.937H345.164V137.933H341.926ZM400.594 203.937H403.832V126.347H400.594Z' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M107.25 203.937H110.488V123.469H107.25ZM165.918 203.937H169.156V112.133H165.918ZM224.59 203.937H227.824V140.187H224.59ZM283.258 203.937H286.496V140.312H283.258ZM341.926 203.937H345.164V137.933H341.926ZM400.594 203.937H403.832V126.347H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M108.871 123.469V123.469' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M106.875 123.469H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M108.871 123.469V123.469' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M106.875 123.469H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M167.539 112.133V112.133' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M165.547 112.133H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M167.539 112.133V112.133' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M165.547 112.133H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M226.207 140.187V140.187' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M224.215 140.187H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M226.207 140.187V140.187' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M224.215 140.187H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M284.875 140.312V140.312' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M282.883 140.312H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M284.875 140.312V140.312' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M282.883 140.312H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M343.547 137.933V137.933' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M341.551 137.934H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M343.547 137.933V137.933' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M341.551 137.934H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M402.215 126.347V126.347' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M400.223 126.347H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M402.215 126.347V126.347' fill='#c285c2'/> +<path clip-path='url(#clip7)' d='M400.223 126.347H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M112.481 203.937H115.719V139H112.481ZM171.149 203.937H174.387V143.82H171.149ZM229.82 203.937H233.055V141.316H229.82ZM288.488 203.937H291.727V133.176H288.488ZM347.156 203.937H350.395V140H347.156ZM405.824 203.937H409.063V133.176H405.824Z' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M112.481 203.937H115.719V139H112.481ZM171.149 203.937H174.387V143.82H171.149ZM229.82 203.937H233.055V141.316H229.82ZM288.488 203.937H291.727V133.176H288.488ZM347.156 203.937H350.395V140H347.156ZM405.824 203.937H409.063V133.176H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M114.098 139V139' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M112.105 139H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M114.098 139V139' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M112.105 139H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M172.77 143.82V143.82' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M170.777 143.82H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M172.77 143.82V143.82' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M170.777 143.82H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M231.438 141.316V141.316' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M229.445 141.316H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M231.438 141.316V141.316' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M229.445 141.316H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M290.106 133.176V133.176' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M288.113 133.176H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M290.106 133.176V133.176' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M288.113 133.176H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M348.777 140V140' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M346.781 140H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M348.777 140V140' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M346.781 140H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M407.445 133.176V133.176' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M405.453 133.176H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M407.445 133.176V133.176' fill='#b366b3'/> +<path clip-path='url(#clip7)' d='M405.453 133.176H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M117.711 203.937H120.949V111.32H117.711ZM176.379 203.937H179.617V78.691H176.379ZM235.051 203.937H238.285V139.75H235.051ZM293.719 203.937H296.957V125.785H293.719ZM352.387 203.937H355.625V124.906H352.387ZM411.055 203.937H414.293V132.359H411.055Z' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M117.711 203.937H120.949V111.32H117.711ZM176.379 203.937H179.617V78.691H176.379ZM235.051 203.937H238.285V139.75H235.051ZM293.719 203.937H296.957V125.785H293.719ZM352.387 203.937H355.625V124.906H352.387ZM411.055 203.937H414.293V132.359H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M119.328 111.32V111.32' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M117.336 111.32H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M119.328 111.32V111.32' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M117.336 111.32H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M178 78.691V78.691' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M176.008 78.691H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M178 78.691V78.691' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M176.008 78.691H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M236.668 139.75V139.75' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M234.676 139.75H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M236.668 139.75V139.75' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M234.676 139.75H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M295.336 125.785V125.785' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M293.344 125.785H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M295.336 125.785V125.785' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M293.344 125.785H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M354.008 124.906V124.906' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M352.012 124.906H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M354.008 124.906V124.906' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M352.012 124.906H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M412.676 132.359V132.359' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M410.684 132.359H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M412.676 132.359V132.359' fill='#a447a4'/> +<path clip-path='url(#clip7)' d='M410.684 132.359H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M122.941 203.937H126.18V143.57H122.941ZM181.609 203.937H184.848V154.34H181.609ZM240.281 203.937H243.516V141.504H240.281ZM298.949 203.937H302.188V133.363H298.949ZM357.617 203.937H360.856V139.937H357.617ZM416.285 203.937H419.524V133.426H416.285Z' fill='#942994'/> +<path clip-path='url(#clip7)' d='M122.941 203.937H126.18V143.57H122.941ZM181.609 203.937H184.848V154.34H181.609ZM240.281 203.937H243.516V141.504H240.281ZM298.949 203.937H302.188V133.363H298.949ZM357.617 203.937H360.856V139.937H357.617ZM416.285 203.937H419.524V133.426H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M124.559 143.57V143.57' fill='#942994'/> +<path clip-path='url(#clip7)' d='M122.566 143.571H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M124.559 143.57V143.57' fill='#942994'/> +<path clip-path='url(#clip7)' d='M122.566 143.571H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M183.231 154.34V154.34' fill='#942994'/> +<path clip-path='url(#clip7)' d='M181.238 154.34H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M183.231 154.34V154.34' fill='#942994'/> +<path clip-path='url(#clip7)' d='M181.238 154.34H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M241.899 141.504V141.504' fill='#942994'/> +<path clip-path='url(#clip7)' d='M239.906 141.504H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M241.899 141.504V141.504' fill='#942994'/> +<path clip-path='url(#clip7)' d='M239.906 141.504H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M300.567 133.363V133.363' fill='#942994'/> +<path clip-path='url(#clip7)' d='M298.574 133.363H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M300.567 133.363V133.363' fill='#942994'/> +<path clip-path='url(#clip7)' d='M298.574 133.363H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M359.238 139.937V139.937' fill='#942994'/> +<path clip-path='url(#clip7)' d='M357.242 139.938H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M359.238 139.937V139.937' fill='#942994'/> +<path clip-path='url(#clip7)' d='M357.242 139.938H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M417.906 133.426V133.426' fill='#942994'/> +<path clip-path='url(#clip7)' d='M415.914 133.426H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M417.906 133.426V133.426' fill='#942994'/> +<path clip-path='url(#clip7)' d='M415.914 133.426H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M128.172 203.937H131.41V118.457H128.172ZM186.84 203.937H190.078V113.699H186.84ZM245.512 203.937H248.746V140.062H245.512ZM304.18 203.937H307.418V133.613H304.18ZM362.848 203.937H366.086V97.101H362.848ZM421.516 203.937H424.754V137.371H421.516Z' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M128.172 203.937H131.41V118.457H128.172ZM186.84 203.937H190.078V113.699H186.84ZM245.512 203.937H248.746V140.062H245.512ZM304.18 203.937H307.418V133.613H304.18ZM362.848 203.937H366.086V97.101H362.848ZM421.516 203.937H424.754V137.371H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M129.789 118.457V118.457' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M127.797 118.457H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M129.789 118.457V118.457' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M127.797 118.457H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M188.461 113.699V113.699' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M186.469 113.7H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M188.461 113.699V113.699' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M186.469 113.7H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M247.129 140.062V140.062' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M245.137 140.063H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M247.129 140.062V140.062' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M245.137 140.063H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M305.797 133.613V133.613' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M303.804 133.614H307.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M305.797 133.613V133.613' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M303.804 133.614H307.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M364.469 97.101V97.101' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M362.473 97.102H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M364.469 97.101V97.101' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M362.473 97.102H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M423.137 137.371V137.371' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M421.144 137.371H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip7)' d='M423.137 137.371V137.371' fill='#850a85'/> +<path clip-path='url(#clip7)' d='M421.144 137.371H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -89.137 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -30.468 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 28.201 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 86.87 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 145.539 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 204.208 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -83.906 202.685)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -25.237 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-50' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-48' y='183.949'/> +<use x='126.877' xlink:href='#g1-55' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 33.432 246.709)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 92.101 263.116)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 150.77 238.255)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 209.439 247.273)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -78.676 224.29)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -20.007 216.65)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 38.662 248.087)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 97.331 249.84)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 156 245.707)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 214.669 230.552)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-51' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -73.445 231.93)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -14.776 220.595)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 43.893 248.65)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 102.562 248.776)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 161.231 246.396)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 219.9 234.811)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -68.215 247.46)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -9.546 252.282)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 49.123 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 107.792 241.637)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 166.461 248.462)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 225.13 241.637)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -62.984 219.781)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -4.315 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-52' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-51' y='183.949'/> +<use x='126.877' xlink:href='#g1-54' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 54.354 248.212)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 113.023 234.247)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 171.692 233.37)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 230.361 240.822)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -57.754 252.032)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 0.915 262.803)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 59.584 249.965)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 118.253 241.824)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 176.922 248.4)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 235.591 241.887)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -52.524 226.92)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-51' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 6.145 222.161)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 64.814 248.525)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 123.483 242.075)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 182.152 205.566)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 240.821 245.832)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -124.589 307.697)'> +<use x='114.487' xlink:href='#g0-82' y='183.949'/> +<use x='120.457' xlink:href='#g0-101' y='183.949'/> +<use x='124.553' xlink:href='#g0-108' y='183.949'/> +<use x='126.753' xlink:href='#g0-97' y='183.949'/> +<use x='131.181' xlink:href='#g0-116' y='183.949'/> +<use x='134.509' xlink:href='#g0-105' y='183.949'/> +<use x='136.709' xlink:href='#g0-118' y='183.949'/> +<use x='140.957' xlink:href='#g0-101' y='183.949'/> +<use x='148.124' xlink:href='#g0-114' y='183.949'/> +<use x='151.272' xlink:href='#g0-115' y='183.949'/> +<use x='154.805' xlink:href='#g0-115' y='183.949'/> +<use x='161.409' xlink:href='#g2-40' y='183.949'/> +<use x='164.702' xlink:href='#g2-108' y='183.949'/> +<use x='166.722' xlink:href='#g2-111' y='183.949'/> +<use x='170.721' xlink:href='#g2-119' y='183.949'/> +<use x='176.27' xlink:href='#g2-101' y='183.949'/> +<use x='180.034' xlink:href='#g2-114' y='183.949'/> +<use x='185.749' xlink:href='#g2-105' y='183.949'/> +<use x='187.769' xlink:href='#g2-115' y='183.949'/> +<use x='193.838' xlink:href='#g2-98' y='183.949'/> +<use x='198.446' xlink:href='#g2-101' y='183.949'/> +<use x='202.209' xlink:href='#g2-116' y='183.949'/> +<use x='205.267' xlink:href='#g2-116' y='183.949'/> +<use x='208.325' xlink:href='#g2-101' y='183.949'/> +<use x='212.089' xlink:href='#g2-114' y='183.949'/> +<use x='214.981' xlink:href='#g2-41' y='183.949'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg new file mode 100644 index 0000000..cb2bbc8 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg @@ -0,0 +1,854 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='196.567pt' version='1.1' viewBox='106.737 54.996 381.623 196.567' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip8'> +<path d='M135.949 203.938H487.961V78.692H135.949Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/> +<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/> +<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/> +<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/> +<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/> +<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/> +<path d='M2.002 -3.457H1.519L0.149 0H0.558L0.946 -0.986H2.461L2.849 0H3.372L2.002 -3.457ZM1.709 -3.078L2.336 -1.28H1.071L1.709 -3.078Z' id='g1-65'/> +<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/> +<path d='M0.488 -3.457V0H1.903C2.8 0 3.522 -0.757 3.522 -1.699C3.522 -2.675 2.795 -3.457 1.903 -3.457H0.488ZM0.976 -0.294V-3.163H1.768C2.451 -3.163 3.034 -2.62 3.034 -1.704C3.034 -0.777 2.426 -0.294 1.768 -0.294H0.976Z' id='g1-68'/> +<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/> +<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/> +<path d='M2.775 -1.729C2.715 -1.579 2.356 -0.702 2.306 -0.493H2.301C2.267 -0.638 2.037 -1.21 1.988 -1.34L1.131 -3.457H0.523V0H0.941V-3.059H0.946C0.986 -2.884 1.245 -2.227 1.27 -2.172L2.102 -0.105H2.496L3.238 -1.938C3.238 -1.943 3.582 -2.79 3.666 -3.064H3.671V0H4.09V-3.457H3.477L2.775 -1.729Z' id='g1-77'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M2.361 -2.212H1.958C1.554 -1.26 1.275 -0.618 1.255 -0.314C1.245 -0.453 1.156 -0.702 1.066 -0.936C0.986 -1.136 0.907 -1.335 0.817 -1.529L0.503 -2.212H0.075L1.106 0C1.046 0.144 0.946 0.374 0.917 0.438C0.812 0.648 0.742 0.717 0.608 0.717C0.588 0.717 0.403 0.717 0.189 0.628L0.219 0.976C0.264 0.986 0.448 1.016 0.603 1.016C0.802 1.016 0.981 0.941 1.191 0.463L2.361 -2.212Z' id='g1-121'/> +<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page8'> +<path d='M194.617 212.793V203.938M253.285 212.793V203.938M311.953 212.793V203.938M370.625 212.793V203.938M429.293 212.793V203.938M194.617 69.836V78.692M253.285 69.836V78.692M311.953 69.836V78.692M370.625 69.836V78.692M429.293 69.836V78.692' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 208.192V203.938M223.953 208.192V203.938M282.621 208.192V203.938M341.289 208.192V203.938M399.957 208.192V203.938M458.629 208.192V203.938M165.281 74.442V78.692M223.953 74.442V78.692M282.621 74.442V78.692M341.289 74.442V78.692M399.957 74.442V78.692M458.629 74.442V78.692' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 203.938H140.199M135.949 172.625H140.199M135.949 141.317H140.199M135.949 110.004H140.199M135.949 78.692H140.199M487.961 203.938H483.711M487.961 172.625H483.711M487.961 141.317H483.711M487.961 110.004H483.711M487.961 78.692H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 203.938V78.692H487.961V203.938H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 59.571)'> +<use x='168.285' xlink:href='#g2-97' y='158.367'/> +<use x='172.353' xlink:href='#g2-108' y='158.367'/> +<use x='174.373' xlink:href='#g2-108' y='158.367'/> +<use x='176.393' xlink:href='#g2-111' y='158.367'/> +<use x='180.863' xlink:href='#g2-99' y='158.367'/> +<use x='184.627' xlink:href='#g2-45' y='158.367'/> +<use x='187.449' xlink:href='#g2-116' y='158.367'/> +<use x='190.507' xlink:href='#g2-101' y='158.367'/> +<use x='194.271' xlink:href='#g2-115' y='158.367'/> +<use x='197.517' xlink:href='#g2-116' y='158.367'/> +<use x='200.575' xlink:href='#g2-49' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 36.532 59.571)'> +<use x='168.285' xlink:href='#g2-97' y='158.367'/> +<use x='172.353' xlink:href='#g2-108' y='158.367'/> +<use x='174.373' xlink:href='#g2-108' y='158.367'/> +<use x='176.393' xlink:href='#g2-111' y='158.367'/> +<use x='180.863' xlink:href='#g2-99' y='158.367'/> +<use x='184.627' xlink:href='#g2-45' y='158.367'/> +<use x='187.449' xlink:href='#g2-116' y='158.367'/> +<use x='190.507' xlink:href='#g2-101' y='158.367'/> +<use x='194.271' xlink:href='#g2-115' y='158.367'/> +<use x='197.517' xlink:href='#g2-116' y='158.367'/> +<use x='200.575' xlink:href='#g2-78' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 94.98 59.571)'> +<use x='168.285' xlink:href='#g2-115' y='158.367'/> +<use x='171.531' xlink:href='#g2-104' y='158.367'/> +<use x='175.904' xlink:href='#g2-54' y='158.367'/> +<use x='180.138' xlink:href='#g2-98' y='158.367'/> +<use x='184.746' xlink:href='#g2-101' y='158.367'/> +<use x='188.509' xlink:href='#g2-110' y='158.367'/> +<use x='192.882' xlink:href='#g2-99' y='158.367'/> +<use x='196.646' xlink:href='#g2-104' y='158.367'/> +<use x='201.018' xlink:href='#g2-78' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 153.649 59.571)'> +<use x='168.285' xlink:href='#g2-115' y='158.367'/> +<use x='171.531' xlink:href='#g2-104' y='158.367'/> +<use x='175.904' xlink:href='#g2-56' y='158.367'/> +<use x='180.138' xlink:href='#g2-98' y='158.367'/> +<use x='184.746' xlink:href='#g2-101' y='158.367'/> +<use x='188.509' xlink:href='#g2-110' y='158.367'/> +<use x='192.882' xlink:href='#g2-99' y='158.367'/> +<use x='196.646' xlink:href='#g2-104' y='158.367'/> +<use x='201.018' xlink:href='#g2-78' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 207.225 59.571)'> +<use x='168.285' xlink:href='#g2-120' y='158.367'/> +<use x='172.187' xlink:href='#g2-109' y='158.367'/> +<use x='178.912' xlink:href='#g2-97' y='158.367'/> +<use x='182.98' xlink:href='#g2-108' y='158.367'/> +<use x='185' xlink:href='#g2-108' y='158.367'/> +<use x='187.02' xlink:href='#g2-111' y='158.367'/> +<use x='191.49' xlink:href='#g2-99' y='158.367'/> +<use x='195.254' xlink:href='#g2-45' y='158.367'/> +<use x='198.076' xlink:href='#g2-116' y='158.367'/> +<use x='201.134' xlink:href='#g2-101' y='158.367'/> +<use x='204.898' xlink:href='#g2-115' y='158.367'/> +<use x='208.144' xlink:href='#g2-116' y='158.367'/> +<use x='211.202' xlink:href='#g2-78' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 263.494 59.571)'> +<use x='168.285' xlink:href='#g2-99' y='158.367'/> +<use x='172.049' xlink:href='#g2-97' y='158.367'/> +<use x='176.117' xlink:href='#g2-99' y='158.367'/> +<use x='179.88' xlink:href='#g2-104' y='158.367'/> +<use x='184.253' xlink:href='#g2-101' y='158.367'/> +<use x='188.017' xlink:href='#g2-45' y='158.367'/> +<use x='190.839' xlink:href='#g2-115' y='158.367'/> +<use x='194.086' xlink:href='#g2-99' y='158.367'/> +<use x='197.849' xlink:href='#g2-114' y='158.367'/> +<use x='200.741' xlink:href='#g2-97' y='158.367'/> +<use x='204.81' xlink:href='#g2-116' y='158.367'/> +<use x='207.868' xlink:href='#g2-99' y='158.367'/> +<use x='211.631' xlink:href='#g2-104' y='158.367'/> +<use x='216.004' xlink:href='#g2-78' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 47.205)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-120' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 15.894)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-53' y='158.367'/> +<use x='175.048' xlink:href='#g1-120' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -15.418)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-120' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -46.729)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-53' y='158.367'/> +<use x='175.048' xlink:href='#g1-120' y='158.367'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -78.041)'> +<use x='168.285' xlink:href='#g1-50' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-120' y='158.367'/> +</g> +<path clip-path='url(#clip8)' d='M135.949 141.317H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M145.356 203.938H148.594V141.317H145.356ZM204.028 203.938H207.266V141.317H204.028ZM262.695 203.938H265.934V141.317H262.695ZM321.363 203.938H324.602V141.317H321.363ZM380.031 203.938H383.27V141.317H380.031ZM438.703 203.938H441.942V141.317H438.703Z' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M145.356 203.938H148.594V141.317H145.356ZM204.028 203.938H207.266V141.317H204.028ZM262.695 203.938H265.934V141.317H262.695ZM321.363 203.938H324.602V141.317H321.363ZM380.031 203.938H383.27V141.317H380.031ZM438.703 203.938H441.942V141.317H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M146.977 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M144.984 141.317H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M146.977 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M144.984 141.317H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M205.645 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M203.652 141.317H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M205.645 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M203.652 141.317H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M264.313 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M262.32 141.317H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M264.313 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M262.32 141.317H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M322.984 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M320.992 141.317H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M322.984 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M320.992 141.317H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M381.652 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M379.66 141.317H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M381.652 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M379.66 141.317H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M440.32 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M438.328 141.317H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M440.32 141.317V141.317' fill='#f0e0f0'/> +<path clip-path='url(#clip8)' d='M438.328 141.317H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M150.586 203.938H153.824V137.809H150.586ZM209.258 203.938H212.496V144.196H209.258ZM267.926 203.938H271.164V140.563H267.926ZM326.594 203.938H329.832V141.754H326.594ZM385.262 203.938H388.5V188.406H385.262ZM443.934 203.938H447.172V110.754H443.934Z' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M150.586 203.938H153.824V137.809H150.586ZM209.258 203.938H212.496V144.196H209.258ZM267.926 203.938H271.164V140.563H267.926ZM326.594 203.938H329.832V141.754H326.594ZM385.262 203.938H388.5V188.406H385.262ZM443.934 203.938H447.172V110.754H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M152.207 137.809V137.809' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M150.215 137.809H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M152.207 137.809V137.809' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M150.215 137.809H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M210.875 144.196V144.196' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M208.883 144.195H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M210.875 144.196V144.196' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M208.883 144.195H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M269.543 140.563V140.563' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M267.551 140.562H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M269.543 140.563V140.563' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M267.551 140.562H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M328.215 141.754V141.754' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M326.223 141.754H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M328.215 141.754V141.754' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M326.223 141.754H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M386.883 188.406V188.406' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M384.891 188.406H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M386.883 188.406V188.406' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M384.891 188.406H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M445.551 110.754V110.754' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M443.559 110.754H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M445.551 110.754V110.754' fill='#e1c2e1'/> +<path clip-path='url(#clip8)' d='M443.559 110.754H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M155.817 203.938H159.055V140.313H155.817ZM214.488 203.938H217.727V147.453H214.488ZM273.156 203.938H276.395V139.625H273.156ZM331.824 203.938H335.063V130.043H331.824ZM390.492 203.938H393.731V170.809H390.492ZM449.164 203.938H452.402V120.024H449.164Z' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M155.817 203.938H159.055V140.313H155.817ZM214.488 203.938H217.727V147.453H214.488ZM273.156 203.938H276.395V139.625H273.156ZM331.824 203.938H335.063V130.043H331.824ZM390.492 203.938H393.731V170.809H390.492ZM449.164 203.938H452.402V120.024H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M157.438 140.313V140.313' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M155.445 140.313H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M157.438 140.313V140.313' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M155.445 140.313H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M216.106 147.453V147.453' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M214.113 147.453H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M216.106 147.453V147.453' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M214.113 147.453H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M274.774 139.625V139.625' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M272.781 139.625H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M274.774 139.625V139.625' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M272.781 139.625H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M333.445 130.043V130.043' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M331.453 130.043H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M333.445 130.043V130.043' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M331.453 130.043H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M392.113 170.809V170.809' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M390.121 170.808H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M392.113 170.809V170.809' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M390.121 170.808H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M450.781 120.024V120.024' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M448.789 120.023H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M450.781 120.024V120.024' fill='#d1a3d1'/> +<path clip-path='url(#clip8)' d='M448.789 120.023H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M161.047 203.938H164.285V137.559H161.047ZM219.719 203.938H222.957V144.383H219.719ZM278.387 203.938H281.625V131.36H278.387ZM337.055 203.938H340.293V128.164H337.055ZM395.723 203.938H398.961V138.121H395.723ZM454.395 203.938H457.633V137.559H454.395Z' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M161.047 203.938H164.285V137.559H161.047ZM219.719 203.938H222.957V144.383H219.719ZM278.387 203.938H281.625V131.36H278.387ZM337.055 203.938H340.293V128.164H337.055ZM395.723 203.938H398.961V138.121H395.723ZM454.395 203.938H457.633V137.559H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M162.668 137.559V137.559' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M160.676 137.558H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M162.668 137.559V137.559' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M160.676 137.558H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M221.336 144.383V144.383' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M219.344 144.382H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M221.336 144.383V144.383' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M219.344 144.382H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M280.004 131.36V131.36' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M278.012 131.36H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M280.004 131.36V131.36' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M278.012 131.36H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M338.676 128.164V128.164' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M336.684 128.164H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M338.676 128.164V128.164' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M336.684 128.164H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M397.344 138.121V138.121' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M395.352 138.121H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M397.344 138.121V138.121' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M395.352 138.121H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M456.012 137.559V137.559' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M454.02 137.558H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M456.012 137.559V137.559' fill='#c285c2'/> +<path clip-path='url(#clip8)' d='M454.02 137.558H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M166.278 203.938H169.516V126.723H166.278ZM224.949 203.938H228.188V141.629H224.949ZM283.617 203.938H286.856V104.055H283.617ZM342.285 203.938H345.524V122.84H342.285ZM400.953 203.938H404.192V186.215H400.953ZM459.625 203.938H462.863V140.188H459.625Z' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M166.278 203.938H169.516V126.723H166.278ZM224.949 203.938H228.188V141.629H224.949ZM283.617 203.938H286.856V104.055H283.617ZM342.285 203.938H345.524V122.84H342.285ZM400.953 203.938H404.192V186.215H400.953ZM459.625 203.938H462.863V140.188H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M167.899 126.723V126.723' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M165.906 126.723H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M167.899 126.723V126.723' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M165.906 126.723H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M226.567 141.629V141.629' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M224.574 141.629H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M226.567 141.629V141.629' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M224.574 141.629H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M285.234 104.055V104.055' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M283.242 104.055H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M285.234 104.055V104.055' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M283.242 104.055H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M343.906 122.84V122.84' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M341.914 122.84H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M343.906 122.84V122.84' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M341.914 122.84H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M402.574 186.215V186.215' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M400.582 186.215H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M402.574 186.215V186.215' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M400.582 186.215H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M461.242 140.188V140.188' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M459.25 140.188H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M461.242 140.188V140.188' fill='#b366b3'/> +<path clip-path='url(#clip8)' d='M459.25 140.188H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M171.508 203.938H174.746V115.828H171.508ZM230.18 203.938H233.414V91.215H230.18ZM288.848 203.938H292.086V95.977H288.848ZM347.516 203.938H350.754V78.692H347.516ZM406.184 203.938H409.422V167.68H406.184ZM464.856 203.938H468.094V130.856H464.856Z' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M171.508 203.938H174.746V115.828H171.508ZM230.18 203.938H233.414V91.215H230.18ZM288.848 203.938H292.086V95.977H288.848ZM347.516 203.938H350.754V78.692H347.516ZM406.184 203.938H409.422V167.68H406.184ZM464.856 203.938H468.094V130.856H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M173.129 115.828V115.828' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M171.137 115.828H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M173.129 115.828V115.828' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M171.137 115.828H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M231.797 91.215V91.215' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M229.805 91.215H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M231.797 91.215V91.215' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M229.805 91.215H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M290.465 95.977V95.977' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M288.473 95.977H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M290.465 95.977V95.977' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M288.473 95.977H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M349.137 78.692V78.692' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M347.145 78.691H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M349.137 78.692V78.692' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M347.145 78.691H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M407.805 167.68V167.68' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M405.813 167.68H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M407.805 167.68V167.68' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M405.813 167.68H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M466.473 130.856V130.856' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M464.481 130.856H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M466.473 130.856V130.856' fill='#a447a4'/> +<path clip-path='url(#clip8)' d='M464.481 130.856H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M176.738 203.938H179.977V126.973H176.738ZM235.41 203.938H238.645V141.754H235.41ZM294.078 203.938H297.317V104.18H294.078ZM352.746 203.938H355.984V122.903H352.746ZM411.414 203.938H414.652V186.278H411.414ZM470.086 203.938H473.324V140.688H470.086Z' fill='#942994'/> +<path clip-path='url(#clip8)' d='M176.738 203.938H179.977V126.973H176.738ZM235.41 203.938H238.645V141.754H235.41ZM294.078 203.938H297.317V104.18H294.078ZM352.746 203.938H355.984V122.903H352.746ZM411.414 203.938H414.652V186.278H411.414ZM470.086 203.938H473.324V140.688H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M178.36 126.973V126.973' fill='#942994'/> +<path clip-path='url(#clip8)' d='M176.367 126.972H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M178.36 126.973V126.973' fill='#942994'/> +<path clip-path='url(#clip8)' d='M176.367 126.972H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M237.027 141.754V141.754' fill='#942994'/> +<path clip-path='url(#clip8)' d='M235.035 141.754H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M237.027 141.754V141.754' fill='#942994'/> +<path clip-path='url(#clip8)' d='M235.035 141.754H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M295.695 104.18V104.18' fill='#942994'/> +<path clip-path='url(#clip8)' d='M293.703 104.179H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M295.695 104.18V104.18' fill='#942994'/> +<path clip-path='url(#clip8)' d='M293.703 104.179H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M354.367 122.903V122.903' fill='#942994'/> +<path clip-path='url(#clip8)' d='M352.375 122.903H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M354.367 122.903V122.903' fill='#942994'/> +<path clip-path='url(#clip8)' d='M352.375 122.903H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M413.035 186.278V186.278' fill='#942994'/> +<path clip-path='url(#clip8)' d='M411.043 186.277H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M413.035 186.278V186.278' fill='#942994'/> +<path clip-path='url(#clip8)' d='M411.043 186.277H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M471.703 140.688V140.688' fill='#942994'/> +<path clip-path='url(#clip8)' d='M469.711 140.688H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M471.703 140.688V140.688' fill='#942994'/> +<path clip-path='url(#clip8)' d='M469.711 140.688H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M416.645 203.938H419.883V157.973H416.645ZM181.969 203.938H185.207V135.051H181.969ZM240.641 203.938H243.875V142.129H240.641ZM299.309 203.938H302.547V134.676H299.309ZM357.977 203.938H361.215V140.25H357.977ZM475.317 203.938H478.555V131.235H475.317Z' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M416.645 203.938H419.883V157.973H416.645ZM181.969 203.938H185.207V135.051H181.969ZM240.641 203.938H243.875V142.129H240.641ZM299.309 203.938H302.547V134.676H299.309ZM357.977 203.938H361.215V140.25H357.977ZM475.317 203.938H478.555V131.235H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M418.266 157.973V157.973' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M416.274 157.973H420.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M418.266 157.973V157.973' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M416.274 157.973H420.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M183.59 135.051V135.051' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M181.598 135.051H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M183.59 135.051V135.051' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M181.598 135.051H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M242.258 142.129V142.129' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M240.266 142.129H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M242.258 142.129V142.129' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M240.266 142.129H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M300.926 134.676V134.676' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M298.933 134.676H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M300.926 134.676V134.676' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M298.933 134.676H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M359.598 140.25V140.25' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M357.606 140.25H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M359.598 140.25V140.25' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M357.606 140.25H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M476.934 131.235V131.235' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M474.942 131.235H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M476.934 131.235V131.235' fill='#850a85'/> +<path clip-path='url(#clip8)' d='M474.942 131.235H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip8)' d='M418.387 251.164H487.762V229.188H418.387Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 253.422 88.837)'> +<use x='168.285' xlink:href='#g1-114' y='147.13'/> +<use x='170.092' xlink:href='#g1-53' y='147.13'/> +<use x='172.739' xlink:href='#g1-97' y='147.13'/> +<use x='175.281' xlink:href='#g1-45' y='147.13'/> +<use x='177.046' xlink:href='#g1-52' y='147.13'/> +<use x='179.692' xlink:href='#g1-120' y='147.13'/> +<use x='182.131' xlink:href='#g1-108' y='147.13'/> +<use x='183.393' xlink:href='#g1-97' y='147.13'/> +<use x='185.789' xlink:href='#g1-114' y='147.13'/> +<use x='187.596' xlink:href='#g1-103' y='147.13'/> +<use x='190.243' xlink:href='#g1-101' y='147.13'/> +<use x='192.595' xlink:href='#g1-44' y='147.13'/> +<use x='195.83' xlink:href='#g1-49' y='147.13'/> +<use x='198.476' xlink:href='#g1-50' y='147.13'/> +<use x='201.122' xlink:href='#g1-56' y='147.13'/> +<use x='203.769' xlink:href='#g1-71' y='147.13'/> +<use x='207.297' xlink:href='#g1-98' y='147.13'/> +<use x='168.285' xlink:href='#g1-49' y='152.749'/> +<use x='170.931' xlink:href='#g1-54' y='152.749'/> +<use x='173.578' xlink:href='#g1-45' y='152.749'/> +<use x='175.342' xlink:href='#g1-99' y='152.749'/> +<use x='177.694' xlink:href='#g1-111' y='152.749'/> +<use x='180.193' xlink:href='#g1-114' y='152.749'/> +<use x='182.001' xlink:href='#g1-101' y='152.749'/> +<use x='186.118' xlink:href='#g1-65' y='152.749'/> +<use x='189.646' xlink:href='#g1-77' y='152.749'/> +<use x='194.264' xlink:href='#g1-68' y='152.749'/> +<use x='199.851' xlink:href='#g1-69' y='152.749'/> +<use x='203.025' xlink:href='#g1-112' y='152.749'/> +<use x='205.611' xlink:href='#g1-121' y='152.749'/> +<use x='208.049' xlink:href='#g1-99' y='152.749'/> +<use x='212.166' xlink:href='#g1-64' y='152.749'/> +<use x='215.695' xlink:href='#g1-50' y='152.749'/> +<use x='218.341' xlink:href='#g1-46' y='152.749'/> +<use x='219.811' xlink:href='#g1-53' y='152.749'/> +<use x='222.457' xlink:href='#g1-71' y='152.749'/> +<use x='225.986' xlink:href='#g1-104' y='152.749'/> +<use x='228.719' xlink:href='#g1-122' y='152.749'/> +<use x='168.285' xlink:href='#g1-85' y='158.367'/> +<use x='171.917' xlink:href='#g1-98' y='158.367'/> +<use x='174.65' xlink:href='#g1-117' y='158.367'/> +<use x='177.383' xlink:href='#g1-110' y='158.367'/> +<use x='180.116' xlink:href='#g1-116' y='158.367'/> +<use x='182.027' xlink:href='#g1-117' y='158.367'/> +<use x='186.524' xlink:href='#g1-49' y='158.367'/> +<use x='189.17' xlink:href='#g1-56' y='158.367'/> +<use x='191.817' xlink:href='#g1-46' y='158.367'/> +<use x='193.287' xlink:href='#g1-48' y='158.367'/> +<use x='195.933' xlink:href='#g1-52' y='158.367'/> +<use x='198.58' xlink:href='#g1-46' y='158.367'/> +<use x='200.05' xlink:href='#g1-49' y='158.367'/> +<use x='202.696' xlink:href='#g1-44' y='158.367'/> +<use x='205.931' xlink:href='#g1-71' y='158.367'/> +<use x='209.459' xlink:href='#g1-67' y='158.367'/> +<use x='212.841' xlink:href='#g1-67' y='158.367'/> +<use x='217.986' xlink:href='#g1-55' y='158.367'/> +<use x='220.633' xlink:href='#g1-46' y='158.367'/> +<use x='222.103' xlink:href='#g1-51' y='158.367'/> +<use x='224.749' xlink:href='#g1-46' y='158.367'/> +<use x='226.219' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 -9.757 303.575)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 48.912 303.575)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 107.581 303.575)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 166.25 303.575)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 224.919 303.575)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 283.588 303.575)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 -4.526 300.068)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-54' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 54.143 306.456)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-53' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 112.812 302.824)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-49' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 171.481 304.013)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 230.15 350.668)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-53' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 288.819 273.015)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-52' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 0.704 302.573)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-50' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 59.373 309.712)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 118.042 301.884)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-51' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 176.711 292.303)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-49' y='158.367'/> +<use x='175.048' xlink:href='#g1-56' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 235.38 333.071)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-53' y='158.367'/> +<use x='175.048' xlink:href='#g1-51' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 294.049 282.283)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-51' y='158.367'/> +<use x='175.048' xlink:href='#g1-52' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 5.935 299.818)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-54' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 64.604 306.644)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-53' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 123.273 293.618)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-49' y='158.367'/> +<use x='175.048' xlink:href='#g1-54' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 181.942 290.424)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-49' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 240.611 300.381)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-53' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 299.28 299.818)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-54' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 11.165 288.984)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-51' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 69.834 303.888)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 128.503 266.314)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-53' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 187.172 285.101)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 245.841 348.476)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-56' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 304.51 302.448)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-50' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 16.396 278.088)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-52' y='158.367'/> +<use x='175.048' xlink:href='#g1-49' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 75.065 253.477)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-56' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 133.734 258.236)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-55' y='158.367'/> +<use x='175.048' xlink:href='#g1-50' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 192.403 240.952)'> +<use x='163.396' xlink:href='#g3-1' y='158.367'/> +<use x='166.901' xlink:href='#g3-1' y='158.367'/> +<use x='170.407' xlink:href='#g3-1' y='158.367'/> +<use x='173.912' xlink:href='#g1-50' y='158.367'/> +<use x='176.558' xlink:href='#g1-46' y='158.367'/> +<use x='178.029' xlink:href='#g1-52' y='158.367'/> +<use x='180.675' xlink:href='#g1-54' y='158.367'/> +<use x='183.321' xlink:href='#g1-120' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 251.072 329.939)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-53' y='158.367'/> +<use x='175.048' xlink:href='#g1-56' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 309.741 293.117)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-49' y='158.367'/> +<use x='175.048' xlink:href='#g1-55' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 21.626 289.234)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-51' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 80.295 304.013)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 138.964 266.44)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-53' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 197.633 285.164)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 256.302 348.538)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-50' y='158.367'/> +<use x='175.048' xlink:href='#g1-56' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 314.971 302.949)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-49' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 261.532 320.233)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-55' y='158.367'/> +<use x='175.048' xlink:href='#g1-51' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 26.856 297.313)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-49' y='158.367'/> +<use x='175.048' xlink:href='#g1-48' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 85.525 304.389)'> +<use x='168.285' xlink:href='#g1-48' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-57' y='158.367'/> +<use x='175.048' xlink:href='#g1-57' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 144.194 296.937)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-49' y='158.367'/> +<use x='175.048' xlink:href='#g1-49' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 202.863 302.511)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-48' y='158.367'/> +<use x='175.048' xlink:href='#g1-50' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 320.201 293.493)'> +<use x='168.285' xlink:href='#g1-49' y='158.367'/> +<use x='170.931' xlink:href='#g1-46' y='158.367'/> +<use x='172.401' xlink:href='#g1-49' y='158.367'/> +<use x='175.048' xlink:href='#g1-54' y='158.367'/> +</g> +<g transform='matrix(0 -1 1 0 -45.209 361.494)'> +<use x='168.285' xlink:href='#g0-82' y='158.367'/> +<use x='174.255' xlink:href='#g0-101' y='158.367'/> +<use x='178.351' xlink:href='#g0-108' y='158.367'/> +<use x='180.551' xlink:href='#g0-97' y='158.367'/> +<use x='184.979' xlink:href='#g0-116' y='158.367'/> +<use x='188.307' xlink:href='#g0-105' y='158.367'/> +<use x='190.507' xlink:href='#g0-118' y='158.367'/> +<use x='194.755' xlink:href='#g0-101' y='158.367'/> +<use x='201.922' xlink:href='#g0-114' y='158.367'/> +<use x='205.07' xlink:href='#g0-115' y='158.367'/> +<use x='208.603' xlink:href='#g0-115' y='158.367'/> +<use x='215.207' xlink:href='#g2-40' y='158.367'/> +<use x='218.5' xlink:href='#g2-108' y='158.367'/> +<use x='220.521' xlink:href='#g2-111' y='158.367'/> +<use x='224.52' xlink:href='#g2-119' y='158.367'/> +<use x='230.068' xlink:href='#g2-101' y='158.367'/> +<use x='233.832' xlink:href='#g2-114' y='158.367'/> +<use x='239.547' xlink:href='#g2-105' y='158.367'/> +<use x='241.567' xlink:href='#g2-115' y='158.367'/> +<use x='247.636' xlink:href='#g2-98' y='158.367'/> +<use x='252.244' xlink:href='#g2-101' y='158.367'/> +<use x='256.008' xlink:href='#g2-116' y='158.367'/> +<use x='259.066' xlink:href='#g2-116' y='158.367'/> +<use x='262.124' xlink:href='#g2-101' y='158.367'/> +<use x='265.887' xlink:href='#g2-114' y='158.367'/> +<use x='268.779' xlink:href='#g2-41' y='158.367'/> +</g> +<path d='M136.149 249.309H349.488V232.317H136.149Z' fill='#ffffff'/> +<path d='M136.149 249.309H349.488V232.317H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 242.804H142.324V234.835H139.336ZM145.313 242.804H148.301V236.828H145.313Z' fill='#f0e0f0'/> +<path d='M139.336 242.804H142.324V234.835H139.336ZM145.313 242.804H148.301V236.828H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -33.522 84.43)'> +<use x='185.011' xlink:href='#g2-109' y='158.367'/> +<use x='191.736' xlink:href='#g2-105' y='158.367'/> +</g> +<path d='M163.422 242.805H166.41V234.836H163.422ZM169.398 242.805H172.391V236.828H169.398Z' fill='#e1c2e1'/> +<path d='M163.422 242.804H166.41V234.835H163.422ZM169.398 242.804H172.391V236.828H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.56 83.976)'> +<use x='208.137' xlink:href='#g2-116' y='158.367'/> +<use x='211.195' xlink:href='#g2-99' y='158.367'/> +</g> +<path d='M185.586 242.805H188.574V234.836H185.586ZM191.563 242.805H194.555V236.828H191.563Z' fill='#d1a3d1'/> +<path d='M185.586 242.804H188.574V234.835H185.586ZM191.563 242.804H194.555V236.828H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.159 84.43)'> +<use x='229.9' xlink:href='#g2-106' y='158.367'/> +<use x='232.155' xlink:href='#g2-101' y='158.367'/> +</g> +<path d='M206.949 242.805H209.938V234.836H206.949ZM212.926 242.805H215.914V236.828H212.926Z' fill='#c285c2'/> +<path d='M206.949 242.804H209.938V234.835H206.949ZM212.926 242.804H215.914V236.828H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.958 83.47)'> +<use x='252.061' xlink:href='#g2-115' y='158.367'/> +<use x='255.307' xlink:href='#g2-110' y='158.367'/> +</g> +<path d='M229.91 242.805H232.898V234.836H229.91ZM235.887 242.805H238.875V236.828H235.887Z' fill='#b366b3'/> +<path d='M229.91 242.804H232.898V234.835H229.91ZM235.887 242.804H238.875V236.828H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.781 83.47)'> +<use x='274.845' xlink:href='#g2-114' y='158.367'/> +<use x='277.737' xlink:href='#g2-112' y='158.367'/> +</g> +<path d='M252.516 242.805H255.504V234.836H252.516ZM258.496 242.805H261.484V236.828H258.496Z' fill='#a447a4'/> +<path d='M252.516 242.804H255.504V234.835H252.516ZM258.496 242.804H261.484V236.828H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.001 84.467)'> +<use x='303.672' xlink:href='#g2-104' y='158.367'/> +<use x='308.045' xlink:href='#g2-111' y='158.367'/> +<use x='312.279' xlink:href='#g2-97' y='158.367'/> +<use x='316.112' xlink:href='#g2-114' y='158.367'/> +<use x='319.004' xlink:href='#g2-100' y='158.367'/> +</g> +<path d='M287.563 242.805H290.551V234.836H287.563ZM293.543 242.805H296.531V236.828H293.543Z' fill='#942994'/> +<path d='M287.563 242.804H290.551V234.835H287.563ZM293.543 242.804H296.531V236.828H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.472 84.467)'> +<use x='337.19' xlink:href='#g2-103' y='158.367'/> +<use x='341.424' xlink:href='#g2-108' y='158.367'/> +<use x='343.444' xlink:href='#g2-105' y='158.367'/> +<use x='345.464' xlink:href='#g2-98' y='158.367'/> +<use x='350.072' xlink:href='#g2-99' y='158.367'/> +</g> +<path d='M319.551 242.805H322.539V234.836H319.551ZM325.527 242.805H328.52V236.828H325.527Z' fill='#850a85'/> +<path d='M319.551 242.804H322.539V234.835H319.551ZM325.527 242.804H328.52V236.828H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.051 84.467)'> +<use x='366.757' xlink:href='#g2-116' y='158.367'/> +<use x='369.815' xlink:href='#g2-98' y='158.367'/> +<use x='374.187' xlink:href='#g2-98' y='158.367'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec-rss.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec-rss.svg new file mode 100644 index 0000000..2c93616 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec-rss.svg @@ -0,0 +1,713 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='182.025pt' version='1.1' viewBox='106.736 51.674 270.486 182.025' width='270.486pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<clipPath id='clip6'> +<path d='M135.949 186.074H355.586V60.828H135.949Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-46' transform='scale(1.6)' xlink:href='#g1-46'/> +<use id='g2-48' transform='scale(1.6)' xlink:href='#g1-48'/> +<use id='g2-50' transform='scale(1.6)' xlink:href='#g1-50'/> +<use id='g2-51' transform='scale(1.6)' xlink:href='#g1-51'/> +<use id='g2-52' transform='scale(1.6)' xlink:href='#g1-52'/> +<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/> +<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/> +<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/> +<use id='g2-107' transform='scale(1.6)' xlink:href='#g1-107'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/> +<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/> +<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/> +<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/> +<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/> +<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/> +<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/> +<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/> +<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/> +<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/> +<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/> +<path d='M1.489 -1.355L2.376 -2.212H1.893L0.827 -1.181V-3.457H0.438V0H0.807V-0.697L1.23 -1.106L2.052 0H2.491L1.489 -1.355Z' id='g1-107'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page6'> +<path d='M190.86 194.93V186.074M245.766 194.93V186.074M300.676 194.93V186.074M190.86 51.973V60.828M245.766 51.973V60.828M300.676 51.973V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M163.403 190.324V186.074M218.313 190.324V186.074M273.223 190.324V186.074M328.133 190.324V186.074M163.403 56.574V60.828M218.313 56.574V60.828M273.223 56.574V60.828M328.133 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 186.074H140.199M135.949 154.762H140.199M135.949 123.449H140.199M135.949 92.141H140.199M135.949 60.828H140.199M355.586 186.074H351.336M355.586 154.762H351.336M355.586 123.449H351.336M355.586 92.141H351.336M355.586 60.828H351.336' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 186.074V60.828H355.586V186.074H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -18.291 59.571)'> +<use x='168.285' xlink:href='#g2-54' y='140.503'/> +<use x='172.519' xlink:href='#g2-48' y='140.503'/> +<use x='176.753' xlink:href='#g2-50' y='140.503'/> +<use x='180.987' xlink:href='#g2-46' y='140.503'/> +<use x='183.34' xlink:href='#g2-103' y='140.503'/> +<use x='187.574' xlink:href='#g2-99' y='140.503'/> +<use x='191.338' xlink:href='#g2-99' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 27.05 59.571)'> +<use x='168.285' xlink:href='#g2-54' y='140.503'/> +<use x='172.519' xlink:href='#g2-50' y='140.503'/> +<use x='176.753' xlink:href='#g2-48' y='140.503'/> +<use x='180.987' xlink:href='#g2-46' y='140.503'/> +<use x='183.34' xlink:href='#g2-111' y='140.503'/> +<use x='187.574' xlink:href='#g2-109' y='140.503'/> +<use x='194.299' xlink:href='#g2-110' y='140.503'/> +<use x='198.671' xlink:href='#g2-101' y='140.503'/> +<use x='202.435' xlink:href='#g2-116' y='140.503'/> +<use x='205.493' xlink:href='#g2-112' y='140.503'/> +<use x='209.866' xlink:href='#g2-112' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 78.694 59.571)'> +<use x='168.285' xlink:href='#g2-54' y='140.503'/> +<use x='172.519' xlink:href='#g2-50' y='140.503'/> +<use x='176.753' xlink:href='#g2-51' y='140.503'/> +<use x='180.987' xlink:href='#g2-46' y='140.503'/> +<use x='183.34' xlink:href='#g2-120' y='140.503'/> +<use x='187.242' xlink:href='#g2-97' y='140.503'/> +<use x='191.31' xlink:href='#g2-108' y='140.503'/> +<use x='193.33' xlink:href='#g2-97' y='140.503'/> +<use x='197.398' xlink:href='#g2-110' y='140.503'/> +<use x='201.771' xlink:href='#g2-99' y='140.503'/> +<use x='205.535' xlink:href='#g2-98' y='140.503'/> +<use x='209.907' xlink:href='#g2-109' y='140.503'/> +<use x='216.632' xlink:href='#g2-107' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 134.081 59.571)'> +<use x='168.285' xlink:href='#g2-54' y='140.503'/> +<use x='172.519' xlink:href='#g2-52' y='140.503'/> +<use x='176.753' xlink:href='#g2-56' y='140.503'/> +<use x='180.987' xlink:href='#g2-46' y='140.503'/> +<use x='183.34' xlink:href='#g2-101' y='140.503'/> +<use x='187.103' xlink:href='#g2-120' y='140.503'/> +<use x='191.006' xlink:href='#g2-99' y='140.503'/> +<use x='194.769' xlink:href='#g2-104' y='140.503'/> +<use x='199.142' xlink:href='#g2-97' y='140.503'/> +<use x='203.21' xlink:href='#g2-110' y='140.503'/> +<use x='207.582' xlink:href='#g2-103' y='140.503'/> +<use x='211.817' xlink:href='#g2-101' y='140.503'/> +<use x='215.58' xlink:href='#g2-50' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 47.205)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 15.894)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -15.418)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -46.729)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -78.041)'> +<use x='168.285' xlink:href='#g1-50' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<path clip-path='url(#clip6)' d='M135.949 123.449H355.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M140.863 186.074H144.102V123.449H140.863ZM195.77 186.074H199.008V123.449H195.77ZM250.68 186.074H253.918V123.449H250.68ZM305.59 186.074H308.828V123.449H305.59Z' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M140.863 186.074H144.102V123.449H140.863ZM195.77 186.074H199.008V123.449H195.77ZM250.68 186.074H253.918V123.449H250.68ZM305.59 186.074H308.828V123.449H305.59Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M142.481 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M140.488 123.449H144.472' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M142.481 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M140.488 123.449H144.472' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M197.391 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M195.398 123.449H199.383' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M197.391 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M195.398 123.449H199.383' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M252.301 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M250.308 123.449H254.292' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M252.301 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M250.308 123.449H254.292' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M307.211 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M305.219 123.449H309.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M307.211 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip6)' d='M305.219 123.449H309.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M146.094 186.074H149.332V123.262H146.094ZM201 186.074H204.238V123.137H201ZM255.91 186.074H259.149V124.141H255.91ZM310.82 186.074H314.059V73.664H310.82Z' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M146.094 186.074H149.332V123.262H146.094ZM201 186.074H204.238V123.137H201ZM255.91 186.074H259.149V124.141H255.91ZM310.82 186.074H314.059V73.664H310.82Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M147.711 123.262V123.262' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M145.719 123.262H149.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M147.711 123.262V123.262' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M145.719 123.262H149.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M202.621 123.137V123.137' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M200.629 123.137H204.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M202.621 123.137V123.137' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M200.629 123.137H204.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M257.531 124.141V124.141' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M255.539 124.141H259.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M257.531 124.141V124.141' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M255.539 124.141H259.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M312.442 73.664V73.664' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M310.449 73.664H314.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M312.442 73.664V73.664' fill='#e1c2e1'/> +<path clip-path='url(#clip6)' d='M310.449 73.664H314.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M151.324 186.074H154.563V121.762H151.324ZM206.231 186.074H209.469V123.891H206.231ZM261.141 186.074H264.379V121.321H261.141ZM316.051 186.074H319.289V94.52H316.051Z' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M151.324 186.074H154.563V121.762H151.324ZM206.231 186.074H209.469V123.891H206.231ZM261.141 186.074H264.379V121.321H261.141ZM316.051 186.074H319.289V94.52H316.051Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M152.942 121.762V121.762' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M150.949 121.762H154.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M152.942 121.762V121.762' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M150.949 121.762H154.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M207.852 123.891V123.891' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M205.86 123.89H209.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M207.852 123.891V123.891' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M205.86 123.89H209.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M262.762 121.321V121.321' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M260.769 121.321H264.753' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M262.762 121.321V121.321' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M260.769 121.321H264.753' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M317.672 94.52V94.52' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M315.68 94.52H319.664' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M317.672 94.52V94.52' fill='#d1a3d1'/> +<path clip-path='url(#clip6)' d='M315.68 94.52H319.664' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M156.555 186.074H159.793V122.449H156.555ZM211.461 186.074H214.699V124.328H211.461ZM266.371 186.074H269.609V124.953H266.371ZM321.281 186.074H324.52V106.168H321.281Z' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M156.555 186.074H159.793V122.449H156.555ZM211.461 186.074H214.699V124.328H211.461ZM266.371 186.074H269.609V124.953H266.371ZM321.281 186.074H324.52V106.168H321.281Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M158.172 122.449V122.449' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M156.18 122.449H160.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M158.172 122.449V122.449' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M156.18 122.449H160.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M213.082 124.328V124.328' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M211.09 124.329H215.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M213.082 124.328V124.328' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M211.09 124.329H215.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M267.992 124.953V124.953' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M266 124.953H269.985' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M267.992 124.953V124.953' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M266 124.953H269.985' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M322.902 106.168V106.168' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M320.91 106.168H324.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M322.902 106.168V106.168' fill='#c285c2'/> +<path clip-path='url(#clip6)' d='M320.91 106.168H324.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M161.785 186.074H165.024V123.891H161.785ZM216.692 186.074H219.93V122.262H216.692ZM271.602 186.074H274.84V127.395H271.602ZM326.512 186.074H329.75V125.328H326.512Z' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M161.785 186.074H165.024V123.891H161.785ZM216.692 186.074H219.93V122.262H216.692ZM271.602 186.074H274.84V127.395H271.602ZM326.512 186.074H329.75V125.328H326.512Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M163.403 123.891V123.891' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M161.41 123.89H165.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M163.403 123.891V123.891' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M161.41 123.89H165.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M218.313 122.262V122.262' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M216.321 122.262H220.305' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M218.313 122.262V122.262' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M216.321 122.262H220.305' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M273.223 127.395V127.395' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M271.23 127.394H275.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M273.223 127.395V127.395' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M271.23 127.394H275.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M328.133 125.328V125.328' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M326.141 125.329H330.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M328.133 125.328V125.328' fill='#b366b3'/> +<path clip-path='url(#clip6)' d='M326.141 125.329H330.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M167.016 186.074H170.254V104.914H167.016ZM221.922 186.074H225.16V113.18H221.922ZM276.832 186.074H280.07V100.781H276.832ZM331.742 186.074H334.981V71.848H331.742Z' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M167.016 186.074H170.254V104.914H167.016ZM221.922 186.074H225.16V113.18H221.922ZM276.832 186.074H280.07V100.781H276.832ZM331.742 186.074H334.981V71.848H331.742Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M168.633 104.914V104.914' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M166.641 104.914H170.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M168.633 104.914V104.914' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M166.641 104.914H170.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M223.543 113.18V113.18' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M221.551 113.18H225.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M223.543 113.18V113.18' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M221.551 113.18H225.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M278.453 100.781V100.781' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M276.461 100.781H280.446' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M278.453 100.781V100.781' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M276.461 100.781H280.446' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M333.363 71.848V71.848' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M331.371 71.848H335.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M333.363 71.848V71.848' fill='#a447a4'/> +<path clip-path='url(#clip6)' d='M331.371 71.848H335.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M172.246 186.074H175.485V123.891H172.246ZM227.153 186.074H230.391V122.324H227.153ZM282.063 186.074H285.301V127.395H282.063ZM336.973 186.074H340.211V123.891H336.973Z' fill='#942994'/> +<path clip-path='url(#clip6)' d='M172.246 186.074H175.485V123.891H172.246ZM227.153 186.074H230.391V122.324H227.153ZM282.063 186.074H285.301V127.395H282.063ZM336.973 186.074H340.211V123.891H336.973Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M173.863 123.891V123.891' fill='#942994'/> +<path clip-path='url(#clip6)' d='M171.871 123.89H175.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M173.863 123.891V123.891' fill='#942994'/> +<path clip-path='url(#clip6)' d='M171.871 123.89H175.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M228.774 122.324V122.324' fill='#942994'/> +<path clip-path='url(#clip6)' d='M226.782 122.325H230.766' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M228.774 122.324V122.324' fill='#942994'/> +<path clip-path='url(#clip6)' d='M226.782 122.325H230.766' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M283.684 127.395V127.395' fill='#942994'/> +<path clip-path='url(#clip6)' d='M281.691 127.394H285.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M283.684 127.395V127.395' fill='#942994'/> +<path clip-path='url(#clip6)' d='M281.691 127.394H285.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M338.594 123.891V123.891' fill='#942994'/> +<path clip-path='url(#clip6)' d='M336.602 123.89H340.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M338.594 123.891V123.891' fill='#942994'/> +<path clip-path='url(#clip6)' d='M336.602 123.89H340.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M177.477 186.074H180.715V104.602H177.477ZM232.383 186.074H235.621V113.367H232.383ZM287.293 186.074H290.531V112.117H287.293ZM342.203 186.074H345.442V103.16H342.203Z' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M177.477 186.074H180.715V104.602H177.477ZM232.383 186.074H235.621V113.367H232.383ZM287.293 186.074H290.531V112.117H287.293ZM342.203 186.074H345.442V103.16H342.203Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M179.094 104.602V104.602' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M177.102 104.601H181.086' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M179.094 104.602V104.602' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M177.102 104.601H181.086' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M234.004 113.367V113.367' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M232.012 113.368H235.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M234.004 113.367V113.367' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M232.012 113.368H235.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M288.914 112.117V112.117' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M286.922 112.117H290.907' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M288.914 112.117V112.117' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M286.922 112.117H290.907' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M343.824 103.16V103.16' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M341.832 103.16H345.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M343.824 103.16V103.16' fill='#850a85'/> +<path clip-path='url(#clip6)' d='M341.832 103.16H345.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M182.707 186.074H185.945V123.324H182.707ZM237.613 186.074H240.852V117.754H237.613ZM292.524 186.074H295.762V121.508H292.524ZM347.434 186.074H350.672V117.375H347.434Z' fill='#760076'/> +<path clip-path='url(#clip6)' d='M182.707 186.074H185.945V123.324H182.707ZM237.613 186.074H240.852V117.754H237.613ZM292.524 186.074H295.762V121.508H292.524ZM347.434 186.074H350.672V117.375H347.434Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M184.324 123.324V123.324' fill='#760076'/> +<path clip-path='url(#clip6)' d='M182.332 123.325H186.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M184.324 123.324V123.324' fill='#760076'/> +<path clip-path='url(#clip6)' d='M182.332 123.325H186.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M239.234 117.754V117.754' fill='#760076'/> +<path clip-path='url(#clip6)' d='M237.243 117.754H241.227' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M239.234 117.754V117.754' fill='#760076'/> +<path clip-path='url(#clip6)' d='M237.243 117.754H241.227' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M294.145 121.508V121.508' fill='#760076'/> +<path clip-path='url(#clip6)' d='M292.152 121.508H296.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M294.145 121.508V121.508' fill='#760076'/> +<path clip-path='url(#clip6)' d='M292.152 121.508H296.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M349.055 117.375V117.375' fill='#760076'/> +<path clip-path='url(#clip6)' d='M347.063 117.375H351.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M349.055 117.375V117.375' fill='#760076'/> +<path clip-path='url(#clip6)' d='M347.063 117.375H351.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip6)' d='M287.102 233.301H355.387V211.324H287.102Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 122.136 88.837)'> +<use x='168.285' xlink:href='#g1-72' y='129.265'/> +<use x='172.021' xlink:href='#g1-80' y='129.265'/> +<use x='175.402' xlink:href='#g1-45' y='129.265'/> +<use x='177.167' xlink:href='#g1-90' y='129.265'/> +<use x='180.401' xlink:href='#g1-52' y='129.265'/> +<use x='183.047' xlink:href='#g1-45' y='129.265'/> +<use x='184.812' xlink:href='#g1-71' y='129.265'/> +<use x='188.34' xlink:href='#g1-52' y='129.265'/> +<use x='190.987' xlink:href='#g1-44' y='129.265'/> +<use x='194.221' xlink:href='#g1-49' y='129.265'/> +<use x='196.867' xlink:href='#g1-54' y='129.265'/> +<use x='199.514' xlink:href='#g1-71' y='129.265'/> +<use x='203.042' xlink:href='#g1-98' y='129.265'/> +<use x='168.285' xlink:href='#g1-56' y='134.884'/> +<use x='170.931' xlink:href='#g1-45' y='134.884'/> +<use x='172.695' xlink:href='#g1-99' y='134.884'/> +<use x='175.048' xlink:href='#g1-111' y='134.884'/> +<use x='177.547' xlink:href='#g1-114' y='134.884'/> +<use x='179.355' xlink:href='#g1-101' y='134.884'/> +<use x='183.471' xlink:href='#g1-73' y='134.884'/> +<use x='184.941' xlink:href='#g1-110' y='134.884'/> +<use x='187.674' xlink:href='#g1-116' y='134.884'/> +<use x='189.585' xlink:href='#g1-101' y='134.884'/> +<use x='191.938' xlink:href='#g1-108' y='134.884'/> +<use x='194.965' xlink:href='#g1-88' y='134.884'/> +<use x='198.493' xlink:href='#g1-69' y='134.884'/> +<use x='201.667' xlink:href='#g1-79' y='134.884'/> +<use x='205.576' xlink:href='#g1-78' y='134.884'/> +<use x='211.076' xlink:href='#g1-64' y='134.884'/> +<use x='214.605' xlink:href='#g1-50' y='134.884'/> +<use x='217.251' xlink:href='#g1-46' y='134.884'/> +<use x='218.721' xlink:href='#g1-55' y='134.884'/> +<use x='221.368' xlink:href='#g1-71' y='134.884'/> +<use x='224.896' xlink:href='#g1-104' y='134.884'/> +<use x='227.629' xlink:href='#g1-122' y='134.884'/> +<use x='168.285' xlink:href='#g1-85' y='140.503'/> +<use x='171.917' xlink:href='#g1-98' y='140.503'/> +<use x='174.65' xlink:href='#g1-117' y='140.503'/> +<use x='177.383' xlink:href='#g1-110' y='140.503'/> +<use x='180.116' xlink:href='#g1-116' y='140.503'/> +<use x='182.027' xlink:href='#g1-117' y='140.503'/> +<use x='186.524' xlink:href='#g1-49' y='140.503'/> +<use x='189.17' xlink:href='#g1-56' y='140.503'/> +<use x='191.817' xlink:href='#g1-46' y='140.503'/> +<use x='193.287' xlink:href='#g1-48' y='140.503'/> +<use x='195.933' xlink:href='#g1-52' y='140.503'/> +<use x='198.58' xlink:href='#g1-46' y='140.503'/> +<use x='200.05' xlink:href='#g1-49' y='140.503'/> +<use x='202.696' xlink:href='#g1-44' y='140.503'/> +<use x='205.931' xlink:href='#g1-71' y='140.503'/> +<use x='209.459' xlink:href='#g1-67' y='140.503'/> +<use x='212.841' xlink:href='#g1-67' y='140.503'/> +<use x='217.986' xlink:href='#g1-55' y='140.503'/> +<use x='220.633' xlink:href='#g1-46' y='140.503'/> +<use x='222.103' xlink:href='#g1-52' y='140.503'/> +<use x='224.749' xlink:href='#g1-46' y='140.503'/> +<use x='226.219' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 3.612 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 58.522 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 113.431 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 168.341 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 8.843 285.523)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 63.752 285.398)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 118.662 286.4)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 173.571 235.926)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-55' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 14.073 284.02)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 68.983 286.149)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 123.892 283.582)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 178.802 256.779)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-52' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 19.304 284.709)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 74.213 286.588)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 129.123 287.214)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-56' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 184.032 268.427)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-56' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 24.534 286.149)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 79.444 284.521)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 134.353 289.656)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-52' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 189.263 287.59)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 29.765 267.175)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-51' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 84.674 275.441)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 139.584 263.042)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-51' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 194.493 234.11)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-56' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 34.995 286.149)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 89.905 284.584)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 144.814 289.656)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-52' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 199.724 286.149)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 40.226 266.862)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-51' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 95.135 275.629)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 150.045 274.376)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-56' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 204.954 265.421)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-51' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 45.456 285.586)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 100.366 280.012)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 155.275 283.77)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 210.185 279.637)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -27.345 343.63)'> +<use x='168.285' xlink:href='#g0-82' y='140.503'/> +<use x='174.255' xlink:href='#g0-101' y='140.503'/> +<use x='178.351' xlink:href='#g0-108' y='140.503'/> +<use x='180.551' xlink:href='#g0-97' y='140.503'/> +<use x='184.979' xlink:href='#g0-116' y='140.503'/> +<use x='188.307' xlink:href='#g0-105' y='140.503'/> +<use x='190.507' xlink:href='#g0-118' y='140.503'/> +<use x='194.755' xlink:href='#g0-101' y='140.503'/> +<use x='201.922' xlink:href='#g0-114' y='140.503'/> +<use x='205.07' xlink:href='#g0-115' y='140.503'/> +<use x='208.603' xlink:href='#g0-115' y='140.503'/> +<use x='215.207' xlink:href='#g2-40' y='140.503'/> +<use x='218.5' xlink:href='#g2-108' y='140.503'/> +<use x='220.521' xlink:href='#g2-111' y='140.503'/> +<use x='224.52' xlink:href='#g2-119' y='140.503'/> +<use x='230.068' xlink:href='#g2-101' y='140.503'/> +<use x='233.832' xlink:href='#g2-114' y='140.503'/> +<use x='239.547' xlink:href='#g2-105' y='140.503'/> +<use x='241.567' xlink:href='#g2-115' y='140.503'/> +<use x='247.636' xlink:href='#g2-98' y='140.503'/> +<use x='252.244' xlink:href='#g2-101' y='140.503'/> +<use x='256.008' xlink:href='#g2-116' y='140.503'/> +<use x='259.066' xlink:href='#g2-116' y='140.503'/> +<use x='262.124' xlink:href='#g2-101' y='140.503'/> +<use x='265.887' xlink:href='#g2-114' y='140.503'/> +<use x='268.779' xlink:href='#g2-41' y='140.503'/> +</g> +<path d='M136.149 231.446H376.824V214.453H136.149Z' fill='#ffffff'/> +<path d='M136.149 231.446H376.824V214.453H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='#f0e0f0'/> +<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -33.522 84.43)'> +<use x='185.011' xlink:href='#g2-109' y='140.503'/> +<use x='191.736' xlink:href='#g2-105' y='140.503'/> +</g> +<path d='M163.422 224.941H166.41V216.973H163.422ZM169.398 224.941H172.391V218.965H169.398Z' fill='#e1c2e1'/> +<path d='M163.422 224.941H166.41V216.972H163.422ZM169.398 224.941H172.391V218.964H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.56 83.976)'> +<use x='208.137' xlink:href='#g2-116' y='140.503'/> +<use x='211.195' xlink:href='#g2-99' y='140.503'/> +</g> +<path d='M185.586 224.941H188.574V216.973H185.586ZM191.563 224.941H194.555V218.965H191.563Z' fill='#d1a3d1'/> +<path d='M185.586 224.941H188.574V216.972H185.586ZM191.563 224.941H194.555V218.964H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.159 84.43)'> +<use x='229.9' xlink:href='#g2-106' y='140.503'/> +<use x='232.155' xlink:href='#g2-101' y='140.503'/> +</g> +<path d='M206.949 224.941H209.938V216.973H206.949ZM212.926 224.941H215.914V218.965H212.926Z' fill='#c285c2'/> +<path d='M206.949 224.941H209.938V216.972H206.949ZM212.926 224.941H215.914V218.964H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.958 83.47)'> +<use x='252.061' xlink:href='#g2-115' y='140.503'/> +<use x='255.307' xlink:href='#g2-110' y='140.503'/> +</g> +<path d='M229.91 224.941H232.898V216.973H229.91ZM235.887 224.941H238.875V218.965H235.887Z' fill='#b366b3'/> +<path d='M229.91 224.941H232.898V216.972H229.91ZM235.887 224.941H238.875V218.964H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.781 83.47)'> +<use x='274.845' xlink:href='#g2-114' y='140.503'/> +<use x='277.737' xlink:href='#g2-112' y='140.503'/> +</g> +<path d='M252.516 224.941H255.504V216.973H252.516ZM258.496 224.941H261.484V218.965H258.496Z' fill='#a447a4'/> +<path d='M252.516 224.941H255.504V216.972H252.516ZM258.496 224.941H261.484V218.964H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.001 84.467)'> +<use x='303.672' xlink:href='#g2-104' y='140.503'/> +<use x='308.045' xlink:href='#g2-111' y='140.503'/> +<use x='312.279' xlink:href='#g2-97' y='140.503'/> +<use x='316.112' xlink:href='#g2-114' y='140.503'/> +<use x='319.004' xlink:href='#g2-100' y='140.503'/> +</g> +<path d='M287.563 224.941H290.551V216.973H287.563ZM293.543 224.941H296.531V218.965H293.543Z' fill='#942994'/> +<path d='M287.563 224.941H290.551V216.972H287.563ZM293.543 224.941H296.531V218.964H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.472 84.467)'> +<use x='337.19' xlink:href='#g2-103' y='140.503'/> +<use x='341.424' xlink:href='#g2-108' y='140.503'/> +<use x='343.444' xlink:href='#g2-105' y='140.503'/> +<use x='345.464' xlink:href='#g2-98' y='140.503'/> +<use x='350.072' xlink:href='#g2-99' y='140.503'/> +</g> +<path d='M319.551 224.941H322.539V216.973H319.551ZM325.527 224.941H328.52V218.965H325.527Z' fill='#850a85'/> +<path d='M319.551 224.941H322.539V216.972H319.551ZM325.527 224.941H328.52V218.964H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.051 84.467)'> +<use x='366.757' xlink:href='#g2-116' y='140.503'/> +<use x='369.815' xlink:href='#g2-98' y='140.503'/> +<use x='374.187' xlink:href='#g2-98' y='140.503'/> +</g> +<path d='M346.699 224.941H349.688V216.973H346.699ZM352.676 224.941H355.664V218.965H352.676Z' fill='#760076'/> +<path d='M346.699 224.941H349.688V216.972H346.699ZM352.676 224.941H355.664V218.964H352.676Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.145 84.43)'> +<use x='393.997' xlink:href='#g2-115' y='140.503'/> +<use x='397.243' xlink:href='#g2-109' y='140.503'/> +<use x='403.968' xlink:href='#g2-105' y='140.503'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec.svg new file mode 100644 index 0000000..af2b41b --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec.svg @@ -0,0 +1,713 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='182.025pt' version='1.1' viewBox='52.938 51.674 270.487 182.025' width='270.487pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<clipPath id='clip5'> +<path d='M82.148 186.074H301.789V60.828H82.148Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-46' transform='scale(1.6)' xlink:href='#g1-46'/> +<use id='g2-48' transform='scale(1.6)' xlink:href='#g1-48'/> +<use id='g2-50' transform='scale(1.6)' xlink:href='#g1-50'/> +<use id='g2-51' transform='scale(1.6)' xlink:href='#g1-51'/> +<use id='g2-52' transform='scale(1.6)' xlink:href='#g1-52'/> +<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/> +<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/> +<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/> +<use id='g2-107' transform='scale(1.6)' xlink:href='#g1-107'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/> +<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/> +<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/> +<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/> +<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/> +<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/> +<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/> +<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/> +<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/> +<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/> +<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/> +<path d='M1.489 -1.355L2.376 -2.212H1.893L0.827 -1.181V-3.457H0.438V0H0.807V-0.697L1.23 -1.106L2.052 0H2.491L1.489 -1.355Z' id='g1-107'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page5'> +<path d='M137.059 194.93V186.074M191.969 194.93V186.074M246.879 194.93V186.074M137.059 51.973V60.828M191.969 51.973V60.828M246.879 51.973V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M109.606 190.324V186.074M164.516 190.324V186.074M219.422 190.324V186.074M274.332 190.324V186.074M109.606 56.574V60.828M164.516 56.574V60.828M219.422 56.574V60.828M274.332 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 186.074H86.402M82.148 154.762H86.402M82.148 123.449H86.402M82.148 92.141H86.402M82.148 60.828H86.402M301.789 186.074H297.535M301.789 154.762H297.535M301.789 123.449H297.535M301.789 92.141H297.535M301.789 60.828H297.535' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 186.074V60.828H301.789V186.074H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -18.291 59.571)'> +<use x='114.487' xlink:href='#g2-54' y='140.503'/> +<use x='118.721' xlink:href='#g2-48' y='140.503'/> +<use x='122.955' xlink:href='#g2-50' y='140.503'/> +<use x='127.189' xlink:href='#g2-46' y='140.503'/> +<use x='129.541' xlink:href='#g2-103' y='140.503'/> +<use x='133.776' xlink:href='#g2-99' y='140.503'/> +<use x='137.539' xlink:href='#g2-99' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 27.05 59.571)'> +<use x='114.487' xlink:href='#g2-54' y='140.503'/> +<use x='118.721' xlink:href='#g2-50' y='140.503'/> +<use x='122.955' xlink:href='#g2-48' y='140.503'/> +<use x='127.189' xlink:href='#g2-46' y='140.503'/> +<use x='129.541' xlink:href='#g2-111' y='140.503'/> +<use x='133.776' xlink:href='#g2-109' y='140.503'/> +<use x='140.501' xlink:href='#g2-110' y='140.503'/> +<use x='144.873' xlink:href='#g2-101' y='140.503'/> +<use x='148.637' xlink:href='#g2-116' y='140.503'/> +<use x='151.695' xlink:href='#g2-112' y='140.503'/> +<use x='156.067' xlink:href='#g2-112' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 78.694 59.571)'> +<use x='114.487' xlink:href='#g2-54' y='140.503'/> +<use x='118.721' xlink:href='#g2-50' y='140.503'/> +<use x='122.955' xlink:href='#g2-51' y='140.503'/> +<use x='127.189' xlink:href='#g2-46' y='140.503'/> +<use x='129.541' xlink:href='#g2-120' y='140.503'/> +<use x='133.444' xlink:href='#g2-97' y='140.503'/> +<use x='137.512' xlink:href='#g2-108' y='140.503'/> +<use x='139.532' xlink:href='#g2-97' y='140.503'/> +<use x='143.6' xlink:href='#g2-110' y='140.503'/> +<use x='147.973' xlink:href='#g2-99' y='140.503'/> +<use x='151.736' xlink:href='#g2-98' y='140.503'/> +<use x='156.109' xlink:href='#g2-109' y='140.503'/> +<use x='162.834' xlink:href='#g2-107' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 134.081 59.571)'> +<use x='114.487' xlink:href='#g2-54' y='140.503'/> +<use x='118.721' xlink:href='#g2-52' y='140.503'/> +<use x='122.955' xlink:href='#g2-56' y='140.503'/> +<use x='127.189' xlink:href='#g2-46' y='140.503'/> +<use x='129.541' xlink:href='#g2-101' y='140.503'/> +<use x='133.305' xlink:href='#g2-120' y='140.503'/> +<use x='137.207' xlink:href='#g2-99' y='140.503'/> +<use x='140.971' xlink:href='#g2-104' y='140.503'/> +<use x='145.344' xlink:href='#g2-97' y='140.503'/> +<use x='149.412' xlink:href='#g2-110' y='140.503'/> +<use x='153.784' xlink:href='#g2-103' y='140.503'/> +<use x='158.018' xlink:href='#g2-101' y='140.503'/> +<use x='161.782' xlink:href='#g2-50' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 47.205)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 15.894)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-53' y='140.503'/> +<use x='121.25' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -15.418)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -46.729)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-53' y='140.503'/> +<use x='121.25' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -78.041)'> +<use x='114.487' xlink:href='#g1-50' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-120' y='140.503'/> +</g> +<path clip-path='url(#clip5)' d='M82.148 123.449H301.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M87.063 186.074H90.301V123.449H87.063ZM141.973 186.074H145.211V123.449H141.973ZM196.883 186.074H200.121V123.449H196.883ZM251.793 186.074H255.031V123.449H251.793Z' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M87.063 186.074H90.301V123.449H87.063ZM141.973 186.074H145.211V123.449H141.973ZM196.883 186.074H200.121V123.449H196.883ZM251.793 186.074H255.031V123.449H251.793Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M88.684 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M86.691 123.449H90.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M88.684 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M86.691 123.449H90.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M143.594 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M141.602 123.449H145.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M143.594 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M141.602 123.449H145.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M198.5 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M196.511 123.449H200.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M198.5 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M196.511 123.449H200.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M253.41 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M251.418 123.449H255.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M253.41 123.449V123.449' fill='#e0e0f0'/> +<path clip-path='url(#clip5)' d='M251.418 123.449H255.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M92.293 186.074H95.531V103.535H92.293ZM147.203 186.074H150.441V125.77H147.203ZM202.113 186.074H205.352V124.203H202.113ZM257.024 186.074H260.262V123.074H257.024Z' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M92.293 186.074H95.531V103.535H92.293ZM147.203 186.074H150.441V125.77H147.203ZM202.113 186.074H205.352V124.203H202.113ZM257.024 186.074H260.262V123.074H257.024Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M93.914 103.535V103.535' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M91.922 103.535H95.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M93.914 103.535V103.535' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M91.922 103.535H95.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M148.824 125.77V125.77' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M146.832 125.77H150.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M148.824 125.77V125.77' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M146.832 125.77H150.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M203.731 124.203V124.203' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M201.742 124.203H205.727' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M203.731 124.203V124.203' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M201.742 124.203H205.727' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M258.641 123.074V123.074' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M256.648 123.074H260.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M258.641 123.074V123.074' fill='#c2c2e1'/> +<path clip-path='url(#clip5)' d='M256.648 123.074H260.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M97.524 186.074H100.762V123.324H97.524ZM152.434 186.074H155.672V123.828H152.434ZM207.344 186.074H210.582V124.203H207.344ZM262.254 186.074H265.492V123.137H262.254Z' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M97.524 186.074H100.762V123.324H97.524ZM152.434 186.074H155.672V123.828H152.434ZM207.344 186.074H210.582V124.203H207.344ZM262.254 186.074H265.492V123.137H262.254Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M99.145 123.324V123.324' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M97.152 123.325H101.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M99.145 123.324V123.324' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M97.152 123.325H101.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M154.055 123.828V123.828' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M152.063 123.829H156.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M154.055 123.828V123.828' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M152.063 123.829H156.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M208.961 124.203V124.203' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M206.972 124.203H210.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M208.961 124.203V124.203' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M206.972 124.203H210.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M263.871 123.137V123.137' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M261.879 123.137H265.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M263.871 123.137V123.137' fill='#a3a3d1'/> +<path clip-path='url(#clip5)' d='M261.879 123.137H265.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M102.754 186.074H105.992V123.449H102.754ZM157.664 186.074H160.902V125.77H157.664ZM212.574 186.074H215.813V125.391H212.574ZM267.484 186.074H270.723V122.449H267.484Z' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M102.754 186.074H105.992V123.449H102.754ZM157.664 186.074H160.902V125.77H157.664ZM212.574 186.074H215.813V125.391H212.574ZM267.484 186.074H270.723V122.449H267.484Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M104.375 123.449V123.449' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M102.383 123.449H106.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M104.375 123.449V123.449' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M102.383 123.449H106.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M159.285 125.77V125.77' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M157.293 125.77H161.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M159.285 125.77V125.77' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M157.293 125.77H161.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M214.192 125.391V125.391' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M212.203 125.39H216.188' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M214.192 125.391V125.391' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M212.203 125.39H216.188' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M269.102 122.449V122.449' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M267.109 122.449H271.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M269.102 122.449V122.449' fill='#8585c2'/> +<path clip-path='url(#clip5)' d='M267.109 122.449H271.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M107.984 186.074H111.223V122.699H107.984ZM162.895 186.074H166.133V117.188H162.895ZM217.805 186.074H221.043V104.727H217.805ZM272.715 186.074H275.953V122.762H272.715Z' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M107.984 186.074H111.223V122.699H107.984ZM162.895 186.074H166.133V117.188H162.895ZM217.805 186.074H221.043V104.727H217.805ZM272.715 186.074H275.953V122.762H272.715Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M109.606 122.699V122.699' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M107.613 122.699H111.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M109.606 122.699V122.699' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M107.613 122.699H111.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M164.516 117.188V117.188' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M162.524 117.188H166.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M164.516 117.188V117.188' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M162.524 117.188H166.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M219.422 104.727V104.727' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M217.433 104.727H221.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M219.422 104.727V104.727' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M217.433 104.727H221.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M274.332 122.762V122.762' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M272.34 122.762H276.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M274.332 122.762V122.762' fill='#6666b3'/> +<path clip-path='url(#clip5)' d='M272.34 122.762H276.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M113.215 186.074H116.453V123.574H113.215ZM168.125 186.074H171.363V119.696H168.125ZM223.035 186.074H226.274V122.637H223.035ZM277.945 186.074H281.184V122.449H277.945Z' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M113.215 186.074H116.453V123.574H113.215ZM168.125 186.074H171.363V119.696H168.125ZM223.035 186.074H226.274V122.637H223.035ZM277.945 186.074H281.184V122.449H277.945Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M114.836 123.574V123.574' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M112.844 123.574H116.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M114.836 123.574V123.574' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M112.844 123.574H116.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M169.746 119.696V119.696' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M167.754 119.695H171.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M169.746 119.696V119.696' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M167.754 119.695H171.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M224.652 122.637V122.637' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M222.664 122.637H226.649' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M224.652 122.637V122.637' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M222.664 122.637H226.649' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M279.563 122.449V122.449' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M277.57 122.449H281.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M279.563 122.449V122.449' fill='#4747a4'/> +<path clip-path='url(#clip5)' d='M277.57 122.449H281.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M118.445 186.074H121.684V122.574H118.445ZM173.356 186.074H176.594V117.25H173.356ZM228.266 186.074H231.504V105.477H228.266ZM283.176 186.074H286.414V121.887H283.176Z' fill='#292994'/> +<path clip-path='url(#clip5)' d='M118.445 186.074H121.684V122.574H118.445ZM173.356 186.074H176.594V117.25H173.356ZM228.266 186.074H231.504V105.477H228.266ZM283.176 186.074H286.414V121.887H283.176Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M120.066 122.574V122.574' fill='#292994'/> +<path clip-path='url(#clip5)' d='M118.074 122.574H122.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M120.066 122.574V122.574' fill='#292994'/> +<path clip-path='url(#clip5)' d='M118.074 122.574H122.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M174.977 117.25V117.25' fill='#292994'/> +<path clip-path='url(#clip5)' d='M172.985 117.25H176.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M174.977 117.25V117.25' fill='#292994'/> +<path clip-path='url(#clip5)' d='M172.985 117.25H176.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M229.883 105.477V105.477' fill='#292994'/> +<path clip-path='url(#clip5)' d='M227.894 105.477H231.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M229.883 105.477V105.477' fill='#292994'/> +<path clip-path='url(#clip5)' d='M227.894 105.477H231.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M284.793 121.887V121.887' fill='#292994'/> +<path clip-path='url(#clip5)' d='M282.801 121.886H286.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M284.793 121.887V121.887' fill='#292994'/> +<path clip-path='url(#clip5)' d='M282.801 121.886H286.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M123.676 186.074H126.914V106.606H123.676ZM178.586 186.074H181.824V122.699H178.586ZM233.496 186.074H236.734V122.449H233.496ZM288.406 186.074H291.645V122.012H288.406Z' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M123.676 186.074H126.914V106.606H123.676ZM178.586 186.074H181.824V122.699H178.586ZM233.496 186.074H236.734V122.449H233.496ZM288.406 186.074H291.645V122.012H288.406Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M125.297 106.606V106.606' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M123.305 106.605H127.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M125.297 106.606V106.606' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M123.305 106.605H127.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M180.207 122.699V122.699' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M178.215 122.699H182.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M180.207 122.699V122.699' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M178.215 122.699H182.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M235.113 122.449V122.449' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M233.125 122.449H237.11' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M235.113 122.449V122.449' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M233.125 122.449H237.11' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M290.024 122.012V122.012' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M288.031 122.012H292.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M290.024 122.012V122.012' fill='#0a0a85'/> +<path clip-path='url(#clip5)' d='M288.031 122.012H292.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M128.906 186.074H132.145V120.633H128.906ZM183.817 186.074H187.055V122.074H183.817ZM238.727 186.074H241.965V119.696H238.727ZM293.637 186.074H296.875V123.387H293.637Z' fill='#000076'/> +<path clip-path='url(#clip5)' d='M128.906 186.074H132.145V120.633H128.906ZM183.817 186.074H187.055V122.074H183.817ZM238.727 186.074H241.965V119.696H238.727ZM293.637 186.074H296.875V123.387H293.637Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M130.527 120.633V120.633' fill='#000076'/> +<path clip-path='url(#clip5)' d='M128.535 120.633H132.52' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M130.527 120.633V120.633' fill='#000076'/> +<path clip-path='url(#clip5)' d='M128.535 120.633H132.52' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M185.438 122.074V122.074' fill='#000076'/> +<path clip-path='url(#clip5)' d='M183.446 122.074H187.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M185.438 122.074V122.074' fill='#000076'/> +<path clip-path='url(#clip5)' d='M183.446 122.074H187.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M240.344 119.696V119.696' fill='#000076'/> +<path clip-path='url(#clip5)' d='M238.355 119.695H242.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M240.344 119.696V119.696' fill='#000076'/> +<path clip-path='url(#clip5)' d='M238.355 119.695H242.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M295.254 123.387V123.387' fill='#000076'/> +<path clip-path='url(#clip5)' d='M293.262 123.387H297.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M295.254 123.387V123.387' fill='#000076'/> +<path clip-path='url(#clip5)' d='M293.262 123.387H297.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip5)' d='M233.301 233.301H301.59V211.324H233.301Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 122.136 88.837)'> +<use x='114.487' xlink:href='#g1-72' y='129.265'/> +<use x='118.223' xlink:href='#g1-80' y='129.265'/> +<use x='121.604' xlink:href='#g1-45' y='129.265'/> +<use x='123.368' xlink:href='#g1-90' y='129.265'/> +<use x='126.603' xlink:href='#g1-52' y='129.265'/> +<use x='129.249' xlink:href='#g1-45' y='129.265'/> +<use x='131.013' xlink:href='#g1-71' y='129.265'/> +<use x='134.542' xlink:href='#g1-52' y='129.265'/> +<use x='137.188' xlink:href='#g1-44' y='129.265'/> +<use x='140.423' xlink:href='#g1-49' y='129.265'/> +<use x='143.069' xlink:href='#g1-54' y='129.265'/> +<use x='145.715' xlink:href='#g1-71' y='129.265'/> +<use x='149.244' xlink:href='#g1-98' y='129.265'/> +<use x='114.487' xlink:href='#g1-56' y='134.884'/> +<use x='117.133' xlink:href='#g1-45' y='134.884'/> +<use x='118.897' xlink:href='#g1-99' y='134.884'/> +<use x='121.25' xlink:href='#g1-111' y='134.884'/> +<use x='123.749' xlink:href='#g1-114' y='134.884'/> +<use x='125.556' xlink:href='#g1-101' y='134.884'/> +<use x='129.673' xlink:href='#g1-73' y='134.884'/> +<use x='131.143' xlink:href='#g1-110' y='134.884'/> +<use x='133.876' xlink:href='#g1-116' y='134.884'/> +<use x='135.787' xlink:href='#g1-101' y='134.884'/> +<use x='138.14' xlink:href='#g1-108' y='134.884'/> +<use x='141.166' xlink:href='#g1-88' y='134.884'/> +<use x='144.695' xlink:href='#g1-69' y='134.884'/> +<use x='147.869' xlink:href='#g1-79' y='134.884'/> +<use x='151.778' xlink:href='#g1-78' y='134.884'/> +<use x='157.278' xlink:href='#g1-64' y='134.884'/> +<use x='160.807' xlink:href='#g1-50' y='134.884'/> +<use x='163.453' xlink:href='#g1-46' y='134.884'/> +<use x='164.923' xlink:href='#g1-55' y='134.884'/> +<use x='167.57' xlink:href='#g1-71' y='134.884'/> +<use x='171.098' xlink:href='#g1-104' y='134.884'/> +<use x='173.831' xlink:href='#g1-122' y='134.884'/> +<use x='114.487' xlink:href='#g1-85' y='140.503'/> +<use x='118.119' xlink:href='#g1-98' y='140.503'/> +<use x='120.852' xlink:href='#g1-117' y='140.503'/> +<use x='123.585' xlink:href='#g1-110' y='140.503'/> +<use x='126.317' xlink:href='#g1-116' y='140.503'/> +<use x='128.229' xlink:href='#g1-117' y='140.503'/> +<use x='132.726' xlink:href='#g1-49' y='140.503'/> +<use x='135.372' xlink:href='#g1-56' y='140.503'/> +<use x='138.018' xlink:href='#g1-46' y='140.503'/> +<use x='139.489' xlink:href='#g1-48' y='140.503'/> +<use x='142.135' xlink:href='#g1-52' y='140.503'/> +<use x='144.781' xlink:href='#g1-46' y='140.503'/> +<use x='146.252' xlink:href='#g1-49' y='140.503'/> +<use x='148.898' xlink:href='#g1-44' y='140.503'/> +<use x='152.132' xlink:href='#g1-71' y='140.503'/> +<use x='155.661' xlink:href='#g1-67' y='140.503'/> +<use x='159.042' xlink:href='#g1-67' y='140.503'/> +<use x='164.188' xlink:href='#g1-55' y='140.503'/> +<use x='166.834' xlink:href='#g1-46' y='140.503'/> +<use x='168.305' xlink:href='#g1-52' y='140.503'/> +<use x='170.951' xlink:href='#g1-46' y='140.503'/> +<use x='172.421' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -50.186 231.913)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 4.724 231.913)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 59.633 231.913)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 114.543 231.913)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -44.955 211.999)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-51' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 9.954 234.23)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-57' y='140.503'/> +<use x='121.25' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 64.864 232.665)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-57' y='140.503'/> +<use x='121.25' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 119.773 231.537)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -39.725 231.788)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 15.185 232.289)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-57' y='140.503'/> +<use x='121.25' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 70.094 232.665)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-57' y='140.503'/> +<use x='121.25' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 125.004 231.6)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -34.494 231.913)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 20.415 234.23)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-57' y='140.503'/> +<use x='121.25' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 75.325 233.854)'> +<use x='114.487' xlink:href='#g1-48' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-57' y='140.503'/> +<use x='121.25' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 130.234 230.911)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -29.264 231.162)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 25.646 225.651)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-49' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 80.555 213.189)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-51' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 135.465 231.224)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -24.033 232.038)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 30.876 228.156)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 85.786 231.099)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 140.695 230.911)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -18.803 231.036)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 36.107 225.713)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-49' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 91.016 213.94)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-50' y='140.503'/> +<use x='121.25' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 145.926 230.348)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -13.572 215.068)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-50' y='140.503'/> +<use x='121.25' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 41.337 231.162)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 96.247 230.911)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 151.156 230.473)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -8.342 229.095)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-52' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 46.568 230.535)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 101.477 228.156)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 156.387 231.85)'> +<use x='114.487' xlink:href='#g1-49' y='140.503'/> +<use x='117.133' xlink:href='#g1-46' y='140.503'/> +<use x='118.603' xlink:href='#g1-48' y='140.503'/> +<use x='121.25' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -81.143 293.197)'> +<use x='114.487' xlink:href='#g0-82' y='140.503'/> +<use x='120.457' xlink:href='#g0-101' y='140.503'/> +<use x='124.553' xlink:href='#g0-108' y='140.503'/> +<use x='126.753' xlink:href='#g0-97' y='140.503'/> +<use x='131.181' xlink:href='#g0-116' y='140.503'/> +<use x='134.509' xlink:href='#g0-105' y='140.503'/> +<use x='136.709' xlink:href='#g0-118' y='140.503'/> +<use x='140.957' xlink:href='#g0-101' y='140.503'/> +<use x='148.124' xlink:href='#g0-116' y='140.503'/> +<use x='151.452' xlink:href='#g0-105' y='140.503'/> +<use x='153.652' xlink:href='#g0-109' y='140.503'/> +<use x='160.972' xlink:href='#g0-101' y='140.503'/> +<use x='168.139' xlink:href='#g2-40' y='140.503'/> +<use x='171.432' xlink:href='#g2-108' y='140.503'/> +<use x='173.453' xlink:href='#g2-111' y='140.503'/> +<use x='177.452' xlink:href='#g2-119' y='140.503'/> +<use x='183' xlink:href='#g2-101' y='140.503'/> +<use x='186.764' xlink:href='#g2-114' y='140.503'/> +<use x='192.479' xlink:href='#g2-105' y='140.503'/> +<use x='194.499' xlink:href='#g2-115' y='140.503'/> +<use x='200.568' xlink:href='#g2-98' y='140.503'/> +<use x='205.176' xlink:href='#g2-101' y='140.503'/> +<use x='208.94' xlink:href='#g2-116' y='140.503'/> +<use x='211.998' xlink:href='#g2-116' y='140.503'/> +<use x='215.056' xlink:href='#g2-101' y='140.503'/> +<use x='218.819' xlink:href='#g2-114' y='140.503'/> +<use x='221.711' xlink:href='#g2-41' y='140.503'/> +</g> +<path d='M82.348 231.446H323.027V214.453H82.348Z' fill='#ffffff'/> +<path d='M82.348 231.446H323.027V214.453H82.348Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M85.535 224.941H88.523V216.972H85.535ZM91.516 224.941H94.504V218.964H91.516Z' fill='#e0e0f0'/> +<path d='M85.535 224.941H88.523V216.972H85.535ZM91.516 224.941H94.504V218.964H91.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -33.522 84.43)'> +<use x='131.213' xlink:href='#g2-109' y='140.503'/> +<use x='137.938' xlink:href='#g2-105' y='140.503'/> +</g> +<path d='M109.625 224.941H112.613V216.973H109.625ZM115.602 224.941H118.59V218.965H115.602Z' fill='#c2c2e1'/> +<path d='M109.625 224.941H112.613V216.972H109.625ZM115.602 224.941H118.59V218.964H115.602Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.56 83.976)'> +<use x='154.339' xlink:href='#g2-116' y='140.503'/> +<use x='157.397' xlink:href='#g2-99' y='140.503'/> +</g> +<path d='M131.789 224.941H134.777V216.973H131.789ZM137.766 224.941H140.754V218.965H137.766Z' fill='#a3a3d1'/> +<path d='M131.789 224.941H134.777V216.972H131.789ZM137.766 224.941H140.754V218.964H137.766Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.159 84.43)'> +<use x='176.102' xlink:href='#g2-106' y='140.503'/> +<use x='178.357' xlink:href='#g2-101' y='140.503'/> +</g> +<path d='M153.152 224.941H156.141V216.973H153.152ZM159.129 224.941H162.117V218.965H159.129Z' fill='#8585c2'/> +<path d='M153.152 224.941H156.141V216.972H153.152ZM159.129 224.941H162.117V218.964H159.129Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.958 83.47)'> +<use x='198.263' xlink:href='#g2-115' y='140.503'/> +<use x='201.509' xlink:href='#g2-110' y='140.503'/> +</g> +<path d='M176.113 224.941H179.102V216.973H176.113ZM182.09 224.941H185.078V218.965H182.09Z' fill='#6666b3'/> +<path d='M176.113 224.941H179.102V216.972H176.113ZM182.09 224.941H185.078V218.964H182.09Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.781 83.47)'> +<use x='221.047' xlink:href='#g2-114' y='140.503'/> +<use x='223.939' xlink:href='#g2-112' y='140.503'/> +</g> +<path d='M198.719 224.941H201.707V216.973H198.719ZM204.695 224.941H207.684V218.965H204.695Z' fill='#4747a4'/> +<path d='M198.719 224.941H201.707V216.972H198.719ZM204.695 224.941H207.684V218.964H204.695Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.001 84.467)'> +<use x='249.874' xlink:href='#g2-104' y='140.503'/> +<use x='254.246' xlink:href='#g2-111' y='140.503'/> +<use x='258.481' xlink:href='#g2-97' y='140.503'/> +<use x='262.314' xlink:href='#g2-114' y='140.503'/> +<use x='265.206' xlink:href='#g2-100' y='140.503'/> +</g> +<path d='M233.766 224.941H236.754V216.973H233.766ZM239.742 224.941H242.731V218.965H239.742Z' fill='#292994'/> +<path d='M233.766 224.941H236.754V216.972H233.766ZM239.742 224.941H242.731V218.964H239.742Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.472 84.467)'> +<use x='283.392' xlink:href='#g2-103' y='140.503'/> +<use x='287.626' xlink:href='#g2-108' y='140.503'/> +<use x='289.646' xlink:href='#g2-105' y='140.503'/> +<use x='291.666' xlink:href='#g2-98' y='140.503'/> +<use x='296.274' xlink:href='#g2-99' y='140.503'/> +</g> +<path d='M265.754 224.941H268.742V216.973H265.754ZM271.73 224.941H274.719V218.965H271.73Z' fill='#0a0a85'/> +<path d='M265.754 224.941H268.742V216.972H265.754ZM271.73 224.941H274.719V218.964H271.73Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.051 84.467)'> +<use x='312.959' xlink:href='#g2-116' y='140.503'/> +<use x='316.017' xlink:href='#g2-98' y='140.503'/> +<use x='320.389' xlink:href='#g2-98' y='140.503'/> +</g> +<path d='M292.898 224.941H295.887V216.973H292.898ZM298.879 224.941H301.867V218.965H298.879Z' fill='#000076'/> +<path d='M292.898 224.941H295.887V216.972H292.898ZM298.879 224.941H301.867V218.964H298.879Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.145 84.43)'> +<use x='340.198' xlink:href='#g2-115' y='140.503'/> +<use x='343.444' xlink:href='#g2-109' y='140.503'/> +<use x='350.169' xlink:href='#g2-105' y='140.503'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-1.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-1.svg new file mode 100644 index 0000000..dacd8ab --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-1.svg @@ -0,0 +1,890 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<clipPath id='clip3'> +<path d='M82.148 203.937H434.164V78.691H82.148Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page3'> +<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 33.989)'> +<use x='114.487' xlink:href='#g2-99' y='183.949'/> +<use x='118.25' xlink:href='#g2-102' y='183.949'/> +<use x='120.838' xlink:href='#g2-114' y='183.949'/> +<use x='123.73' xlink:href='#g2-97' y='183.949'/> +<use x='127.798' xlink:href='#g2-99' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 41.401 33.989)'> +<use x='114.487' xlink:href='#g2-101' y='183.949'/> +<use x='118.25' xlink:href='#g2-115' y='183.949'/> +<use x='121.497' xlink:href='#g2-112' y='183.949'/> +<use x='125.634' xlink:href='#g2-114' y='183.949'/> +<use x='128.526' xlink:href='#g2-101' y='183.949'/> +<use x='132.29' xlink:href='#g2-115' y='183.949'/> +<use x='135.536' xlink:href='#g2-115' y='183.949'/> +<use x='138.782' xlink:href='#g2-111' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 103.095 33.989)'> +<use x='114.487' xlink:href='#g2-98' y='183.949'/> +<use x='118.859' xlink:href='#g2-97' y='183.949'/> +<use x='122.692' xlink:href='#g2-114' y='183.949'/> +<use x='125.584' xlink:href='#g2-110' y='183.949'/> +<use x='129.957' xlink:href='#g2-101' y='183.949'/> +<use x='133.72' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 162.903 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-101' y='183.949'/> +<use x='120.271' xlink:href='#g2-97' y='183.949'/> +<use x='124.339' xlink:href='#g2-110' y='183.949'/> +<use x='128.711' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 223.526 33.989)'> +<use x='114.487' xlink:href='#g2-114' y='183.949'/> +<use x='117.379' xlink:href='#g2-101' y='183.949'/> +<use x='121.142' xlink:href='#g2-100' y='183.949'/> +<use x='125.515' xlink:href='#g2-105' y='183.949'/> +<use x='127.535' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 277.054 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-97' y='183.949'/> +<use x='120.34' xlink:href='#g2-114' y='183.949'/> +<use x='123.232' xlink:href='#g2-115' y='183.949'/> +<use x='126.478' xlink:href='#g2-111' y='183.949'/> +<use x='130.712' xlink:href='#g2-110' y='183.949'/> +<use x='135.085' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 21.624)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.688)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.999)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -72.311)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.622)'> +<use x='114.487' xlink:href='#g1-50' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<path clip-path='url(#clip3)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M87.949 141.316V141.004' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M87.949 141.316V141.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M85.953 141.004H89.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M87.949 141.316V141.629' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M87.949 141.316V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M89.941 141.629H85.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M146.617 141.316V138.937' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M146.617 141.316V138.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M144.625 138.938H148.61' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M146.617 141.316V143.695' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M146.617 141.316V143.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M148.61 143.695H144.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M205.285 141.316V141.066' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M205.285 141.316V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M203.293 141.067H207.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M205.285 141.316V141.566' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M205.285 141.316V141.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M207.278 141.567H203.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M263.953 141.316V141.066' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M263.953 141.316V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M261.961 141.067H265.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M263.953 141.316V141.566' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M263.953 141.316V141.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M265.949 141.567H261.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M322.625 141.316V140.812' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M322.625 141.316V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M320.629 140.812H324.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M322.625 141.316V141.816' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M322.625 141.316V141.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M324.617 141.816H320.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M381.293 141.316V140' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M381.293 141.316V140' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M379.301 140H383.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M381.293 141.316V142.629' fill='#e0e0f0'/> +<path clip-path='url(#clip3)' d='M381.293 141.316V142.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M383.285 142.629H379.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M91.559 203.937H94.797V139.562H91.559ZM150.227 203.937H153.465V138.621H150.227ZM208.899 203.937H212.133V141.441H208.899ZM267.567 203.937H270.805V138.683H267.567ZM326.234 203.937H329.473V137.871H326.234ZM384.902 203.937H388.141V129.855H384.902Z' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M91.559 203.937H94.797V139.562H91.559ZM150.227 203.937H153.465V138.621H150.227ZM208.899 203.937H212.133V141.441H208.899ZM267.567 203.937H270.805V138.683H267.567ZM326.234 203.937H329.473V137.871H326.234ZM384.902 203.937H388.141V129.855H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M93.18 139.562V139.562' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M91.184 139.563H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M93.18 139.562V139.562' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M91.184 139.563H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M151.848 138.621V138.621' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M149.855 138.621H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M151.848 138.621V138.621' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M149.855 138.621H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M210.516 141.441V141.254' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M210.516 141.441V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M208.523 141.254H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M210.516 141.441V141.629' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M210.516 141.441V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M212.508 141.629H208.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M269.184 138.683V138.621' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M269.184 138.683V138.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M267.191 138.621H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M269.184 138.683V138.746' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M269.184 138.683V138.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M271.179 138.746H267.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M327.856 137.871V137.558' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M327.856 137.871V137.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M325.859 137.559H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M327.856 137.871V138.183' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M327.856 137.871V138.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M329.847 138.183H325.863' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M386.524 129.855V129.543' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M386.524 129.855V129.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M384.531 129.543H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M386.524 129.855V130.168' fill='#c2c2e1'/> +<path clip-path='url(#clip3)' d='M386.524 129.855V130.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M388.515 130.168H384.531' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M96.789 203.937H100.027V138.746H96.789ZM155.457 203.937H158.695V135.867H155.457ZM214.129 203.937H217.363V141.379H214.129ZM272.797 203.937H276.035V140.25H272.797ZM331.465 203.937H334.703V130.918H331.465ZM390.133 203.937H393.371V115.515H390.133Z' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M96.789 203.937H100.027V138.746H96.789ZM155.457 203.937H158.695V135.867H155.457ZM214.129 203.937H217.363V141.379H214.129ZM272.797 203.937H276.035V140.25H272.797ZM331.465 203.937H334.703V130.918H331.465ZM390.133 203.937H393.371V115.515H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M98.41 138.746V138.558' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M98.41 138.746V138.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M96.414 138.559H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M98.41 138.746V138.937' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M98.41 138.746V138.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M100.402 138.938H96.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M157.078 135.867V135.867' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M155.086 135.867H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M157.078 135.867V135.867' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M155.086 135.867H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M215.746 141.379V141.129' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M215.746 141.379V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M213.754 141.128H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M215.746 141.379V141.629' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M215.746 141.379V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M217.739 141.629H213.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M274.414 140.25V140.187' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M274.414 140.25V140.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M272.422 140.187H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M274.414 140.25V140.312' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M274.414 140.25V140.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M276.41 140.312H272.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M333.086 130.918V130.73' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M333.086 130.918V130.73' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M331.09 130.73H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M333.086 130.918V131.109' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M333.086 130.918V131.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M335.078 131.11H331.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M391.754 115.515V114.636' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M391.754 115.515V114.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M389.762 114.637H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M391.754 115.515V116.39' fill='#a3a3d1'/> +<path clip-path='url(#clip3)' d='M391.754 115.515V116.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M393.746 116.39H389.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M102.02 203.937H105.258V130.293H102.02ZM160.688 203.937H163.926V133.176H160.688ZM219.359 203.937H222.594V141.066H219.359ZM278.027 203.937H281.266V139.312H278.027ZM336.695 203.937H339.934V136.679H336.695ZM395.363 203.937H398.602V96.789H395.363Z' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M102.02 203.937H105.258V130.293H102.02ZM160.688 203.937H163.926V133.176H160.688ZM219.359 203.937H222.594V141.066H219.359ZM278.027 203.937H281.266V139.312H278.027ZM336.695 203.937H339.934V136.679H336.695ZM395.363 203.937H398.602V96.789H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M103.641 130.293V129.98' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M103.641 130.293V129.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M101.644 129.981H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M103.641 130.293V130.605' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M103.641 130.293V130.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M105.633 130.606H101.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M162.309 133.176V133.176' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M160.316 133.176H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M162.309 133.176V133.176' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M160.316 133.176H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M220.977 141.066V140.941' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M220.977 141.066V140.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M218.984 140.942H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M220.977 141.066V141.191' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M220.977 141.066V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M222.969 141.191H218.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M279.645 139.312V139.125' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M279.645 139.312V139.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M277.652 139.125H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M279.645 139.312V139.5' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M279.645 139.312V139.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M281.64 139.5H277.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M338.317 136.679V136.554' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M338.317 136.679V136.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M336.32 136.555H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M338.317 136.679V136.804' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M338.317 136.679V136.804' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M340.308 136.804H336.324' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M396.984 96.789V96.164' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M396.984 96.789V96.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M394.992 96.164H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M396.984 96.789V97.418' fill='#8585c2'/> +<path clip-path='url(#clip3)' d='M396.984 96.789V97.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M398.976 97.418H394.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M107.25 203.937H110.488V138.621H107.25ZM165.918 203.937H169.156V137.683H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V131.859H283.258ZM341.926 203.937H345.164V132.988H341.926ZM400.594 203.937H403.832V124.844H400.594Z' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M107.25 203.937H110.488V138.621H107.25ZM165.918 203.937H169.156V137.683H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V131.859H283.258ZM341.926 203.937H345.164V132.988H341.926ZM400.594 203.937H403.832V124.844H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M108.871 138.621V138.433' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M108.871 138.621V138.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M106.875 138.434H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M108.871 138.621V138.808' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M108.871 138.621V138.808' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M110.864 138.808H106.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M167.539 137.683V136.429' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M167.539 137.683V136.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M165.547 136.43H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M167.539 137.683V138.937' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M167.539 137.683V138.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M169.532 138.938H165.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M226.207 141.254V141.066' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M226.207 141.254V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M224.215 141.067H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M226.207 141.254V141.441' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M226.207 141.254V141.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M228.2 141.442H224.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M284.875 131.859V131.609' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M284.875 131.859V131.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M282.883 131.61H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M284.875 131.859V132.109' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M284.875 131.859V132.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M286.868 132.11H282.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M343.547 132.988V132.988' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M341.551 132.988H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M343.547 132.988V132.988' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M341.551 132.988H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M402.215 124.844V124.844' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M400.223 124.843H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M402.215 124.844V124.844' fill='#6666b3'/> +<path clip-path='url(#clip3)' d='M400.223 124.843H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M112.481 203.937H115.719V136.179H112.481ZM171.149 203.937H174.387V133.176H171.149ZM229.82 203.937H233.055V140.941H229.82ZM288.488 203.937H291.727V134.051H288.488ZM347.156 203.937H350.395V109.129H347.156ZM405.824 203.937H409.063V123.469H405.824Z' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M112.481 203.937H115.719V136.179H112.481ZM171.149 203.937H174.387V133.176H171.149ZM229.82 203.937H233.055V140.941H229.82ZM288.488 203.937H291.727V134.051H288.488ZM347.156 203.937H350.395V109.129H347.156ZM405.824 203.937H409.063V123.469H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M114.098 136.179V135.867' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M114.098 136.179V135.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M112.105 135.867H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M114.098 136.179V136.492' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M114.098 136.179V136.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M116.094 136.492H112.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M172.77 133.176V133.176' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M170.777 133.176H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M172.77 133.176V133.176' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M170.777 133.176H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M231.438 140.941V140.687' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M231.438 140.941V140.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M229.445 140.687H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M231.438 140.941V141.191' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M231.438 140.941V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M233.43 141.191H229.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M290.106 134.051V133.926' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M290.106 134.051V133.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M288.113 133.926H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M290.106 134.051V134.176' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M290.106 134.051V134.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M292.098 134.176H288.113' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M348.777 109.129V108.937' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M348.777 109.129V108.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M346.781 108.937H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M348.777 109.129V109.316' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M348.777 109.129V109.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M350.769 109.316H346.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M407.445 123.469V122.465' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M407.445 123.469V122.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M405.453 122.465H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M407.445 123.469V124.469' fill='#4747a4'/> +<path clip-path='url(#clip3)' d='M407.445 123.469V124.469' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M409.437 124.469H405.453' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M117.711 203.937H120.949V139.062H117.711ZM176.379 203.937H179.617V133.176H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V131.734H293.719ZM352.387 203.937H355.625V133.238H352.387ZM411.055 203.937H414.293V124.781H411.055Z' fill='#292994'/> +<path clip-path='url(#clip3)' d='M117.711 203.937H120.949V139.062H117.711ZM176.379 203.937H179.617V133.176H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V131.734H293.719ZM352.387 203.937H355.625V133.238H352.387ZM411.055 203.937H414.293V124.781H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M119.328 139.062V138.871' fill='#292994'/> +<path clip-path='url(#clip3)' d='M119.328 139.062V138.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M117.336 138.871H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M119.328 139.062V139.25' fill='#292994'/> +<path clip-path='url(#clip3)' d='M119.328 139.062V139.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M121.325 139.25H117.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M178 133.176V133.176' fill='#292994'/> +<path clip-path='url(#clip3)' d='M176.008 133.176H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M178 133.176V133.176' fill='#292994'/> +<path clip-path='url(#clip3)' d='M176.008 133.176H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M236.668 140.941V140.5' fill='#292994'/> +<path clip-path='url(#clip3)' d='M236.668 140.941V140.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M234.676 140.5H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M236.668 140.941V141.379' fill='#292994'/> +<path clip-path='url(#clip3)' d='M236.668 140.941V141.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M238.66 141.379H234.675' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M295.336 131.734V131.672' fill='#292994'/> +<path clip-path='url(#clip3)' d='M295.336 131.734V131.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M293.344 131.672H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M295.336 131.734V131.797' fill='#292994'/> +<path clip-path='url(#clip3)' d='M295.336 131.734V131.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M297.328 131.797H293.343' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M354.008 133.238V133.176' fill='#292994'/> +<path clip-path='url(#clip3)' d='M354.008 133.238V133.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M352.012 133.175H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M354.008 133.238V133.301' fill='#292994'/> +<path clip-path='url(#clip3)' d='M354.008 133.238V133.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M355.999 133.301H352.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M412.676 124.781V124.719' fill='#292994'/> +<path clip-path='url(#clip3)' d='M412.676 124.781V124.719' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M410.684 124.719H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M412.676 124.781V124.844' fill='#292994'/> +<path clip-path='url(#clip3)' d='M412.676 124.781V124.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M414.667 124.843H410.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M122.941 203.937H126.18V127.601H122.941ZM181.609 203.937H184.848V131.797H181.609ZM240.281 203.937H243.516V141.316H240.281ZM298.949 203.937H302.188V140H298.949ZM357.617 203.937H360.856V109.691H357.617ZM416.285 203.937H419.524V105.308H416.285Z' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M122.941 203.937H126.18V127.601H122.941ZM181.609 203.937H184.848V131.797H181.609ZM240.281 203.937H243.516V141.316H240.281ZM298.949 203.937H302.188V140H298.949ZM357.617 203.937H360.856V109.691H357.617ZM416.285 203.937H419.524V105.308H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M124.559 127.601V127.351' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M124.559 127.601V127.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M122.566 127.351H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M124.559 127.601V127.851' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M124.559 127.601V127.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M126.555 127.851H122.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M183.231 131.797V129.418' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M183.231 131.797V129.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M181.238 129.418H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M183.231 131.797V134.176' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M183.231 131.797V134.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M185.223 134.176H181.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M241.899 141.316V141.129' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M241.899 141.316V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M239.906 141.128H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M241.899 141.316V141.504' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M241.899 141.316V141.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M243.891 141.504H239.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M300.567 140V139.875' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M300.567 140V139.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M298.574 139.875H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M300.567 140V140.125' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M300.567 140V140.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M302.559 140.125H298.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M359.238 109.691V108.812' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M359.238 109.691V108.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M357.242 108.813H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M359.238 109.691V110.566' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M359.238 109.691V110.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M361.23 110.566H357.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M417.906 105.308V104.554' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M417.906 105.308V104.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M415.914 104.555H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M417.906 105.308V106.058' fill='#0a0a85'/> +<path clip-path='url(#clip3)' d='M417.906 105.308V106.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M419.898 106.059H415.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M128.172 203.937H131.41V116.828H128.172ZM186.84 203.937H190.078V126.785H186.84ZM245.512 203.937H248.746V144.195H245.512ZM362.848 203.937H366.086V117.582H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='#000076'/> +<path clip-path='url(#clip3)' d='M128.172 203.937H131.41V116.828H128.172ZM186.84 203.937H190.078V126.785H186.84ZM245.512 203.937H248.746V144.195H245.512ZM362.848 203.937H366.086V117.582H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M129.789 116.828V116.515' fill='#000076'/> +<path clip-path='url(#clip3)' d='M129.789 116.828V116.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M127.797 116.516H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M129.789 116.828V117.144' fill='#000076'/> +<path clip-path='url(#clip3)' d='M129.789 116.828V117.144' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M131.785 117.145H127.8' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M188.461 126.785V124.219' fill='#000076'/> +<path clip-path='url(#clip3)' d='M188.461 126.785V124.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M186.469 124.219H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M188.461 126.785V129.355' fill='#000076'/> +<path clip-path='url(#clip3)' d='M188.461 126.785V129.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M190.453 129.355H186.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M247.129 144.195V144.07' fill='#000076'/> +<path clip-path='url(#clip3)' d='M247.129 144.195V144.07' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M245.137 144.071H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M247.129 144.195V144.32' fill='#000076'/> +<path clip-path='url(#clip3)' d='M247.129 144.195V144.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M249.121 144.32H245.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M364.469 117.582V117.269' fill='#000076'/> +<path clip-path='url(#clip3)' d='M364.469 117.582V117.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M362.473 117.269H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M364.469 117.582V117.894' fill='#000076'/> +<path clip-path='url(#clip3)' d='M364.469 117.582V117.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M366.46 117.894H362.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M423.137 78.691V78.691' fill='#000076'/> +<path clip-path='url(#clip3)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M423.137 78.691V78.691' fill='#000076'/> +<path clip-path='url(#clip3)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M133.402 203.937H136.641V140.5H133.402ZM192.07 203.937H195.309V138.621H192.07ZM250.742 203.937H253.977V140.875H250.742ZM309.41 203.937H312.649V140.625H309.41ZM368.078 203.937H371.317V141.066H368.078ZM426.746 203.937H429.984V142.629H426.746Z' fill='#000067'/> +<path clip-path='url(#clip3)' d='M133.402 203.937H136.641V140.5H133.402ZM192.07 203.937H195.309V138.621H192.07ZM250.742 203.937H253.977V140.875H250.742ZM309.41 203.937H312.649V140.625H309.41ZM368.078 203.937H371.317V141.066H368.078ZM426.746 203.937H429.984V142.629H426.746Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M135.02 140.5V140.187' fill='#000067'/> +<path clip-path='url(#clip3)' d='M135.02 140.5V140.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M133.027 140.187H137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M135.02 140.5V140.812' fill='#000067'/> +<path clip-path='url(#clip3)' d='M135.02 140.5V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M137.016 140.812H133.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M193.692 138.621V138.621' fill='#000067'/> +<path clip-path='url(#clip3)' d='M191.699 138.621H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M193.692 138.621V138.621' fill='#000067'/> +<path clip-path='url(#clip3)' d='M191.699 138.621H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M252.359 140.875V140.5' fill='#000067'/> +<path clip-path='url(#clip3)' d='M252.359 140.875V140.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M250.367 140.5H254.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M252.359 140.875V141.254' fill='#000067'/> +<path clip-path='url(#clip3)' d='M252.359 140.875V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M254.352 141.254H250.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M311.027 140.625V140.375' fill='#000067'/> +<path clip-path='url(#clip3)' d='M311.027 140.625V140.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M309.035 140.375H313.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M311.027 140.625V140.875' fill='#000067'/> +<path clip-path='url(#clip3)' d='M311.027 140.625V140.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M313.02 140.875H309.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M369.699 141.066V140.812' fill='#000067'/> +<path clip-path='url(#clip3)' d='M369.699 141.066V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M367.703 140.812H371.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M369.699 141.066V141.316' fill='#000067'/> +<path clip-path='url(#clip3)' d='M369.699 141.066V141.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M371.692 141.316H367.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M428.367 142.629V140.062' fill='#000067'/> +<path clip-path='url(#clip3)' d='M428.367 142.629V140.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M426.375 140.063H430.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M428.367 142.629V145.199' fill='#000067'/> +<path clip-path='url(#clip3)' d='M428.367 142.629V145.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip3)' d='M430.359 145.199H426.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -94.367 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -35.698 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 22.971 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 81.64 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 140.309 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 198.978 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -89.137 248.024)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -30.468 247.085)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 28.201 249.903)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 86.87 247.147)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 145.539 246.333)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 204.208 238.318)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -83.906 247.21)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -25.237 244.329)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 33.432 249.84)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 92.101 248.713)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 150.77 239.382)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 209.439 223.977)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -78.676 238.756)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -20.007 241.637)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 38.662 249.527)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 97.331 247.774)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 156 245.143)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 214.669 205.253)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -73.445 247.085)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -14.776 246.145)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 43.893 249.715)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 102.562 240.321)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 161.231 241.449)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 219.9 233.308)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -68.215 244.642)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -9.546 241.637)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 49.123 249.402)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 107.792 242.513)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 166.461 217.589)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 225.13 231.93)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -62.984 247.523)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -4.315 241.637)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 54.354 249.402)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 113.023 240.196)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 171.692 241.699)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 230.361 233.245)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -57.754 236.063)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 0.915 240.259)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 59.584 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 118.253 248.462)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 176.922 218.153)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 235.591 213.769)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -52.524 225.292)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-51' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 6.145 235.249)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 64.814 252.658)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 182.152 226.043)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-51' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 240.821 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-50' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-52' y='183.949'/> +<use x='126.877' xlink:href='#g1-52' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -47.293 248.963)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 11.376 247.085)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 70.045 249.339)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 128.714 249.089)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 187.383 249.527)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 246.052 251.093)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -124.589 311.062)'> +<use x='114.487' xlink:href='#g0-82' y='183.949'/> +<use x='120.457' xlink:href='#g0-101' y='183.949'/> +<use x='124.553' xlink:href='#g0-108' y='183.949'/> +<use x='126.753' xlink:href='#g0-97' y='183.949'/> +<use x='131.181' xlink:href='#g0-116' y='183.949'/> +<use x='134.509' xlink:href='#g0-105' y='183.949'/> +<use x='136.709' xlink:href='#g0-118' y='183.949'/> +<use x='140.957' xlink:href='#g0-101' y='183.949'/> +<use x='148.124' xlink:href='#g0-116' y='183.949'/> +<use x='151.452' xlink:href='#g0-105' y='183.949'/> +<use x='153.652' xlink:href='#g0-109' y='183.949'/> +<use x='160.972' xlink:href='#g0-101' y='183.949'/> +<use x='168.139' xlink:href='#g2-40' y='183.949'/> +<use x='171.432' xlink:href='#g2-108' y='183.949'/> +<use x='173.453' xlink:href='#g2-111' y='183.949'/> +<use x='177.452' xlink:href='#g2-119' y='183.949'/> +<use x='183' xlink:href='#g2-101' y='183.949'/> +<use x='186.764' xlink:href='#g2-114' y='183.949'/> +<use x='192.479' xlink:href='#g2-105' y='183.949'/> +<use x='194.499' xlink:href='#g2-115' y='183.949'/> +<use x='200.568' xlink:href='#g2-98' y='183.949'/> +<use x='205.176' xlink:href='#g2-101' y='183.949'/> +<use x='208.94' xlink:href='#g2-116' y='183.949'/> +<use x='211.998' xlink:href='#g2-116' y='183.949'/> +<use x='215.056' xlink:href='#g2-101' y='183.949'/> +<use x='218.819' xlink:href='#g2-114' y='183.949'/> +<use x='221.711' xlink:href='#g2-41' y='183.949'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-2.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-2.svg new file mode 100644 index 0000000..9990cdc --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-2.svg @@ -0,0 +1,1146 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='243.704pt' version='1.1' viewBox='106.737 54.995 381.623 243.704' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<clipPath id='clip4'> +<path d='M135.949 249.281H487.961V81.515H135.949Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/> +<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/> +<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/> +<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/> +<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/> +<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/> +<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/> +<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/> +<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/> +<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/> +<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/> +<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/> +<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/> +<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/> +<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page4'> +<path d='M194.617 258.136V249.281M253.285 258.136V249.281M311.953 258.136V249.281M370.625 258.136V249.281M429.293 258.136V249.281M194.617 72.66V81.515M253.285 72.66V81.515M311.953 72.66V81.515M370.625 72.66V81.515M429.293 72.66V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.265V81.515M223.953 77.265V81.515M282.621 77.265V81.515M341.289 77.265V81.515M399.957 77.265V81.515M458.629 77.265V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.515H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.515H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 249.281V81.515H487.961V249.281H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 61.588)'> +<use x='168.285' xlink:href='#g2-97' y='201.694'/> +<use x='172.353' xlink:href='#g2-108' y='201.694'/> +<use x='174.373' xlink:href='#g2-108' y='201.694'/> +<use x='176.393' xlink:href='#g2-111' y='201.694'/> +<use x='180.863' xlink:href='#g2-99' y='201.694'/> +<use x='184.627' xlink:href='#g2-45' y='201.694'/> +<use x='187.449' xlink:href='#g2-116' y='201.694'/> +<use x='190.507' xlink:href='#g2-101' y='201.694'/> +<use x='194.271' xlink:href='#g2-115' y='201.694'/> +<use x='197.517' xlink:href='#g2-116' y='201.694'/> +<use x='200.575' xlink:href='#g2-49' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 36.532 61.588)'> +<use x='168.285' xlink:href='#g2-97' y='201.694'/> +<use x='172.353' xlink:href='#g2-108' y='201.694'/> +<use x='174.373' xlink:href='#g2-108' y='201.694'/> +<use x='176.393' xlink:href='#g2-111' y='201.694'/> +<use x='180.863' xlink:href='#g2-99' y='201.694'/> +<use x='184.627' xlink:href='#g2-45' y='201.694'/> +<use x='187.449' xlink:href='#g2-116' y='201.694'/> +<use x='190.507' xlink:href='#g2-101' y='201.694'/> +<use x='194.271' xlink:href='#g2-115' y='201.694'/> +<use x='197.517' xlink:href='#g2-116' y='201.694'/> +<use x='200.575' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 94.98 61.588)'> +<use x='168.285' xlink:href='#g2-115' y='201.694'/> +<use x='171.531' xlink:href='#g2-104' y='201.694'/> +<use x='175.904' xlink:href='#g2-54' y='201.694'/> +<use x='180.138' xlink:href='#g2-98' y='201.694'/> +<use x='184.746' xlink:href='#g2-101' y='201.694'/> +<use x='188.509' xlink:href='#g2-110' y='201.694'/> +<use x='192.882' xlink:href='#g2-99' y='201.694'/> +<use x='196.646' xlink:href='#g2-104' y='201.694'/> +<use x='201.018' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 153.649 61.588)'> +<use x='168.285' xlink:href='#g2-115' y='201.694'/> +<use x='171.531' xlink:href='#g2-104' y='201.694'/> +<use x='175.904' xlink:href='#g2-56' y='201.694'/> +<use x='180.138' xlink:href='#g2-98' y='201.694'/> +<use x='184.746' xlink:href='#g2-101' y='201.694'/> +<use x='188.509' xlink:href='#g2-110' y='201.694'/> +<use x='192.882' xlink:href='#g2-99' y='201.694'/> +<use x='196.646' xlink:href='#g2-104' y='201.694'/> +<use x='201.018' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 207.225 61.588)'> +<use x='168.285' xlink:href='#g2-120' y='201.694'/> +<use x='172.187' xlink:href='#g2-109' y='201.694'/> +<use x='178.912' xlink:href='#g2-97' y='201.694'/> +<use x='182.98' xlink:href='#g2-108' y='201.694'/> +<use x='185' xlink:href='#g2-108' y='201.694'/> +<use x='187.02' xlink:href='#g2-111' y='201.694'/> +<use x='191.49' xlink:href='#g2-99' y='201.694'/> +<use x='195.254' xlink:href='#g2-45' y='201.694'/> +<use x='198.076' xlink:href='#g2-116' y='201.694'/> +<use x='201.134' xlink:href='#g2-101' y='201.694'/> +<use x='204.898' xlink:href='#g2-115' y='201.694'/> +<use x='208.144' xlink:href='#g2-116' y='201.694'/> +<use x='211.202' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 263.494 61.588)'> +<use x='168.285' xlink:href='#g2-99' y='201.694'/> +<use x='172.049' xlink:href='#g2-97' y='201.694'/> +<use x='176.117' xlink:href='#g2-99' y='201.694'/> +<use x='179.88' xlink:href='#g2-104' y='201.694'/> +<use x='184.253' xlink:href='#g2-101' y='201.694'/> +<use x='188.017' xlink:href='#g2-45' y='201.694'/> +<use x='190.839' xlink:href='#g2-115' y='201.694'/> +<use x='194.086' xlink:href='#g2-99' y='201.694'/> +<use x='197.849' xlink:href='#g2-114' y='201.694'/> +<use x='200.741' xlink:href='#g2-97' y='201.694'/> +<use x='204.81' xlink:href='#g2-116' y='201.694'/> +<use x='207.868' xlink:href='#g2-99' y='201.694'/> +<use x='211.631' xlink:href='#g2-104' y='201.694'/> +<use x='216.004' xlink:href='#g2-78' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 49.223)'> +<use x='168.285' xlink:href='#g1-48' y='201.694'/> +<use x='170.931' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 15.67)'> +<use x='168.285' xlink:href='#g1-48' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -17.883)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -51.436)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -84.989)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -118.543)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-53' y='201.694'/> +<use x='175.048' xlink:href='#g1-120' y='201.694'/> +</g> +<path clip-path='url(#clip4)' d='M135.949 182.176H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M141.746 182.176V181.906' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M141.746 182.176V181.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M139.754 181.907H143.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M141.746 182.176V182.445' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M141.746 182.176V182.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M143.739 182.446H139.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M200.414 182.176V181.773' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M200.414 182.176V181.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M198.422 181.774H202.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M200.414 182.176V182.578' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M200.414 182.176V182.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M202.406 182.578H198.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M259.082 182.176V180.297' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M259.082 182.176V180.297' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M257.09 180.297H261.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M259.082 182.176V184.054' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M259.082 182.176V184.054' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M261.074 184.055H257.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M317.754 182.176V181.57' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M317.754 182.176V181.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M315.762 181.57H319.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M317.754 182.176V182.781' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M317.754 182.176V182.781' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M319.746 182.781H315.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M376.422 182.176V181.035' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M376.422 182.176V181.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M374.43 181.035H378.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M376.422 182.176V183.316' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M376.422 182.176V183.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M378.414 183.316H374.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M435.09 182.176V179.156' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M435.09 182.176V179.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M433.098 179.156H437.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M435.09 182.176V185.195' fill='#e0e0f0'/> +<path clip-path='url(#clip4)' d='M435.09 182.176V185.195' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M437.082 185.195H433.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M145.356 249.281H148.594V181.371H145.356ZM204.028 249.281H207.266V179.492H204.028ZM262.695 249.281H265.934V149.898H262.695ZM321.363 249.281H324.602V81.515H321.363ZM380.031 249.281H383.27V81.515H380.031ZM438.703 249.281H441.942V81.515H438.703Z' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M145.356 249.281H148.594V181.371H145.356ZM204.028 249.281H207.266V179.492H204.028ZM262.695 249.281H265.934V149.898H262.695ZM321.363 249.281H324.602V81.515H321.363ZM380.031 249.281H383.27V81.515H380.031ZM438.703 249.281H441.942V81.515H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M146.977 181.371V181.238' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M146.977 181.371V181.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M144.984 181.239H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M146.977 181.371V181.504' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M146.977 181.371V181.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M148.969 181.504H144.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M205.645 179.492V179.359' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M205.645 179.492V179.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M203.652 179.36H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M205.645 179.492V179.625' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M205.645 179.492V179.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M207.636 179.625H203.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M264.313 149.898V149.359' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M264.313 149.898V149.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M262.32 149.359H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M264.313 149.898V150.433' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M264.313 149.898V150.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M266.304 150.434H262.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M322.984 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M320.992 81.516H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M322.984 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M320.992 81.516H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M381.652 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M379.66 81.516H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M381.652 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M379.66 81.516H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M440.32 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M438.328 81.516H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M440.32 81.515V81.515' fill='#c2c2e1'/> +<path clip-path='url(#clip4)' d='M438.328 81.516H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M150.586 249.281H153.824V178.687H150.586ZM209.258 249.281H212.496V177.679H209.258ZM267.926 249.281H271.164V81.515H267.926ZM326.594 249.281H329.832V133.39H326.594ZM385.262 249.281H388.5V110.91H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M150.586 249.281H153.824V178.687H150.586ZM209.258 249.281H212.496V177.679H209.258ZM267.926 249.281H271.164V81.515H267.926ZM326.594 249.281H329.832V133.39H326.594ZM385.262 249.281H388.5V110.91H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M152.207 178.687V178.418' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M152.207 178.687V178.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M150.215 178.418H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M152.207 178.687V178.953' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M152.207 178.687V178.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M154.2 178.953H150.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M210.875 177.679V177.547' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M210.875 177.679V177.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M208.883 177.547H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M210.875 177.679V177.812' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M210.875 177.679V177.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M212.867 177.812H208.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M269.543 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M267.551 81.516H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M269.543 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M267.551 81.516H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M328.215 133.39V131.176' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M328.215 133.39V131.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M326.223 131.176H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M328.215 133.39V135.605' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M328.215 133.39V135.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M330.207 135.606H326.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M386.883 110.91V110.371' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M386.883 110.91V110.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M384.891 110.371H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M386.883 110.91V111.445' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M386.883 110.91V111.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M388.875 111.445H384.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M445.551 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M445.551 81.515V81.515' fill='#a3a3d1'/> +<path clip-path='url(#clip4)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M155.817 249.281H159.055V161.91H155.817ZM214.488 249.281H217.727V158.219H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V150.097H331.824ZM390.492 249.281H393.731V162.445H390.492ZM449.164 249.281H452.402V181.101H449.164Z' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M155.817 249.281H159.055V161.91H155.817ZM214.488 249.281H217.727V158.219H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V150.097H331.824ZM390.492 249.281H393.731V162.445H390.492ZM449.164 249.281H452.402V181.101H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M157.438 161.91V161.777' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M157.438 161.91V161.777' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M155.445 161.777H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M157.438 161.91V162.043' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M157.438 161.91V162.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M159.43 162.043H155.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M216.106 158.219V158.019' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M216.106 158.219V158.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M214.113 158.02H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M216.106 158.219V158.422' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M216.106 158.219V158.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M218.098 158.422H214.113' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M274.774 81.515V81.515' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M274.774 81.515V81.515' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M333.445 150.097V149.496' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M333.445 150.097V149.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M331.453 149.496H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M333.445 150.097V150.703' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M333.445 150.097V150.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M335.437 150.703H331.449' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M392.113 162.445V162.179' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M392.113 162.445V162.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M390.121 162.18H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M392.113 162.445V162.715' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M392.113 162.445V162.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M394.105 162.714H390.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M450.781 181.101V177.41' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M450.781 181.101V177.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M448.789 177.411H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M450.781 181.101V184.793' fill='#8585c2'/> +<path clip-path='url(#clip4)' d='M450.781 181.101V184.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M452.773 184.793H448.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M161.047 249.281H164.285V169.023H161.047ZM219.719 249.281H222.957V168.152H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V81.515H337.055ZM395.723 249.281H398.961V81.515H395.723ZM454.395 249.281H457.633V81.515H454.395Z' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M161.047 249.281H164.285V169.023H161.047ZM219.719 249.281H222.957V168.152H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V81.515H337.055ZM395.723 249.281H398.961V81.515H395.723ZM454.395 249.281H457.633V81.515H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M162.668 169.023V168.957' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M162.668 169.023V168.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M160.676 168.957H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M162.668 169.023V169.09' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M162.668 169.023V169.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M164.661 169.089H160.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M221.336 168.152V168.015' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M221.336 168.152V168.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M219.344 168.016H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M221.336 168.152V168.285' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M221.336 168.152V168.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M223.329 168.285H219.344' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M280.004 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M280.004 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M338.676 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M336.684 81.516H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M338.676 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M336.684 81.516H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M397.344 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M395.352 81.516H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M397.344 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M395.352 81.516H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M456.012 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M454.02 81.516H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M456.012 81.515V81.515' fill='#6666b3'/> +<path clip-path='url(#clip4)' d='M454.02 81.516H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M166.278 249.281H169.516V175.734H166.278ZM224.949 249.281H228.188V169.023H224.949ZM283.617 249.281H286.856V107.488H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M166.278 249.281H169.516V175.734H166.278ZM224.949 249.281H228.188V169.023H224.949ZM283.617 249.281H286.856V107.488H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M167.899 175.734V175.465' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M167.899 175.734V175.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M165.906 175.465H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M167.899 175.734V176.004' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M167.899 175.734V176.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M169.891 176.004H165.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M226.567 169.023V168.554' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M226.567 169.023V168.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M224.574 168.555H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M226.567 169.023V169.492' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M226.567 169.023V169.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M228.559 169.492H224.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M285.234 107.488V107.015' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M285.234 107.488V107.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M283.242 107.015H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M285.234 107.488V107.957' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M285.234 107.488V107.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M287.227 107.957H283.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M343.906 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M343.906 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M402.574 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M402.574 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M461.242 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M461.242 81.515V81.515' fill='#4747a4'/> +<path clip-path='url(#clip4)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M171.508 249.281H174.746V168.82H171.508ZM230.18 249.281H233.414V168.621H230.18ZM288.848 249.281H292.086V81.515H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='#292994'/> +<path clip-path='url(#clip4)' d='M171.508 249.281H174.746V168.82H171.508ZM230.18 249.281H233.414V168.621H230.18ZM288.848 249.281H292.086V81.515H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M173.129 168.82V168.554' fill='#292994'/> +<path clip-path='url(#clip4)' d='M173.129 168.82V168.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M171.137 168.555H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M173.129 168.82V169.09' fill='#292994'/> +<path clip-path='url(#clip4)' d='M173.129 168.82V169.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M175.122 169.089H171.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M231.797 168.621V168.554' fill='#292994'/> +<path clip-path='url(#clip4)' d='M231.797 168.621V168.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M229.805 168.555H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M231.797 168.621V168.687' fill='#292994'/> +<path clip-path='url(#clip4)' d='M231.797 168.621V168.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M233.79 168.688H229.805' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M290.465 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M288.473 81.516H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M290.465 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M288.473 81.516H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M349.137 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M349.137 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M407.805 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M407.805 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M466.473 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M466.473 81.515V81.515' fill='#292994'/> +<path clip-path='url(#clip4)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M411.414 249.281H414.652V133.59H411.414ZM176.738 249.281H179.977V162.113H176.738ZM235.41 249.281H238.645V162.648H235.41ZM294.078 249.281H297.317V81.515H294.078ZM352.746 249.281H355.984V125.875H352.746ZM470.086 249.281H473.324V181.035H470.086Z' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M411.414 249.281H414.652V133.59H411.414ZM176.738 249.281H179.977V162.113H176.738ZM235.41 249.281H238.645V162.648H235.41ZM294.078 249.281H297.317V81.515H294.078ZM352.746 249.281H355.984V125.875H352.746ZM470.086 249.281H473.324V181.035H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M413.035 133.59V126.211' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M413.035 133.59V126.211' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M411.043 126.211H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M413.035 133.59V140.972' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M413.035 133.59V140.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M415.027 140.973H411.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M178.36 162.113V161.777' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M178.36 162.113V161.777' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M176.367 161.777H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M178.36 162.113V162.445' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M178.36 162.113V162.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M180.352 162.445H176.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M237.027 162.648V162.515' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M237.027 162.648V162.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M235.035 162.516H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M237.027 162.648V162.781' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M237.027 162.648V162.781' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M239.02 162.781H235.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M295.695 81.515V81.515' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M293.703 81.516H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M295.695 81.515V81.515' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M293.703 81.516H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M354.367 125.875V125.672' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M354.367 125.875V125.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M352.375 125.672H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M354.367 125.875V126.074' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M354.367 125.875V126.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M356.359 126.074H352.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M471.703 181.035V178.219' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M471.703 181.035V178.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M469.711 178.219H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M471.703 181.035V183.855' fill='#0a0a85'/> +<path clip-path='url(#clip4)' d='M471.703 181.035V183.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M473.695 183.856H469.711' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M181.969 249.281H185.207V154.594H181.969ZM240.641 249.281H243.875V149.695H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V81.515H357.977ZM475.317 249.281H478.555V81.515H475.317Z' fill='#000076'/> +<path clip-path='url(#clip4)' d='M181.969 249.281H185.207V154.594H181.969ZM240.641 249.281H243.875V149.695H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V81.515H357.977ZM475.317 249.281H478.555V81.515H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M183.59 154.594V154.461' fill='#000076'/> +<path clip-path='url(#clip4)' d='M183.59 154.594V154.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M181.598 154.461H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M183.59 154.594V154.73' fill='#000076'/> +<path clip-path='url(#clip4)' d='M183.59 154.594V154.73' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M185.582 154.731H181.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M242.258 149.695V149.562' fill='#000076'/> +<path clip-path='url(#clip4)' d='M242.258 149.695V149.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M240.266 149.563H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M242.258 149.695V149.832' fill='#000076'/> +<path clip-path='url(#clip4)' d='M242.258 149.695V149.832' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M244.25 149.832H240.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M300.926 81.515V81.515' fill='#000076'/> +<path clip-path='url(#clip4)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M300.926 81.515V81.515' fill='#000076'/> +<path clip-path='url(#clip4)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M359.598 81.515V81.515' fill='#000076'/> +<path clip-path='url(#clip4)' d='M357.606 81.516H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M359.598 81.515V81.515' fill='#000076'/> +<path clip-path='url(#clip4)' d='M357.606 81.516H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M476.934 81.515V81.515' fill='#000076'/> +<path clip-path='url(#clip4)' d='M474.942 81.516H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M476.934 81.515V81.515' fill='#000076'/> +<path clip-path='url(#clip4)' d='M474.942 81.516H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M187.199 249.281H190.438V181.64H187.199ZM245.871 249.281H249.106V181.64H245.871ZM304.539 249.281H307.777V164.258H304.539ZM363.207 249.281H366.445V151.105H363.207ZM421.875 249.281H425.113V179.828H421.875ZM480.547 249.281H483.785V181.371H480.547Z' fill='#000067'/> +<path clip-path='url(#clip4)' d='M187.199 249.281H190.438V181.64H187.199ZM245.871 249.281H249.106V181.64H245.871ZM304.539 249.281H307.777V164.258H304.539ZM363.207 249.281H366.445V151.105H363.207ZM421.875 249.281H425.113V179.828H421.875ZM480.547 249.281H483.785V181.371H480.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M188.82 181.64V181.57' fill='#000067'/> +<path clip-path='url(#clip4)' d='M188.82 181.64V181.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M186.828 181.57H190.813' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M188.82 181.64V181.707' fill='#000067'/> +<path clip-path='url(#clip4)' d='M188.82 181.64V181.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M190.813 181.707H186.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M247.488 181.64V181.437' fill='#000067'/> +<path clip-path='url(#clip4)' d='M247.488 181.64V181.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M245.496 181.437H249.481' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M247.488 181.64V181.84' fill='#000067'/> +<path clip-path='url(#clip4)' d='M247.488 181.64V181.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M249.481 181.84H245.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M306.156 164.258V163.992' fill='#000067'/> +<path clip-path='url(#clip4)' d='M306.156 164.258V163.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M304.164 163.992H308.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M306.156 164.258V164.527' fill='#000067'/> +<path clip-path='url(#clip4)' d='M306.156 164.258V164.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M308.149 164.527H304.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M364.828 151.105V150.168' fill='#000067'/> +<path clip-path='url(#clip4)' d='M364.828 151.105V150.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M362.836 150.168H366.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M364.828 151.105V152.047' fill='#000067'/> +<path clip-path='url(#clip4)' d='M364.828 151.105V152.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M366.82 152.047H362.832' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M423.496 179.828V179.09' fill='#000067'/> +<path clip-path='url(#clip4)' d='M423.496 179.828V179.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M421.504 179.09H425.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M423.496 179.828V180.566' fill='#000067'/> +<path clip-path='url(#clip4)' d='M423.496 179.828V180.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M425.488 180.567H421.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M482.164 181.371V178.148' fill='#000067'/> +<path clip-path='url(#clip4)' d='M482.164 181.371V178.148' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M480.172 178.149H484.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M482.164 181.371V184.594' fill='#000067'/> +<path clip-path='url(#clip4)' d='M482.164 181.371V184.594' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M484.156 184.594H480.172' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip4)' d='M419.477 298.301H487.762V276.324H419.477Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 254.512 92.648)'> +<use x='168.285' xlink:href='#g1-72' y='190.457'/> +<use x='172.021' xlink:href='#g1-80' y='190.457'/> +<use x='175.402' xlink:href='#g1-45' y='190.457'/> +<use x='177.167' xlink:href='#g1-90' y='190.457'/> +<use x='180.401' xlink:href='#g1-52' y='190.457'/> +<use x='183.047' xlink:href='#g1-45' y='190.457'/> +<use x='184.812' xlink:href='#g1-71' y='190.457'/> +<use x='188.34' xlink:href='#g1-52' y='190.457'/> +<use x='190.987' xlink:href='#g1-44' y='190.457'/> +<use x='194.221' xlink:href='#g1-49' y='190.457'/> +<use x='196.867' xlink:href='#g1-54' y='190.457'/> +<use x='199.514' xlink:href='#g1-71' y='190.457'/> +<use x='203.042' xlink:href='#g1-98' y='190.457'/> +<use x='168.285' xlink:href='#g1-56' y='196.075'/> +<use x='170.931' xlink:href='#g1-45' y='196.075'/> +<use x='172.695' xlink:href='#g1-99' y='196.075'/> +<use x='175.048' xlink:href='#g1-111' y='196.075'/> +<use x='177.547' xlink:href='#g1-114' y='196.075'/> +<use x='179.355' xlink:href='#g1-101' y='196.075'/> +<use x='183.471' xlink:href='#g1-73' y='196.075'/> +<use x='184.941' xlink:href='#g1-110' y='196.075'/> +<use x='187.674' xlink:href='#g1-116' y='196.075'/> +<use x='189.585' xlink:href='#g1-101' y='196.075'/> +<use x='191.938' xlink:href='#g1-108' y='196.075'/> +<use x='194.965' xlink:href='#g1-88' y='196.075'/> +<use x='198.493' xlink:href='#g1-69' y='196.075'/> +<use x='201.667' xlink:href='#g1-79' y='196.075'/> +<use x='205.576' xlink:href='#g1-78' y='196.075'/> +<use x='211.076' xlink:href='#g1-64' y='196.075'/> +<use x='214.605' xlink:href='#g1-50' y='196.075'/> +<use x='217.251' xlink:href='#g1-46' y='196.075'/> +<use x='218.721' xlink:href='#g1-55' y='196.075'/> +<use x='221.368' xlink:href='#g1-71' y='196.075'/> +<use x='224.896' xlink:href='#g1-104' y='196.075'/> +<use x='227.629' xlink:href='#g1-122' y='196.075'/> +<use x='168.285' xlink:href='#g1-85' y='201.694'/> +<use x='171.917' xlink:href='#g1-98' y='201.694'/> +<use x='174.65' xlink:href='#g1-117' y='201.694'/> +<use x='177.383' xlink:href='#g1-110' y='201.694'/> +<use x='180.116' xlink:href='#g1-116' y='201.694'/> +<use x='182.027' xlink:href='#g1-117' y='201.694'/> +<use x='186.524' xlink:href='#g1-49' y='201.694'/> +<use x='189.17' xlink:href='#g1-56' y='201.694'/> +<use x='191.817' xlink:href='#g1-46' y='201.694'/> +<use x='193.287' xlink:href='#g1-48' y='201.694'/> +<use x='195.933' xlink:href='#g1-52' y='201.694'/> +<use x='198.58' xlink:href='#g1-46' y='201.694'/> +<use x='200.05' xlink:href='#g1-49' y='201.694'/> +<use x='202.696' xlink:href='#g1-44' y='201.694'/> +<use x='205.931' xlink:href='#g1-71' y='201.694'/> +<use x='209.459' xlink:href='#g1-67' y='201.694'/> +<use x='212.841' xlink:href='#g1-67' y='201.694'/> +<use x='217.986' xlink:href='#g1-55' y='201.694'/> +<use x='220.633' xlink:href='#g1-46' y='201.694'/> +<use x='222.103' xlink:href='#g1-52' y='201.694'/> +<use x='224.749' xlink:href='#g1-46' y='201.694'/> +<use x='226.219' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -58.314 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 0.355 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 59.024 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 117.693 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 176.362 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 235.031 344.257)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -53.084 343.452)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 5.585 341.573)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 64.254 311.979)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-56' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 122.923 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-54' y='201.694'/> +<use x='180.675' xlink:href='#g1-53' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 181.592 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-53' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-48' y='201.694'/> +<use x='180.675' xlink:href='#g1-54' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 240.261 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-49' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-56' y='201.694'/> +<use x='183.321' xlink:href='#g1-51' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -47.853 340.768)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-53' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 10.816 339.761)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-55' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 69.485 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-51' y='201.694'/> +<use x='180.675' xlink:href='#g1-54' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 128.154 295.471)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-55' y='201.694'/> +<use x='175.048' xlink:href='#g1-51' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 186.823 272.99)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 245.492 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-50' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-48' y='201.694'/> +<use x='183.321' xlink:href='#g1-55' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -42.623 323.991)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 16.046 320.3)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 74.715 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-56' y='201.694'/> +<use x='180.675' xlink:href='#g1-57' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 133.384 312.18)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-56' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 192.053 324.528)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-57' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 250.722 343.183)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-50' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -37.392 331.104)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 21.277 330.232)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 79.946 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-54' y='201.694'/> +<use x='180.675' xlink:href='#g1-53' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 138.615 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-53' y='201.694'/> +<use x='180.675' xlink:href='#g1-49' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 197.284 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-53' y='201.694'/> +<use x='180.675' xlink:href='#g1-49' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 255.953 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-54' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-49' y='201.694'/> +<use x='180.675' xlink:href='#g1-56' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -32.162 337.815)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-49' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 26.507 331.104)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 85.176 269.568)'> +<use x='168.285' xlink:href='#g1-50' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-49' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 143.845 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-48' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-50' y='201.694'/> +<use x='183.321' xlink:href='#g1-50' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 202.514 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-49' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-52' y='201.694'/> +<use x='183.321' xlink:href='#g1-50' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 261.183 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-55' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-48' y='201.694'/> +<use x='180.675' xlink:href='#g1-49' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -26.931 330.903)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 31.738 330.702)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 90.407 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-50' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-54' y='201.694'/> +<use x='180.675' xlink:href='#g1-55' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 149.076 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-54' y='201.694'/> +<use x='180.675' xlink:href='#g1-48' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 207.745 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-53' y='201.694'/> +<use x='180.675' xlink:href='#g1-49' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 266.414 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-53' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-55' y='201.694'/> +<use x='180.675' xlink:href='#g1-54' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 212.975 295.672)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-55' y='201.694'/> +<use x='175.048' xlink:href='#g1-50' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -21.701 324.192)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-51' y='201.694'/> +<use x='175.048' xlink:href='#g1-48' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 36.968 324.729)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-57' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 95.637 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-51' y='201.694'/> +<use x='180.675' xlink:href='#g1-55' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 154.306 287.955)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-56' y='201.694'/> +<use x='175.048' xlink:href='#g1-52' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 271.644 343.116)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-50' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -16.471 316.676)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 42.198 311.778)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-56' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 100.867 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-54' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-48' y='201.694'/> +<use x='180.675' xlink:href='#g1-54' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 159.536 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-51' y='201.694'/> +<use x='176.558' xlink:href='#g1-46' y='201.694'/> +<use x='178.029' xlink:href='#g1-49' y='201.694'/> +<use x='180.675' xlink:href='#g1-52' y='201.694'/> +<use x='183.321' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 276.874 243.598)'> +<use x='163.396' xlink:href='#g3-1' y='201.694'/> +<use x='166.901' xlink:href='#g3-1' y='201.694'/> +<use x='170.407' xlink:href='#g3-1' y='201.694'/> +<use x='173.912' xlink:href='#g1-49' y='201.694'/> +<use x='176.558' xlink:href='#g1-49' y='201.694'/> +<use x='179.205' xlink:href='#g1-46' y='201.694'/> +<use x='180.675' xlink:href='#g1-56' y='201.694'/> +<use x='183.321' xlink:href='#g1-56' y='201.694'/> +<use x='185.968' xlink:href='#g1-120' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -11.24 343.72)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 47.429 343.72)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 106.098 326.34)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-50' y='201.694'/> +<use x='175.048' xlink:href='#g1-55' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 164.767 313.187)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-52' y='201.694'/> +<use x='175.048' xlink:href='#g1-54' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 223.436 341.908)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-51' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 282.105 343.452)'> +<use x='168.285' xlink:href='#g1-49' y='201.694'/> +<use x='170.931' xlink:href='#g1-46' y='201.694'/> +<use x='172.401' xlink:href='#g1-48' y='201.694'/> +<use x='175.048' xlink:href='#g1-49' y='201.694'/> +</g> +<g transform='matrix(0 -1 1 0 -88.536 388.944)'> +<use x='168.285' xlink:href='#g0-82' y='201.694'/> +<use x='174.255' xlink:href='#g0-101' y='201.694'/> +<use x='178.351' xlink:href='#g0-108' y='201.694'/> +<use x='180.551' xlink:href='#g0-97' y='201.694'/> +<use x='184.979' xlink:href='#g0-116' y='201.694'/> +<use x='188.307' xlink:href='#g0-105' y='201.694'/> +<use x='190.507' xlink:href='#g0-118' y='201.694'/> +<use x='194.755' xlink:href='#g0-101' y='201.694'/> +<use x='201.922' xlink:href='#g0-116' y='201.694'/> +<use x='205.25' xlink:href='#g0-105' y='201.694'/> +<use x='207.45' xlink:href='#g0-109' y='201.694'/> +<use x='214.77' xlink:href='#g0-101' y='201.694'/> +<use x='221.937' xlink:href='#g2-40' y='201.694'/> +<use x='225.231' xlink:href='#g2-108' y='201.694'/> +<use x='227.251' xlink:href='#g2-111' y='201.694'/> +<use x='231.25' xlink:href='#g2-119' y='201.694'/> +<use x='236.799' xlink:href='#g2-101' y='201.694'/> +<use x='240.562' xlink:href='#g2-114' y='201.694'/> +<use x='246.277' xlink:href='#g2-105' y='201.694'/> +<use x='248.297' xlink:href='#g2-115' y='201.694'/> +<use x='254.366' xlink:href='#g2-98' y='201.694'/> +<use x='258.974' xlink:href='#g2-101' y='201.694'/> +<use x='262.738' xlink:href='#g2-116' y='201.694'/> +<use x='265.796' xlink:href='#g2-116' y='201.694'/> +<use x='268.854' xlink:href='#g2-101' y='201.694'/> +<use x='272.618' xlink:href='#g2-114' y='201.694'/> +<use x='275.51' xlink:href='#g2-41' y='201.694'/> +</g> +<path d='M136.149 296.672H402.137V279.679H136.149Z' fill='#ffffff'/> +<path d='M136.149 296.672H402.137V279.679H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#e0e0f0'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -33.522 88.465)'> +<use x='185.011' xlink:href='#g2-109' y='201.694'/> +<use x='191.736' xlink:href='#g2-105' y='201.694'/> +</g> +<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='#c2c2e1'/> +<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.56 88.011)'> +<use x='208.137' xlink:href='#g2-116' y='201.694'/> +<use x='211.195' xlink:href='#g2-99' y='201.694'/> +</g> +<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='#a3a3d1'/> +<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.159 88.465)'> +<use x='229.9' xlink:href='#g2-106' y='201.694'/> +<use x='232.155' xlink:href='#g2-101' y='201.694'/> +</g> +<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='#8585c2'/> +<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.958 87.505)'> +<use x='252.061' xlink:href='#g2-115' y='201.694'/> +<use x='255.307' xlink:href='#g2-110' y='201.694'/> +</g> +<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='#6666b3'/> +<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.781 87.505)'> +<use x='274.845' xlink:href='#g2-114' y='201.694'/> +<use x='277.737' xlink:href='#g2-112' y='201.694'/> +</g> +<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='#4747a4'/> +<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.001 88.501)'> +<use x='303.672' xlink:href='#g2-104' y='201.694'/> +<use x='308.045' xlink:href='#g2-111' y='201.694'/> +<use x='312.279' xlink:href='#g2-97' y='201.694'/> +<use x='316.112' xlink:href='#g2-114' y='201.694'/> +<use x='319.004' xlink:href='#g2-100' y='201.694'/> +</g> +<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='#292994'/> +<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.472 88.501)'> +<use x='337.19' xlink:href='#g2-103' y='201.694'/> +<use x='341.424' xlink:href='#g2-108' y='201.694'/> +<use x='343.444' xlink:href='#g2-105' y='201.694'/> +<use x='345.464' xlink:href='#g2-98' y='201.694'/> +<use x='350.072' xlink:href='#g2-99' y='201.694'/> +</g> +<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='#0a0a85'/> +<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.051 88.501)'> +<use x='366.757' xlink:href='#g2-116' y='201.694'/> +<use x='369.815' xlink:href='#g2-98' y='201.694'/> +<use x='374.187' xlink:href='#g2-98' y='201.694'/> +</g> +<path d='M346.699 290.168H349.688V282.199H346.699ZM352.676 290.168H355.664V284.191H352.676Z' fill='#000076'/> +<path d='M346.699 290.168H349.688V282.199H346.699ZM352.676 290.168H355.664V284.191H352.676Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -34.135 87.505)'> +<use x='392.986' xlink:href='#g2-115' y='201.694'/> +<use x='396.233' xlink:href='#g2-109' y='201.694'/> +</g> +<path d='M372.012 290.168H375V282.199H372.012ZM377.988 290.168H380.977V284.191H377.988Z' fill='#000067'/> +<path d='M372.012 290.168H375V282.199H372.012ZM377.988 290.168H380.977V284.191H377.988Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.145 88.465)'> +<use x='419.31' xlink:href='#g2-115' y='201.694'/> +<use x='422.556' xlink:href='#g2-109' y='201.694'/> +<use x='429.281' xlink:href='#g2-105' y='201.694'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-1.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-1.svg new file mode 100644 index 0000000..891f7d6 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-1.svg @@ -0,0 +1,796 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<clipPath id='clip9'> +<path d='M82.148 203.937H434.164V78.691H82.148Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page9'> +<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -11.54 33.989)'> +<use x='114.487' xlink:href='#g2-99' y='183.949'/> +<use x='118.25' xlink:href='#g2-102' y='183.949'/> +<use x='120.838' xlink:href='#g2-114' y='183.949'/> +<use x='123.73' xlink:href='#g2-97' y='183.949'/> +<use x='127.798' xlink:href='#g2-99' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 41.401 33.989)'> +<use x='114.487' xlink:href='#g2-101' y='183.949'/> +<use x='118.25' xlink:href='#g2-115' y='183.949'/> +<use x='121.497' xlink:href='#g2-112' y='183.949'/> +<use x='125.634' xlink:href='#g2-114' y='183.949'/> +<use x='128.526' xlink:href='#g2-101' y='183.949'/> +<use x='132.29' xlink:href='#g2-115' y='183.949'/> +<use x='135.536' xlink:href='#g2-115' y='183.949'/> +<use x='138.782' xlink:href='#g2-111' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 103.095 33.989)'> +<use x='114.487' xlink:href='#g2-98' y='183.949'/> +<use x='118.859' xlink:href='#g2-97' y='183.949'/> +<use x='122.692' xlink:href='#g2-114' y='183.949'/> +<use x='125.584' xlink:href='#g2-110' y='183.949'/> +<use x='129.957' xlink:href='#g2-101' y='183.949'/> +<use x='133.72' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 162.903 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-101' y='183.949'/> +<use x='120.271' xlink:href='#g2-97' y='183.949'/> +<use x='124.339' xlink:href='#g2-110' y='183.949'/> +<use x='128.711' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 223.526 33.989)'> +<use x='114.487' xlink:href='#g2-114' y='183.949'/> +<use x='117.379' xlink:href='#g2-101' y='183.949'/> +<use x='121.142' xlink:href='#g2-100' y='183.949'/> +<use x='125.515' xlink:href='#g2-105' y='183.949'/> +<use x='127.535' xlink:href='#g2-115' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 277.054 33.989)'> +<use x='114.487' xlink:href='#g2-108' y='183.949'/> +<use x='116.507' xlink:href='#g2-97' y='183.949'/> +<use x='120.34' xlink:href='#g2-114' y='183.949'/> +<use x='123.232' xlink:href='#g2-115' y='183.949'/> +<use x='126.478' xlink:href='#g2-111' y='183.949'/> +<use x='130.712' xlink:href='#g2-110' y='183.949'/> +<use x='135.085' xlink:href='#g2-78' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 21.624)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.688)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.999)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -72.311)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.622)'> +<use x='114.487' xlink:href='#g1-50' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-120' y='183.949'/> +</g> +<path clip-path='url(#clip9)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M87.949 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M85.953 141.316H89.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M87.949 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M85.953 141.316H89.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M146.617 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M144.625 141.316H148.61' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M146.617 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M144.625 141.316H148.61' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M205.285 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M203.293 141.316H207.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M205.285 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M203.293 141.316H207.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M263.953 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M261.961 141.316H265.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M263.953 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M261.961 141.316H265.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M322.625 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M320.629 141.316H324.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M322.625 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M320.629 141.316H324.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M381.293 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M379.301 141.316H383.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M381.293 141.316V141.316' fill='#f0e0f0'/> +<path clip-path='url(#clip9)' d='M379.301 141.316H383.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M91.559 203.937H94.797V93.156H91.559ZM150.227 203.937H153.465V78.691H150.227ZM208.899 203.937H212.133V138.246H208.899ZM267.567 203.937H270.805V145.949H267.567ZM326.234 203.937H329.473V130.23H326.234ZM384.902 203.937H388.141V140.25H384.902Z' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M91.559 203.937H94.797V93.156H91.559ZM150.227 203.937H153.465V78.691H150.227ZM208.899 203.937H212.133V138.246H208.899ZM267.567 203.937H270.805V145.949H267.567ZM326.234 203.937H329.473V130.23H326.234ZM384.902 203.937H388.141V140.25H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M93.18 93.156V93.156' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M91.184 93.156H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M93.18 93.156V93.156' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M91.184 93.156H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M151.848 78.691V78.691' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M149.855 78.691H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M151.848 78.691V78.691' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M149.855 78.691H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M210.516 138.246V138.246' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M208.523 138.246H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M210.516 138.246V138.246' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M208.523 138.246H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M269.184 145.949V145.949' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M267.191 145.949H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M269.184 145.949V145.949' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M267.191 145.949H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M327.856 130.23V130.23' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M325.859 130.23H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M327.856 130.23V130.23' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M325.859 130.23H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M386.524 140.25V140.25' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M384.531 140.25H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M386.524 140.25V140.25' fill='#e1c2e1'/> +<path clip-path='url(#clip9)' d='M384.531 140.25H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M96.789 203.937H100.027V110.816H96.789ZM155.457 203.937H158.695V104.679H155.457ZM214.129 203.937H217.363V139.75H214.129ZM272.797 203.937H276.035V141.254H272.797ZM331.465 203.937H334.703V137.496H331.465ZM390.133 203.937H393.371V132.109H390.133Z' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M96.789 203.937H100.027V110.816H96.789ZM155.457 203.937H158.695V104.679H155.457ZM214.129 203.937H217.363V139.75H214.129ZM272.797 203.937H276.035V141.254H272.797ZM331.465 203.937H334.703V137.496H331.465ZM390.133 203.937H393.371V132.109H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M98.41 110.816V110.816' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M96.414 110.817H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M98.41 110.816V110.816' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M96.414 110.817H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M157.078 104.679V104.679' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M155.086 104.68H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M157.078 104.679V104.679' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M155.086 104.68H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M215.746 139.75V139.75' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M213.754 139.75H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M215.746 139.75V139.75' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M213.754 139.75H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M274.414 141.254V141.254' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M272.422 141.254H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M274.414 141.254V141.254' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M272.422 141.254H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M333.086 137.496V137.496' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M331.09 137.496H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M333.086 137.496V137.496' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M331.09 137.496H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M391.754 132.109V132.109' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M389.762 132.11H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M391.754 132.109V132.109' fill='#d1a3d1'/> +<path clip-path='url(#clip9)' d='M389.762 132.11H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M102.02 203.937H105.258V121.777H102.02ZM160.688 203.937H163.926V110.066H160.688ZM219.359 203.937H222.594V140.312H219.359ZM278.027 203.937H281.266V140.437H278.027ZM336.695 203.937H339.934V138.058H336.695ZM395.363 203.937H398.602V125.16H395.363Z' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M102.02 203.937H105.258V121.777H102.02ZM160.688 203.937H163.926V110.066H160.688ZM219.359 203.937H222.594V140.312H219.359ZM278.027 203.937H281.266V140.437H278.027ZM336.695 203.937H339.934V138.058H336.695ZM395.363 203.937H398.602V125.16H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M103.641 121.777V121.777' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M101.644 121.777H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M103.641 121.777V121.777' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M101.644 121.777H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M162.309 110.066V110.066' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M160.316 110.066H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M162.309 110.066V110.066' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M160.316 110.066H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M220.977 140.312V140.312' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M218.984 140.312H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M220.977 140.312V140.312' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M218.984 140.312H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M279.645 140.437V140.437' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M277.652 140.438H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M279.645 140.437V140.437' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M277.652 140.438H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M338.317 138.058V138.058' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M336.32 138.059H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M338.317 138.058V138.058' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M336.32 138.059H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M396.984 125.16V125.16' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M394.992 125.161H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M396.984 125.16V125.16' fill='#c285c2'/> +<path clip-path='url(#clip9)' d='M394.992 125.161H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M107.25 203.937H110.488V138.433H107.25ZM165.918 203.937H169.156V141.754H165.918ZM224.59 203.937H227.824V141.379H224.59ZM283.258 203.937H286.496V131.172H283.258ZM341.926 203.937H345.164V140.5H341.926ZM400.594 203.937H403.832V134.238H400.594Z' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M107.25 203.937H110.488V138.433H107.25ZM165.918 203.937H169.156V141.754H165.918ZM224.59 203.937H227.824V141.379H224.59ZM283.258 203.937H286.496V131.172H283.258ZM341.926 203.937H345.164V140.5H341.926ZM400.594 203.937H403.832V134.238H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M108.871 138.433V138.433' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M106.875 138.434H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M108.871 138.433V138.433' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M106.875 138.434H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M167.539 141.754V141.754' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M165.547 141.754H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M167.539 141.754V141.754' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M165.547 141.754H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M226.207 141.379V141.379' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M224.215 141.379H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M226.207 141.379V141.379' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M224.215 141.379H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M284.875 131.172V131.172' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M282.883 131.172H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M284.875 131.172V131.172' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M282.883 131.172H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M343.547 140.5V140.5' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M341.551 140.5H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M343.547 140.5V140.5' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M341.551 140.5H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M402.215 134.238V134.238' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M400.223 134.238H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M402.215 134.238V134.238' fill='#b366b3'/> +<path clip-path='url(#clip9)' d='M400.223 134.238H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M112.481 203.937H115.719V108.687H112.481ZM171.149 203.937H174.387V78.691H171.149ZM229.82 203.937H233.055V139.812H229.82ZM288.488 203.937H291.727V125.785H288.488ZM347.156 203.937H350.395V125.41H347.156ZM405.824 203.937H409.063V131.672H405.824Z' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M112.481 203.937H115.719V108.687H112.481ZM171.149 203.937H174.387V78.691H171.149ZM229.82 203.937H233.055V139.812H229.82ZM288.488 203.937H291.727V125.785H288.488ZM347.156 203.937H350.395V125.41H347.156ZM405.824 203.937H409.063V131.672H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M114.098 108.687V108.687' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M112.105 108.688H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M114.098 108.687V108.687' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M112.105 108.688H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M172.77 78.691V78.691' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M170.777 78.691H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M172.77 78.691V78.691' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M170.777 78.691H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M231.438 139.812V139.812' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M229.445 139.812H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M231.438 139.812V139.812' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M229.445 139.812H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M290.106 125.785V125.785' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M288.113 125.785H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M290.106 125.785V125.785' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M288.113 125.785H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M348.777 125.41V125.41' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M346.781 125.41H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M348.777 125.41V125.41' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M346.781 125.41H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M407.445 131.672V131.672' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M405.453 131.672H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M407.445 131.672V131.672' fill='#a447a4'/> +<path clip-path='url(#clip9)' d='M405.453 131.672H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M117.711 203.937H120.949V141.316H117.711ZM176.379 203.937H179.617V153.402H176.379ZM235.051 203.937H238.285V141.566H235.051ZM293.719 203.937H296.957V131.922H293.719ZM352.387 203.937H355.625V140.562H352.387ZM411.055 203.937H414.293V134.613H411.055Z' fill='#942994'/> +<path clip-path='url(#clip9)' d='M117.711 203.937H120.949V141.316H117.711ZM176.379 203.937H179.617V153.402H176.379ZM235.051 203.937H238.285V141.566H235.051ZM293.719 203.937H296.957V131.922H293.719ZM352.387 203.937H355.625V140.562H352.387ZM411.055 203.937H414.293V134.613H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M119.328 141.316V141.316' fill='#942994'/> +<path clip-path='url(#clip9)' d='M117.336 141.316H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M119.328 141.316V141.316' fill='#942994'/> +<path clip-path='url(#clip9)' d='M117.336 141.316H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M178 153.402V153.402' fill='#942994'/> +<path clip-path='url(#clip9)' d='M176.008 153.403H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M178 153.402V153.402' fill='#942994'/> +<path clip-path='url(#clip9)' d='M176.008 153.403H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M236.668 141.566V141.566' fill='#942994'/> +<path clip-path='url(#clip9)' d='M234.676 141.567H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M236.668 141.566V141.566' fill='#942994'/> +<path clip-path='url(#clip9)' d='M234.676 141.567H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M295.336 131.922V131.922' fill='#942994'/> +<path clip-path='url(#clip9)' d='M293.344 131.922H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M295.336 131.922V131.922' fill='#942994'/> +<path clip-path='url(#clip9)' d='M293.344 131.922H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M354.008 140.562V140.562' fill='#942994'/> +<path clip-path='url(#clip9)' d='M352.012 140.563H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M354.008 140.562V140.562' fill='#942994'/> +<path clip-path='url(#clip9)' d='M352.012 140.563H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M412.676 134.613V134.613' fill='#942994'/> +<path clip-path='url(#clip9)' d='M410.684 134.614H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M412.676 134.613V134.613' fill='#942994'/> +<path clip-path='url(#clip9)' d='M410.684 134.614H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M122.941 203.937H126.18V116.765H122.941ZM181.609 203.937H184.848V112.32H181.609ZM240.281 203.937H243.516V140.125H240.281ZM298.949 203.937H302.188V131.734H298.949ZM357.617 203.937H360.856V97.168H357.617ZM416.285 203.937H419.524V136.804H416.285Z' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M122.941 203.937H126.18V116.765H122.941ZM181.609 203.937H184.848V112.32H181.609ZM240.281 203.937H243.516V140.125H240.281ZM298.949 203.937H302.188V131.734H298.949ZM357.617 203.937H360.856V97.168H357.617ZM416.285 203.937H419.524V136.804H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M124.559 116.765V116.765' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M122.566 116.766H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M124.559 116.765V116.765' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M122.566 116.766H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M183.231 112.32V112.32' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M181.238 112.32H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M183.231 112.32V112.32' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M181.238 112.32H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M241.899 140.125V140.125' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M239.906 140.125H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M241.899 140.125V140.125' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M239.906 140.125H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M300.567 131.734V131.734' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M298.574 131.734H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M300.567 131.734V131.734' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M298.574 131.734H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M359.238 97.168V97.168' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M357.242 97.168H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M359.238 97.168V97.168' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M357.242 97.168H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M417.906 136.804V136.804' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M415.914 136.804H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M417.906 136.804V136.804' fill='#850a85'/> +<path clip-path='url(#clip9)' d='M415.914 136.804H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M128.172 203.937H131.41V104.992H128.172ZM186.84 203.937H190.078V90.09H186.84ZM245.512 203.937H248.746V133.238H245.512ZM362.848 203.937H366.086V124.906H362.848ZM421.516 203.937H424.754V148.453H421.516Z' fill='#760076'/> +<path clip-path='url(#clip9)' d='M128.172 203.937H131.41V104.992H128.172ZM186.84 203.937H190.078V90.09H186.84ZM245.512 203.937H248.746V133.238H245.512ZM362.848 203.937H366.086V124.906H362.848ZM421.516 203.937H424.754V148.453H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M129.789 104.992V104.992' fill='#760076'/> +<path clip-path='url(#clip9)' d='M127.797 104.992H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M129.789 104.992V104.992' fill='#760076'/> +<path clip-path='url(#clip9)' d='M127.797 104.992H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M188.461 90.09V90.09' fill='#760076'/> +<path clip-path='url(#clip9)' d='M186.469 90.09H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M188.461 90.09V90.09' fill='#760076'/> +<path clip-path='url(#clip9)' d='M186.469 90.09H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M247.129 133.238V133.238' fill='#760076'/> +<path clip-path='url(#clip9)' d='M245.137 133.238H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M247.129 133.238V133.238' fill='#760076'/> +<path clip-path='url(#clip9)' d='M245.137 133.238H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M364.469 124.906V124.906' fill='#760076'/> +<path clip-path='url(#clip9)' d='M362.473 124.906H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M364.469 124.906V124.906' fill='#760076'/> +<path clip-path='url(#clip9)' d='M362.473 124.906H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M423.137 148.453V148.453' fill='#760076'/> +<path clip-path='url(#clip9)' d='M421.144 148.453H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M423.137 148.453V148.453' fill='#760076'/> +<path clip-path='url(#clip9)' d='M421.144 148.453H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M133.402 203.937H136.641V138.746H133.402ZM192.07 203.937H195.309V107.058H192.07ZM250.742 203.937H253.977V141.316H250.742ZM309.41 203.937H312.649V129.355H309.41ZM368.078 203.937H371.317V140.125H368.078ZM426.746 203.937H429.984V140.375H426.746Z' fill='#670067'/> +<path clip-path='url(#clip9)' d='M133.402 203.937H136.641V138.746H133.402ZM192.07 203.937H195.309V107.058H192.07ZM250.742 203.937H253.977V141.316H250.742ZM309.41 203.937H312.649V129.355H309.41ZM368.078 203.937H371.317V140.125H368.078ZM426.746 203.937H429.984V140.375H426.746Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M135.02 138.746V138.746' fill='#670067'/> +<path clip-path='url(#clip9)' d='M133.027 138.746H137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M135.02 138.746V138.746' fill='#670067'/> +<path clip-path='url(#clip9)' d='M133.027 138.746H137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M193.692 107.058V107.058' fill='#670067'/> +<path clip-path='url(#clip9)' d='M191.699 107.058H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M193.692 107.058V107.058' fill='#670067'/> +<path clip-path='url(#clip9)' d='M191.699 107.058H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M252.359 141.316V141.316' fill='#670067'/> +<path clip-path='url(#clip9)' d='M250.367 141.316H254.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M252.359 141.316V141.316' fill='#670067'/> +<path clip-path='url(#clip9)' d='M250.367 141.316H254.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M311.027 129.355V129.355' fill='#670067'/> +<path clip-path='url(#clip9)' d='M309.035 129.355H313.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M311.027 129.355V129.355' fill='#670067'/> +<path clip-path='url(#clip9)' d='M309.035 129.355H313.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M369.699 140.125V140.125' fill='#670067'/> +<path clip-path='url(#clip9)' d='M367.703 140.125H371.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M369.699 140.125V140.125' fill='#670067'/> +<path clip-path='url(#clip9)' d='M367.703 140.125H371.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M428.367 140.375V140.375' fill='#670067'/> +<path clip-path='url(#clip9)' d='M426.375 140.375H430.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip9)' d='M428.367 140.375V140.375' fill='#670067'/> +<path clip-path='url(#clip9)' d='M426.375 140.375H430.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(0 -1 1 0 -94.367 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -35.698 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 22.971 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 81.64 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 140.309 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 198.978 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -89.137 201.62)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -30.468 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-50' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-49' y='183.949'/> +<use x='126.877' xlink:href='#g1-52' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 28.201 246.709)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 86.87 254.412)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 145.539 238.693)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 204.208 248.713)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -83.906 219.28)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -25.237 213.143)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 33.432 248.212)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 92.101 249.715)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 150.77 245.958)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 209.439 240.572)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -78.676 230.239)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-51' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -20.007 218.529)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 38.662 248.776)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 97.331 248.901)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 156 246.521)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 214.669 233.621)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -73.445 246.897)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -14.776 250.216)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-57' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 43.893 249.84)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 102.562 239.633)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 161.231 248.963)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 219.9 242.701)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -68.215 217.151)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -9.546 187.155)'> +<use x='109.598' xlink:href='#g3-1' y='183.949'/> +<use x='113.103' xlink:href='#g3-1' y='183.949'/> +<use x='116.608' xlink:href='#g3-1' y='183.949'/> +<use x='120.114' xlink:href='#g1-52' y='183.949'/> +<use x='122.76' xlink:href='#g1-46' y='183.949'/> +<use x='124.23' xlink:href='#g1-53' y='183.949'/> +<use x='126.877' xlink:href='#g1-50' y='183.949'/> +<use x='129.523' xlink:href='#g1-120' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 49.123 248.275)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 107.792 234.247)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 166.461 233.871)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 225.13 240.134)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -62.984 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -4.315 261.864)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-56' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 54.354 250.028)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 113.023 240.384)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 171.692 249.026)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 230.361 243.077)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -57.754 225.229)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-51' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 0.915 220.783)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-52' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 59.584 248.588)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 118.253 240.196)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 176.922 205.628)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-55' y='183.949'/> +<use x='121.25' xlink:href='#g1-49' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 235.591 245.269)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-55' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -52.524 213.456)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-56' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 6.145 198.552)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-56' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 64.814 241.699)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-51' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 182.152 233.37)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-50' y='183.949'/> +<use x='121.25' xlink:href='#g1-54' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 240.821 256.917)'> +<use x='114.487' xlink:href='#g1-48' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-56' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -47.293 247.21)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-52' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 11.376 215.523)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-53' y='183.949'/> +<use x='121.25' xlink:href='#g1-53' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 70.045 249.778)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-48' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 128.714 237.817)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-49' y='183.949'/> +<use x='121.25' xlink:href='#g1-57' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 187.383 248.588)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 246.052 248.838)'> +<use x='114.487' xlink:href='#g1-49' y='183.949'/> +<use x='117.133' xlink:href='#g1-46' y='183.949'/> +<use x='118.603' xlink:href='#g1-48' y='183.949'/> +<use x='121.25' xlink:href='#g1-50' y='183.949'/> +</g> +<g transform='matrix(0 -1 1 0 -124.589 307.697)'> +<use x='114.487' xlink:href='#g0-82' y='183.949'/> +<use x='120.457' xlink:href='#g0-101' y='183.949'/> +<use x='124.553' xlink:href='#g0-108' y='183.949'/> +<use x='126.753' xlink:href='#g0-97' y='183.949'/> +<use x='131.181' xlink:href='#g0-116' y='183.949'/> +<use x='134.509' xlink:href='#g0-105' y='183.949'/> +<use x='136.709' xlink:href='#g0-118' y='183.949'/> +<use x='140.957' xlink:href='#g0-101' y='183.949'/> +<use x='148.124' xlink:href='#g0-114' y='183.949'/> +<use x='151.272' xlink:href='#g0-115' y='183.949'/> +<use x='154.805' xlink:href='#g0-115' y='183.949'/> +<use x='161.409' xlink:href='#g2-40' y='183.949'/> +<use x='164.702' xlink:href='#g2-108' y='183.949'/> +<use x='166.722' xlink:href='#g2-111' y='183.949'/> +<use x='170.721' xlink:href='#g2-119' y='183.949'/> +<use x='176.27' xlink:href='#g2-101' y='183.949'/> +<use x='180.034' xlink:href='#g2-114' y='183.949'/> +<use x='185.749' xlink:href='#g2-105' y='183.949'/> +<use x='187.769' xlink:href='#g2-115' y='183.949'/> +<use x='193.838' xlink:href='#g2-98' y='183.949'/> +<use x='198.446' xlink:href='#g2-101' y='183.949'/> +<use x='202.209' xlink:href='#g2-116' y='183.949'/> +<use x='205.267' xlink:href='#g2-116' y='183.949'/> +<use x='208.325' xlink:href='#g2-101' y='183.949'/> +<use x='212.089' xlink:href='#g2-114' y='183.949'/> +<use x='214.981' xlink:href='#g2-41' y='183.949'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-2.svg b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-2.svg new file mode 100644 index 0000000..f426537 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-2.svg @@ -0,0 +1,974 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.4.2 --> +<svg height='182.025pt' version='1.1' viewBox='106.736 51.674 381.623 182.025' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> +<defs> +<clipPath id='clip10'> +<path d='M135.949 186.074H487.961V60.828H135.949Z'/> +</clipPath> +<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/> +<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/> +<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/> +<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/> +<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/> +<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/> +<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/> +<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/> +<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/> +<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/> +<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/> +<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/> +<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/> +<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/> +<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/> +<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/> +<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/> +<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/> +<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/> +<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/> +<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/> +<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/> +<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/> +<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/> +<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/> +<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/> +<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/> +<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/> +<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/> +<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/> +<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/> +<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/> +<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/> +<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/> +<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/> +<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/> +<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/> +<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/> +<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/> +<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/> +<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/> +<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/> +<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/> +<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/> +<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/> +<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/> +<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/> +<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/> +<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/> +<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/> +<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/> +<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/> +<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/> +<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/> +<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/> +<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/> +<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/> +<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/> +<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/> +<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/> +<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/> +<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/> +<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/> +<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/> +<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/> +<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/> +<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/> +<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/> +<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/> +<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/> +<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/> +<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/> +<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/> +<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/> +<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/> +<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/> +<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/> +<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/> +<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/> +<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/> +<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/> +<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/> +</defs> +<g id='page10'> +<path d='M194.617 194.93V186.074M253.285 194.93V186.074M311.953 194.93V186.074M370.625 194.93V186.074M429.293 194.93V186.074M194.617 51.973V60.828M253.285 51.973V60.828M311.953 51.973V60.828M370.625 51.973V60.828M429.293 51.973V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M165.281 190.324V186.074M223.953 190.324V186.074M282.621 190.324V186.074M341.289 190.324V186.074M399.957 190.324V186.074M458.629 190.324V186.074M165.281 56.574V60.828M223.953 56.574V60.828M282.621 56.574V60.828M341.289 56.574V60.828M399.957 56.574V60.828M458.629 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 186.074H140.199M135.949 154.762H140.199M135.949 123.449H140.199M135.949 92.141H140.199M135.949 60.828H140.199M487.961 186.074H483.711M487.961 154.762H483.711M487.961 123.449H483.711M487.961 92.141H483.711M487.961 60.828H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/> +<path d='M135.949 186.074V60.828H487.961V186.074H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -21.265 59.571)'> +<use x='168.285' xlink:href='#g2-97' y='140.503'/> +<use x='172.353' xlink:href='#g2-108' y='140.503'/> +<use x='174.373' xlink:href='#g2-108' y='140.503'/> +<use x='176.393' xlink:href='#g2-111' y='140.503'/> +<use x='180.863' xlink:href='#g2-99' y='140.503'/> +<use x='184.627' xlink:href='#g2-45' y='140.503'/> +<use x='187.449' xlink:href='#g2-116' y='140.503'/> +<use x='190.507' xlink:href='#g2-101' y='140.503'/> +<use x='194.271' xlink:href='#g2-115' y='140.503'/> +<use x='197.517' xlink:href='#g2-116' y='140.503'/> +<use x='200.575' xlink:href='#g2-49' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 36.532 59.571)'> +<use x='168.285' xlink:href='#g2-97' y='140.503'/> +<use x='172.353' xlink:href='#g2-108' y='140.503'/> +<use x='174.373' xlink:href='#g2-108' y='140.503'/> +<use x='176.393' xlink:href='#g2-111' y='140.503'/> +<use x='180.863' xlink:href='#g2-99' y='140.503'/> +<use x='184.627' xlink:href='#g2-45' y='140.503'/> +<use x='187.449' xlink:href='#g2-116' y='140.503'/> +<use x='190.507' xlink:href='#g2-101' y='140.503'/> +<use x='194.271' xlink:href='#g2-115' y='140.503'/> +<use x='197.517' xlink:href='#g2-116' y='140.503'/> +<use x='200.575' xlink:href='#g2-78' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 94.98 59.571)'> +<use x='168.285' xlink:href='#g2-115' y='140.503'/> +<use x='171.531' xlink:href='#g2-104' y='140.503'/> +<use x='175.904' xlink:href='#g2-54' y='140.503'/> +<use x='180.138' xlink:href='#g2-98' y='140.503'/> +<use x='184.746' xlink:href='#g2-101' y='140.503'/> +<use x='188.509' xlink:href='#g2-110' y='140.503'/> +<use x='192.882' xlink:href='#g2-99' y='140.503'/> +<use x='196.646' xlink:href='#g2-104' y='140.503'/> +<use x='201.018' xlink:href='#g2-78' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 153.649 59.571)'> +<use x='168.285' xlink:href='#g2-115' y='140.503'/> +<use x='171.531' xlink:href='#g2-104' y='140.503'/> +<use x='175.904' xlink:href='#g2-56' y='140.503'/> +<use x='180.138' xlink:href='#g2-98' y='140.503'/> +<use x='184.746' xlink:href='#g2-101' y='140.503'/> +<use x='188.509' xlink:href='#g2-110' y='140.503'/> +<use x='192.882' xlink:href='#g2-99' y='140.503'/> +<use x='196.646' xlink:href='#g2-104' y='140.503'/> +<use x='201.018' xlink:href='#g2-78' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 207.225 59.571)'> +<use x='168.285' xlink:href='#g2-120' y='140.503'/> +<use x='172.187' xlink:href='#g2-109' y='140.503'/> +<use x='178.912' xlink:href='#g2-97' y='140.503'/> +<use x='182.98' xlink:href='#g2-108' y='140.503'/> +<use x='185' xlink:href='#g2-108' y='140.503'/> +<use x='187.02' xlink:href='#g2-111' y='140.503'/> +<use x='191.49' xlink:href='#g2-99' y='140.503'/> +<use x='195.254' xlink:href='#g2-45' y='140.503'/> +<use x='198.076' xlink:href='#g2-116' y='140.503'/> +<use x='201.134' xlink:href='#g2-101' y='140.503'/> +<use x='204.898' xlink:href='#g2-115' y='140.503'/> +<use x='208.144' xlink:href='#g2-116' y='140.503'/> +<use x='211.202' xlink:href='#g2-78' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 263.494 59.571)'> +<use x='168.285' xlink:href='#g2-99' y='140.503'/> +<use x='172.049' xlink:href='#g2-97' y='140.503'/> +<use x='176.117' xlink:href='#g2-99' y='140.503'/> +<use x='179.88' xlink:href='#g2-104' y='140.503'/> +<use x='184.253' xlink:href='#g2-101' y='140.503'/> +<use x='188.017' xlink:href='#g2-45' y='140.503'/> +<use x='190.839' xlink:href='#g2-115' y='140.503'/> +<use x='194.086' xlink:href='#g2-99' y='140.503'/> +<use x='197.849' xlink:href='#g2-114' y='140.503'/> +<use x='200.741' xlink:href='#g2-97' y='140.503'/> +<use x='204.81' xlink:href='#g2-116' y='140.503'/> +<use x='207.868' xlink:href='#g2-99' y='140.503'/> +<use x='211.631' xlink:href='#g2-104' y='140.503'/> +<use x='216.004' xlink:href='#g2-78' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 47.205)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 15.894)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -15.418)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -46.729)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -78.041)'> +<use x='168.285' xlink:href='#g1-50' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-120' y='140.503'/> +</g> +<path clip-path='url(#clip10)' d='M135.949 123.449H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M140.125 186.074H143.363V123.449H140.125ZM198.797 186.074H202.035V123.449H198.797ZM257.465 186.074H260.703V123.449H257.465ZM316.133 186.074H319.371V123.449H316.133ZM374.801 186.074H378.039V123.449H374.801ZM433.473 186.074H436.711V123.449H433.473Z' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M140.125 186.074H143.363V123.449H140.125ZM198.797 186.074H202.035V123.449H198.797ZM257.465 186.074H260.703V123.449H257.465ZM316.133 186.074H319.371V123.449H316.133ZM374.801 186.074H378.039V123.449H374.801ZM433.473 186.074H436.711V123.449H433.473Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M141.746 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M139.754 123.449H143.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M141.746 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M139.754 123.449H143.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M200.414 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M198.422 123.449H202.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M200.414 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M198.422 123.449H202.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M259.082 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M257.09 123.449H261.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M259.082 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M257.09 123.449H261.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M317.754 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M315.762 123.449H319.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M317.754 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M315.762 123.449H319.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M376.422 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M374.43 123.449H378.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M376.422 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M374.43 123.449H378.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M435.09 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M433.098 123.449H437.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M435.09 123.449V123.449' fill='#f0e0f0'/> +<path clip-path='url(#clip10)' d='M433.098 123.449H437.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M145.356 186.074H148.594V120.071H145.356ZM204.028 186.074H207.266V121.571H204.028ZM262.695 186.074H265.934V122.699H262.695ZM321.363 186.074H324.602V125.895H321.363ZM380.031 186.074H383.27V173.172H380.031ZM438.703 186.074H441.942V93.391H438.703Z' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M145.356 186.074H148.594V120.071H145.356ZM204.028 186.074H207.266V121.571H204.028ZM262.695 186.074H265.934V122.699H262.695ZM321.363 186.074H324.602V125.895H321.363ZM380.031 186.074H383.27V173.172H380.031ZM438.703 186.074H441.942V93.391H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M146.977 120.071V120.071' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M144.984 120.07H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M146.977 120.071V120.071' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M144.984 120.07H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M205.645 121.571V121.571' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M203.652 121.57H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M205.645 121.571V121.571' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M203.652 121.57H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M264.313 122.699V122.699' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M262.32 122.699H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M264.313 122.699V122.699' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M262.32 122.699H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M322.984 125.895V125.895' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M320.992 125.894H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M322.984 125.895V125.895' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M320.992 125.894H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M381.652 173.172V173.172' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M379.66 173.172H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M381.652 173.172V173.172' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M379.66 173.172H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M440.32 93.391V93.391' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M438.328 93.391H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M440.32 93.391V93.391' fill='#e1c2e1'/> +<path clip-path='url(#clip10)' d='M438.328 93.391H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M150.586 186.074H153.824V122.699H150.586ZM209.258 186.074H212.496V124.766H209.258ZM267.926 186.074H271.164V121.762H267.926ZM326.594 186.074H329.832V118.692H326.594ZM385.262 186.074H388.5V154.324H385.262ZM443.934 186.074H447.172V111.238H443.934Z' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M150.586 186.074H153.824V122.699H150.586ZM209.258 186.074H212.496V124.766H209.258ZM267.926 186.074H271.164V121.762H267.926ZM326.594 186.074H329.832V118.692H326.594ZM385.262 186.074H388.5V154.324H385.262ZM443.934 186.074H447.172V111.238H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M152.207 122.699V122.699' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M150.215 122.699H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M152.207 122.699V122.699' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M150.215 122.699H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M210.875 124.766V124.766' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M208.883 124.766H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M210.875 124.766V124.766' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M208.883 124.766H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M269.543 121.762V121.762' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M267.551 121.762H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M269.543 121.762V121.762' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M267.551 121.762H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M328.215 118.692V118.692' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M326.223 118.691H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M328.215 118.692V118.692' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M326.223 118.691H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M386.883 154.324V154.324' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M384.891 154.324H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M386.883 154.324V154.324' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M384.891 154.324H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M445.551 111.238V111.238' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M443.559 111.238H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M445.551 111.238V111.238' fill='#d1a3d1'/> +<path clip-path='url(#clip10)' d='M443.559 111.238H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M155.817 186.074H159.055V119.696H155.817ZM214.488 186.074H217.727V121.887H214.488ZM273.156 186.074H276.395V113.43H273.156ZM331.824 186.074H335.063V119.004H331.824ZM390.492 186.074H393.731V89.133H390.492ZM449.164 186.074H452.402V120.633H449.164Z' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M155.817 186.074H159.055V119.696H155.817ZM214.488 186.074H217.727V121.887H214.488ZM273.156 186.074H276.395V113.43H273.156ZM331.824 186.074H335.063V119.004H331.824ZM390.492 186.074H393.731V89.133H390.492ZM449.164 186.074H452.402V120.633H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M157.438 119.696V119.696' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M155.445 119.695H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M157.438 119.696V119.696' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M155.445 119.695H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M216.106 121.887V121.887' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M214.113 121.886H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M216.106 121.887V121.887' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M214.113 121.886H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M274.774 113.43V113.43' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M272.781 113.43H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M274.774 113.43V113.43' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M272.781 113.43H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M333.445 119.004V119.004' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M331.453 119.004H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M333.445 119.004V119.004' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M331.453 119.004H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M392.113 89.133V89.133' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M390.121 89.133H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M392.113 89.133V89.133' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M390.121 89.133H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M450.781 120.633V120.633' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M448.789 120.633H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M450.781 120.633V120.633' fill='#c285c2'/> +<path clip-path='url(#clip10)' d='M448.789 120.633H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M161.047 186.074H164.285V109.738H161.047ZM219.719 186.074H222.957V112.555H219.719ZM278.387 186.074H281.625V86.192H278.387ZM337.055 186.074H340.293V106.543H337.055ZM395.723 186.074H398.961V172.172H395.723ZM454.395 186.074H457.633V122.949H454.395Z' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M161.047 186.074H164.285V109.738H161.047ZM219.719 186.074H222.957V112.555H219.719ZM278.387 186.074H281.625V86.192H278.387ZM337.055 186.074H340.293V106.543H337.055ZM395.723 186.074H398.961V172.172H395.723ZM454.395 186.074H457.633V122.949H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M162.668 109.738V109.738' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M160.676 109.738H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M162.668 109.738V109.738' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M160.676 109.738H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M221.336 112.555V112.555' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M219.344 112.554H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M221.336 112.555V112.555' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M219.344 112.554H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M280.004 86.192V86.192' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M278.012 86.191H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M280.004 86.192V86.192' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M278.012 86.191H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M338.676 106.543V106.543' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M336.684 106.543H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M338.676 106.543V106.543' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M336.684 106.543H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M397.344 172.172V172.172' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M395.352 172.172H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M397.344 172.172V172.172' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M395.352 172.172H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M456.012 122.949V122.949' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M454.02 122.949H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M456.012 122.949V122.949' fill='#b366b3'/> +<path clip-path='url(#clip10)' d='M454.02 122.949H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M166.278 186.074H169.516V98.278H166.278ZM224.949 186.074H228.188V94.77H224.949ZM283.617 186.074H286.856V78.051H283.617ZM342.285 186.074H345.524V92.453H342.285ZM400.953 186.074H404.192V154.762H400.953ZM459.625 186.074H462.863V113.242H459.625Z' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M166.278 186.074H169.516V98.278H166.278ZM224.949 186.074H228.188V94.77H224.949ZM283.617 186.074H286.856V78.051H283.617ZM342.285 186.074H345.524V92.453H342.285ZM400.953 186.074H404.192V154.762H400.953ZM459.625 186.074H462.863V113.242H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M167.899 98.278V98.278' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M165.906 98.277H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M167.899 98.278V98.278' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M165.906 98.277H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M226.567 94.77V94.77' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M224.574 94.77H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M226.567 94.77V94.77' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M224.574 94.77H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M285.234 78.051V78.051' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M283.242 78.051H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M285.234 78.051V78.051' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M283.242 78.051H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M343.906 92.453V92.453' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M341.914 92.453H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M343.906 92.453V92.453' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M341.914 92.453H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M402.574 154.762V154.762' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M400.582 154.761H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M402.574 154.762V154.762' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M400.582 154.761H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M461.242 113.242V113.242' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M459.25 113.242H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M461.242 113.242V113.242' fill='#a447a4'/> +<path clip-path='url(#clip10)' d='M459.25 113.242H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M171.508 186.074H174.746V109.172H171.508ZM230.18 186.074H233.414V112.617H230.18ZM288.848 186.074H292.086V86.254H288.848ZM347.516 186.074H350.754V107.418H347.516ZM406.184 186.074H409.422V172.235H406.184ZM464.856 186.074H468.094V124.266H464.856Z' fill='#942994'/> +<path clip-path='url(#clip10)' d='M171.508 186.074H174.746V109.172H171.508ZM230.18 186.074H233.414V112.617H230.18ZM288.848 186.074H292.086V86.254H288.848ZM347.516 186.074H350.754V107.418H347.516ZM406.184 186.074H409.422V172.235H406.184ZM464.856 186.074H468.094V124.266H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M173.129 109.172V109.172' fill='#942994'/> +<path clip-path='url(#clip10)' d='M171.137 109.172H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M173.129 109.172V109.172' fill='#942994'/> +<path clip-path='url(#clip10)' d='M171.137 109.172H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M231.797 112.617V112.617' fill='#942994'/> +<path clip-path='url(#clip10)' d='M229.805 112.617H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M231.797 112.617V112.617' fill='#942994'/> +<path clip-path='url(#clip10)' d='M229.805 112.617H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M290.465 86.254V86.254' fill='#942994'/> +<path clip-path='url(#clip10)' d='M288.473 86.254H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M290.465 86.254V86.254' fill='#942994'/> +<path clip-path='url(#clip10)' d='M288.473 86.254H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M349.137 107.418V107.418' fill='#942994'/> +<path clip-path='url(#clip10)' d='M347.145 107.418H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M349.137 107.418V107.418' fill='#942994'/> +<path clip-path='url(#clip10)' d='M347.145 107.418H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M407.805 172.235V172.235' fill='#942994'/> +<path clip-path='url(#clip10)' d='M405.813 172.234H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M407.805 172.235V172.235' fill='#942994'/> +<path clip-path='url(#clip10)' d='M405.813 172.234H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M466.473 124.266V124.266' fill='#942994'/> +<path clip-path='url(#clip10)' d='M464.481 124.266H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M466.473 124.266V124.266' fill='#942994'/> +<path clip-path='url(#clip10)' d='M464.481 124.266H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M411.414 186.074H414.652V151.946H411.414ZM176.738 186.074H179.977V117.375H176.738ZM235.41 186.074H238.645V119.567H235.41ZM294.078 186.074H297.317V116.813H294.078ZM352.746 186.074H355.984V123.891H352.746ZM470.086 186.074H473.324V117.313H470.086Z' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M411.414 186.074H414.652V151.946H411.414ZM176.738 186.074H179.977V117.375H176.738ZM235.41 186.074H238.645V119.567H235.41ZM294.078 186.074H297.317V116.813H294.078ZM352.746 186.074H355.984V123.891H352.746ZM470.086 186.074H473.324V117.313H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M413.035 151.946V151.946' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M411.043 151.945H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M413.035 151.946V151.946' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M411.043 151.945H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M178.36 117.375V117.375' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M176.367 117.375H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M178.36 117.375V117.375' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M176.367 117.375H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M237.027 119.567V119.567' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M235.035 119.566H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M237.027 119.567V119.567' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M235.035 119.566H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M295.695 116.813V116.813' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M293.703 116.813H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M295.695 116.813V116.813' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M293.703 116.813H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M354.367 123.891V123.891' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M352.375 123.89H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M354.367 123.891V123.891' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M352.375 123.89H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M471.703 117.313V117.313' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M469.711 117.313H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M471.703 117.313V117.313' fill='#850a85'/> +<path clip-path='url(#clip10)' d='M469.711 117.313H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M181.969 186.074H185.207V121.762H181.969ZM240.641 186.074H243.875V122.074H240.641ZM299.309 186.074H302.547V122.574H299.309ZM357.977 186.074H361.215V121.949H357.977ZM475.317 186.074H478.555V113.746H475.317Z' fill='#760076'/> +<path clip-path='url(#clip10)' d='M181.969 186.074H185.207V121.762H181.969ZM240.641 186.074H243.875V122.074H240.641ZM299.309 186.074H302.547V122.574H299.309ZM357.977 186.074H361.215V121.949H357.977ZM475.317 186.074H478.555V113.746H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M183.59 121.762V121.762' fill='#760076'/> +<path clip-path='url(#clip10)' d='M181.598 121.762H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M183.59 121.762V121.762' fill='#760076'/> +<path clip-path='url(#clip10)' d='M181.598 121.762H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M242.258 122.074V122.074' fill='#760076'/> +<path clip-path='url(#clip10)' d='M240.266 122.074H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M242.258 122.074V122.074' fill='#760076'/> +<path clip-path='url(#clip10)' d='M240.266 122.074H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M300.926 122.574V122.574' fill='#760076'/> +<path clip-path='url(#clip10)' d='M298.933 122.574H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M300.926 122.574V122.574' fill='#760076'/> +<path clip-path='url(#clip10)' d='M298.933 122.574H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M359.598 121.949V121.949' fill='#760076'/> +<path clip-path='url(#clip10)' d='M357.606 121.949H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M359.598 121.949V121.949' fill='#760076'/> +<path clip-path='url(#clip10)' d='M357.606 121.949H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M476.934 113.746V113.746' fill='#760076'/> +<path clip-path='url(#clip10)' d='M474.942 113.746H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M476.934 113.746V113.746' fill='#760076'/> +<path clip-path='url(#clip10)' d='M474.942 113.746H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M187.199 186.074H190.438V122.887H187.199ZM245.871 186.074H249.106V122.637H245.871ZM304.539 186.074H307.777V123.387H304.539ZM363.207 186.074H366.445V125.391H363.207ZM421.875 186.074H425.113V169.164H421.875ZM480.547 186.074H483.785V121.571H480.547Z' fill='#670067'/> +<path clip-path='url(#clip10)' d='M187.199 186.074H190.438V122.887H187.199ZM245.871 186.074H249.106V122.637H245.871ZM304.539 186.074H307.777V123.387H304.539ZM363.207 186.074H366.445V125.391H363.207ZM421.875 186.074H425.113V169.164H421.875ZM480.547 186.074H483.785V121.571H480.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M188.82 122.887V122.887' fill='#670067'/> +<path clip-path='url(#clip10)' d='M186.828 122.886H190.813' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M188.82 122.887V122.887' fill='#670067'/> +<path clip-path='url(#clip10)' d='M186.828 122.886H190.813' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M247.488 122.637V122.637' fill='#670067'/> +<path clip-path='url(#clip10)' d='M245.496 122.637H249.481' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M247.488 122.637V122.637' fill='#670067'/> +<path clip-path='url(#clip10)' d='M245.496 122.637H249.481' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M306.156 123.387V123.387' fill='#670067'/> +<path clip-path='url(#clip10)' d='M304.164 123.387H308.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M306.156 123.387V123.387' fill='#670067'/> +<path clip-path='url(#clip10)' d='M304.164 123.387H308.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M364.828 125.391V125.391' fill='#670067'/> +<path clip-path='url(#clip10)' d='M362.836 125.39H366.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M364.828 125.391V125.391' fill='#670067'/> +<path clip-path='url(#clip10)' d='M362.836 125.39H366.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M423.496 169.164V169.164' fill='#670067'/> +<path clip-path='url(#clip10)' d='M421.504 169.164H425.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M423.496 169.164V169.164' fill='#670067'/> +<path clip-path='url(#clip10)' d='M421.504 169.164H425.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M482.164 121.571V121.571' fill='#670067'/> +<path clip-path='url(#clip10)' d='M480.172 121.57H484.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M482.164 121.571V121.571' fill='#670067'/> +<path clip-path='url(#clip10)' d='M480.172 121.57H484.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path clip-path='url(#clip10)' d='M419.477 233.301H487.762V211.324H419.477Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 254.512 88.837)'> +<use x='168.285' xlink:href='#g1-72' y='129.265'/> +<use x='172.021' xlink:href='#g1-80' y='129.265'/> +<use x='175.402' xlink:href='#g1-45' y='129.265'/> +<use x='177.167' xlink:href='#g1-90' y='129.265'/> +<use x='180.401' xlink:href='#g1-52' y='129.265'/> +<use x='183.047' xlink:href='#g1-45' y='129.265'/> +<use x='184.812' xlink:href='#g1-71' y='129.265'/> +<use x='188.34' xlink:href='#g1-52' y='129.265'/> +<use x='190.987' xlink:href='#g1-44' y='129.265'/> +<use x='194.221' xlink:href='#g1-49' y='129.265'/> +<use x='196.867' xlink:href='#g1-54' y='129.265'/> +<use x='199.514' xlink:href='#g1-71' y='129.265'/> +<use x='203.042' xlink:href='#g1-98' y='129.265'/> +<use x='168.285' xlink:href='#g1-56' y='134.884'/> +<use x='170.931' xlink:href='#g1-45' y='134.884'/> +<use x='172.695' xlink:href='#g1-99' y='134.884'/> +<use x='175.048' xlink:href='#g1-111' y='134.884'/> +<use x='177.547' xlink:href='#g1-114' y='134.884'/> +<use x='179.355' xlink:href='#g1-101' y='134.884'/> +<use x='183.471' xlink:href='#g1-73' y='134.884'/> +<use x='184.941' xlink:href='#g1-110' y='134.884'/> +<use x='187.674' xlink:href='#g1-116' y='134.884'/> +<use x='189.585' xlink:href='#g1-101' y='134.884'/> +<use x='191.938' xlink:href='#g1-108' y='134.884'/> +<use x='194.965' xlink:href='#g1-88' y='134.884'/> +<use x='198.493' xlink:href='#g1-69' y='134.884'/> +<use x='201.667' xlink:href='#g1-79' y='134.884'/> +<use x='205.576' xlink:href='#g1-78' y='134.884'/> +<use x='211.076' xlink:href='#g1-64' y='134.884'/> +<use x='214.605' xlink:href='#g1-50' y='134.884'/> +<use x='217.251' xlink:href='#g1-46' y='134.884'/> +<use x='218.721' xlink:href='#g1-55' y='134.884'/> +<use x='221.368' xlink:href='#g1-71' y='134.884'/> +<use x='224.896' xlink:href='#g1-104' y='134.884'/> +<use x='227.629' xlink:href='#g1-122' y='134.884'/> +<use x='168.285' xlink:href='#g1-85' y='140.503'/> +<use x='171.917' xlink:href='#g1-98' y='140.503'/> +<use x='174.65' xlink:href='#g1-117' y='140.503'/> +<use x='177.383' xlink:href='#g1-110' y='140.503'/> +<use x='180.116' xlink:href='#g1-116' y='140.503'/> +<use x='182.027' xlink:href='#g1-117' y='140.503'/> +<use x='186.524' xlink:href='#g1-49' y='140.503'/> +<use x='189.17' xlink:href='#g1-56' y='140.503'/> +<use x='191.817' xlink:href='#g1-46' y='140.503'/> +<use x='193.287' xlink:href='#g1-48' y='140.503'/> +<use x='195.933' xlink:href='#g1-52' y='140.503'/> +<use x='198.58' xlink:href='#g1-46' y='140.503'/> +<use x='200.05' xlink:href='#g1-49' y='140.503'/> +<use x='202.696' xlink:href='#g1-44' y='140.503'/> +<use x='205.931' xlink:href='#g1-71' y='140.503'/> +<use x='209.459' xlink:href='#g1-67' y='140.503'/> +<use x='212.841' xlink:href='#g1-67' y='140.503'/> +<use x='217.986' xlink:href='#g1-55' y='140.503'/> +<use x='220.633' xlink:href='#g1-46' y='140.503'/> +<use x='222.103' xlink:href='#g1-52' y='140.503'/> +<use x='224.749' xlink:href='#g1-46' y='140.503'/> +<use x='226.219' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 2.877 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 61.546 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 120.215 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 178.884 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 237.553 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 296.222 285.711)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 8.107 282.329)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-53' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 66.776 283.832)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 125.445 284.96)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 184.114 288.153)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 242.783 335.434)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 301.452 255.652)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-52' y='140.503'/> +<use x='175.048' xlink:href='#g1-56' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 13.338 284.96)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 72.007 287.026)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-56' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 130.676 284.02)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 189.345 280.952)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-56' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 248.014 316.584)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 306.683 273.5)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 18.568 281.954)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 77.237 284.146)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 135.906 275.691)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 194.575 281.265)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 253.244 251.394)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-53' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 311.913 282.893)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-52' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 23.799 271.997)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 82.468 274.815)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 141.137 248.45)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-54' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 199.806 268.803)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 258.475 334.432)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 317.144 285.21)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 29.029 260.537)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-52' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 87.698 257.03)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-52' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 146.367 240.309)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-55' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 205.036 254.713)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-52' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 263.705 317.023)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 322.374 275.504)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 34.26 271.433)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 92.929 274.877)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 151.598 248.513)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 210.267 269.68)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 268.936 334.494)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 327.605 286.525)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 274.166 314.205)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-53' y='140.503'/> +<use x='175.048' xlink:href='#g1-52' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 39.49 279.637)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 98.159 281.828)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 156.828 279.073)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 215.497 286.149)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-57' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 332.835 279.574)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 44.72 284.02)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 103.389 284.333)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 162.058 284.834)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 220.727 284.208)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-50' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 338.065 276.005)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-49' y='140.503'/> +<use x='175.048' xlink:href='#g1-54' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 49.951 285.147)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 108.62 284.897)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-49' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 167.289 285.648)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-48' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 225.958 287.652)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-57' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 284.627 331.426)'> +<use x='168.285' xlink:href='#g1-48' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-50' y='140.503'/> +<use x='175.048' xlink:href='#g1-55' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 343.296 283.832)'> +<use x='168.285' xlink:href='#g1-49' y='140.503'/> +<use x='170.931' xlink:href='#g1-46' y='140.503'/> +<use x='172.401' xlink:href='#g1-48' y='140.503'/> +<use x='175.048' xlink:href='#g1-51' y='140.503'/> +</g> +<g transform='matrix(0 -1 1 0 -27.345 343.63)'> +<use x='168.285' xlink:href='#g0-82' y='140.503'/> +<use x='174.255' xlink:href='#g0-101' y='140.503'/> +<use x='178.351' xlink:href='#g0-108' y='140.503'/> +<use x='180.551' xlink:href='#g0-97' y='140.503'/> +<use x='184.979' xlink:href='#g0-116' y='140.503'/> +<use x='188.307' xlink:href='#g0-105' y='140.503'/> +<use x='190.507' xlink:href='#g0-118' y='140.503'/> +<use x='194.755' xlink:href='#g0-101' y='140.503'/> +<use x='201.922' xlink:href='#g0-114' y='140.503'/> +<use x='205.07' xlink:href='#g0-115' y='140.503'/> +<use x='208.603' xlink:href='#g0-115' y='140.503'/> +<use x='215.207' xlink:href='#g2-40' y='140.503'/> +<use x='218.5' xlink:href='#g2-108' y='140.503'/> +<use x='220.521' xlink:href='#g2-111' y='140.503'/> +<use x='224.52' xlink:href='#g2-119' y='140.503'/> +<use x='230.068' xlink:href='#g2-101' y='140.503'/> +<use x='233.832' xlink:href='#g2-114' y='140.503'/> +<use x='239.547' xlink:href='#g2-105' y='140.503'/> +<use x='241.567' xlink:href='#g2-115' y='140.503'/> +<use x='247.636' xlink:href='#g2-98' y='140.503'/> +<use x='252.244' xlink:href='#g2-101' y='140.503'/> +<use x='256.008' xlink:href='#g2-116' y='140.503'/> +<use x='259.066' xlink:href='#g2-116' y='140.503'/> +<use x='262.124' xlink:href='#g2-101' y='140.503'/> +<use x='265.887' xlink:href='#g2-114' y='140.503'/> +<use x='268.779' xlink:href='#g2-41' y='140.503'/> +</g> +<path d='M136.149 231.446H402.137V214.453H136.149Z' fill='#ffffff'/> +<path d='M136.149 231.446H402.137V214.453H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='#f0e0f0'/> +<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -33.522 84.43)'> +<use x='185.011' xlink:href='#g2-109' y='140.503'/> +<use x='191.736' xlink:href='#g2-105' y='140.503'/> +</g> +<path d='M163.422 224.941H166.41V216.973H163.422ZM169.398 224.941H172.391V218.965H169.398Z' fill='#e1c2e1'/> +<path d='M163.422 224.941H166.41V216.972H163.422ZM169.398 224.941H172.391V218.964H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.56 83.976)'> +<use x='208.137' xlink:href='#g2-116' y='140.503'/> +<use x='211.195' xlink:href='#g2-99' y='140.503'/> +</g> +<path d='M185.586 224.941H188.574V216.973H185.586ZM191.563 224.941H194.555V218.965H191.563Z' fill='#d1a3d1'/> +<path d='M185.586 224.941H188.574V216.972H185.586ZM191.563 224.941H194.555V218.964H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.159 84.43)'> +<use x='229.9' xlink:href='#g2-106' y='140.503'/> +<use x='232.155' xlink:href='#g2-101' y='140.503'/> +</g> +<path d='M206.949 224.941H209.938V216.973H206.949ZM212.926 224.941H215.914V218.965H212.926Z' fill='#c285c2'/> +<path d='M206.949 224.941H209.938V216.972H206.949ZM212.926 224.941H215.914V218.964H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.958 83.47)'> +<use x='252.061' xlink:href='#g2-115' y='140.503'/> +<use x='255.307' xlink:href='#g2-110' y='140.503'/> +</g> +<path d='M229.91 224.941H232.898V216.973H229.91ZM235.887 224.941H238.875V218.965H235.887Z' fill='#b366b3'/> +<path d='M229.91 224.941H232.898V216.972H229.91ZM235.887 224.941H238.875V218.964H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -32.781 83.47)'> +<use x='274.845' xlink:href='#g2-114' y='140.503'/> +<use x='277.737' xlink:href='#g2-112' y='140.503'/> +</g> +<path d='M252.516 224.941H255.504V216.973H252.516ZM258.496 224.941H261.484V218.965H258.496Z' fill='#a447a4'/> +<path d='M252.516 224.941H255.504V216.972H252.516ZM258.496 224.941H261.484V218.964H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -39.001 84.467)'> +<use x='303.672' xlink:href='#g2-104' y='140.503'/> +<use x='308.045' xlink:href='#g2-111' y='140.503'/> +<use x='312.279' xlink:href='#g2-97' y='140.503'/> +<use x='316.112' xlink:href='#g2-114' y='140.503'/> +<use x='319.004' xlink:href='#g2-100' y='140.503'/> +</g> +<path d='M287.563 224.941H290.551V216.973H287.563ZM293.543 224.941H296.531V218.965H293.543Z' fill='#942994'/> +<path d='M287.563 224.941H290.551V216.972H287.563ZM293.543 224.941H296.531V218.964H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -37.472 84.467)'> +<use x='337.19' xlink:href='#g2-103' y='140.503'/> +<use x='341.424' xlink:href='#g2-108' y='140.503'/> +<use x='343.444' xlink:href='#g2-105' y='140.503'/> +<use x='345.464' xlink:href='#g2-98' y='140.503'/> +<use x='350.072' xlink:href='#g2-99' y='140.503'/> +</g> +<path d='M319.551 224.941H322.539V216.973H319.551ZM325.527 224.941H328.52V218.965H325.527Z' fill='#850a85'/> +<path d='M319.551 224.941H322.539V216.972H319.551ZM325.527 224.941H328.52V218.964H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.051 84.467)'> +<use x='366.757' xlink:href='#g2-116' y='140.503'/> +<use x='369.815' xlink:href='#g2-98' y='140.503'/> +<use x='374.187' xlink:href='#g2-98' y='140.503'/> +</g> +<path d='M346.699 224.941H349.688V216.973H346.699ZM352.676 224.941H355.664V218.965H352.676Z' fill='#760076'/> +<path d='M346.699 224.941H349.688V216.972H346.699ZM352.676 224.941H355.664V218.964H352.676Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -34.135 83.47)'> +<use x='392.986' xlink:href='#g2-115' y='140.503'/> +<use x='396.233' xlink:href='#g2-109' y='140.503'/> +</g> +<path d='M372.012 224.941H375V216.973H372.012ZM377.988 224.941H380.977V218.965H377.988Z' fill='#670067'/> +<path d='M372.012 224.941H375V216.972H372.012ZM377.988 224.941H380.977V218.964H377.988Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/> +<g transform='matrix(1 0 0 1 -35.145 84.43)'> +<use x='419.31' xlink:href='#g2-115' y='140.503'/> +<use x='422.556' xlink:href='#g2-109' y='140.503'/> +<use x='429.281' xlink:href='#g2-105' y='140.503'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg new file mode 100644 index 0000000..86a97bf --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg @@ -0,0 +1,952 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.629pt' height='170.383pt' viewBox='52.934 54.994 381.629 170.383'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip1'> +<path d='M82.148 209.23H434.164V83.984H82.148Z'/> +</clipPath> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +</defs> +<g id='page1'> +<path d='M140.82 218.086V209.23M199.488 218.086V209.23M258.156 218.086V209.23M316.824 218.086V209.23M375.496 218.086V209.23M140.82 75.129V83.984M199.488 75.129V83.984M258.156 75.129V83.984M316.824 75.129V83.984M375.496 75.129V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M111.484 213.484V209.23M170.152 213.484V209.23M228.824 213.484V209.23M287.492 213.484V209.23M346.16 213.484V209.23M404.828 213.484V209.23M111.484 79.734V83.984M170.152 79.734V83.984M228.824 79.734V83.984M287.492 79.734V83.984M346.16 79.734V83.984M404.828 79.734V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 209.23H86.402M82.148 177.918H86.402M82.148 146.609H86.402M82.148 115.297H86.402M82.148 83.984H86.402M434.164 209.23H429.91M434.164 177.918H429.91M434.164 146.609H429.91M434.164 115.297H429.91M434.164 83.984H429.91' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 209.23V83.984H434.164V209.23H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -11.54 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-99'/> +<use x='118.25' y='188.674' xlink:href='#g3-102'/> +<use x='120.838' y='188.674' xlink:href='#g3-114'/> +<use x='123.73' y='188.674' xlink:href='#g3-97'/> +<use x='127.798' y='188.674' xlink:href='#g3-99'/> +</g> +<g transform='matrix(1 0 0 1 45.565 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-108'/> +<use x='116.507' y='188.674' xlink:href='#g3-101'/> +<use x='120.271' y='188.674' xlink:href='#g3-97'/> +<use x='124.339' y='188.674' xlink:href='#g3-110'/> +<use x='128.711' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 106.188 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-114'/> +<use x='117.379' y='188.674' xlink:href='#g3-101'/> +<use x='121.142' y='188.674' xlink:href='#g3-100'/> +<use x='125.515' y='188.674' xlink:href='#g3-105'/> +<use x='127.535' y='188.674' xlink:href='#g3-115'/> +</g> +<g transform='matrix(1 0 0 1 159.716 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-108'/> +<use x='116.507' y='188.674' xlink:href='#g3-97'/> +<use x='120.34' y='188.674' xlink:href='#g3-114'/> +<use x='123.232' y='188.674' xlink:href='#g3-115'/> +<use x='126.478' y='188.674' xlink:href='#g3-111'/> +<use x='130.712' y='188.674' xlink:href='#g3-110'/> +<use x='135.085' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 215.596 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-109'/> +<use x='121.211' y='188.674' xlink:href='#g3-115'/> +<use x='124.458' y='188.674' xlink:href='#g3-116'/> +<use x='127.516' y='188.674' xlink:href='#g3-114'/> +<use x='130.408' y='188.674' xlink:href='#g3-101'/> +<use x='134.171' y='188.674' xlink:href='#g3-115'/> +<use x='137.418' y='188.674' xlink:href='#g3-115'/> +<use x='140.664' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 277.158 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-114'/> +<use x='117.379' y='188.674' xlink:href='#g3-112'/> +<use x='121.751' y='188.674' xlink:href='#g3-116'/> +<use x='124.809' y='188.674' xlink:href='#g3-101'/> +<use x='128.573' y='188.674' xlink:href='#g3-115'/> +<use x='131.819' y='188.674' xlink:href='#g3-116'/> +<use x='134.877' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 22.192)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.12)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.431)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.743)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.054)'> +<use x='114.487' y='188.674' xlink:href='#g2-50'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<path d='M82.148 146.609H434.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' fill='#933' clip-path='url(#clip1)'/> +<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M87.949 146.609V146.484' fill='#933' clip-path='url(#clip1)'/> +<path d='M87.949 146.609V146.484' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M85.953 146.484H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M87.949 146.609V146.734' fill='#933' clip-path='url(#clip1)'/> +<path d='M87.949 146.609V146.734' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M89.941 146.734H85.957' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M146.617 146.609V146.359' fill='#933' clip-path='url(#clip1)'/> +<path d='M146.617 146.609V146.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M144.625 146.36H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M146.617 146.609V146.859' fill='#933' clip-path='url(#clip1)'/> +<path d='M146.617 146.609V146.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M148.61 146.86H144.625' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M205.285 146.609V146.297' fill='#933' clip-path='url(#clip1)'/> +<path d='M205.285 146.609V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M203.293 146.297H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M205.285 146.609V146.922' fill='#933' clip-path='url(#clip1)'/> +<path d='M205.285 146.609V146.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M207.278 146.922H203.293' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M263.953 146.609V146.422' fill='#933' clip-path='url(#clip1)'/> +<path d='M263.953 146.609V146.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M261.961 146.422H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M263.953 146.609V146.797' fill='#933' clip-path='url(#clip1)'/> +<path d='M263.953 146.609V146.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M265.949 146.797H261.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M322.625 146.609V146.168' fill='#933' clip-path='url(#clip1)'/> +<path d='M322.625 146.609V146.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M320.629 146.168H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M322.625 146.609V147.047' fill='#933' clip-path='url(#clip1)'/> +<path d='M322.625 146.609V147.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M324.617 147.046H320.633' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M381.293 146.609V145.168' fill='#933' clip-path='url(#clip1)'/> +<path d='M381.293 146.609V145.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M379.301 145.168H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M381.293 146.609V148.047' fill='#933' clip-path='url(#clip1)'/> +<path d='M381.293 146.609V148.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M383.285 148.046H379.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M91.559 209.23H94.797V147.172H91.559ZM150.227 209.23H153.465V145.48H150.227ZM208.899 209.23H212.133V146.797H208.899ZM267.567 209.23H270.805V149.051H267.567ZM326.234 209.23H329.473V146.359H326.234ZM384.902 209.23H388.141V132.707H384.902Z' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M91.559 209.23H94.797V147.172H91.559ZM150.227 209.23H153.465V145.48H150.227ZM208.899 209.23H212.133V146.797H208.899ZM267.567 209.23H270.805V149.051H267.567ZM326.234 209.23H329.473V146.359H326.234ZM384.902 209.23H388.141V132.707H384.902Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M93.18 147.172V146.922' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M93.18 147.172V146.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M91.184 146.922H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M93.18 147.172V147.422' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M93.18 147.172V147.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M95.172 147.422H91.187' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M151.848 145.48V145.23' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M151.848 145.48V145.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M149.855 145.23H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M151.848 145.48V145.73' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M151.848 145.48V145.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M153.84 145.73H149.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M210.516 146.797V146.484' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M210.516 146.797V146.484' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M208.523 146.484H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M210.516 146.797V147.109' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M210.516 146.797V147.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M212.508 147.109H208.523' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M269.184 149.051V148.426' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M269.184 149.051V148.426' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M267.191 148.426H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M269.184 149.051V149.676' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M269.184 149.051V149.676' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M271.179 149.676H267.191' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M327.856 146.359V144.164' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M327.856 146.359V144.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M325.859 144.164H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M327.856 146.359V148.551' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M327.856 146.359V148.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M329.847 148.55H325.863' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M386.524 132.707V129.137' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M386.524 132.707V129.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M384.531 129.136H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M386.524 132.707V136.273' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M386.524 132.707V136.273' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M388.515 136.273H384.531' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M96.789 209.23H100.027V146.359H96.789ZM155.457 209.23H158.695V138.781H155.457ZM214.129 209.23H217.363V142.476H214.129ZM272.797 209.23H276.035V135.086H272.797ZM331.465 209.23H334.703V146.922H331.465ZM390.133 209.23H393.371V83.984H390.133Z' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M96.789 209.23H100.027V146.359H96.789ZM155.457 209.23H158.695V138.781H155.457ZM214.129 209.23H217.363V142.476H214.129ZM272.797 209.23H276.035V135.086H272.797ZM331.465 209.23H334.703V146.922H331.465ZM390.133 209.23H393.371V83.984H390.133Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M98.41 146.359V146.043' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M98.41 146.359V146.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M96.414 146.043H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M98.41 146.359V146.672' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M98.41 146.359V146.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M100.402 146.672H96.418' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M157.078 138.781V138.469' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M157.078 138.781V138.469' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M155.086 138.469H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M157.078 138.781V139.094' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M157.078 138.781V139.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M159.071 139.093H155.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M215.746 142.476V142.289' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M215.746 142.476V142.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M213.754 142.289H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M215.746 142.476V142.664' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M215.746 142.476V142.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M217.739 142.664H213.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M274.414 135.086V132.957' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M274.414 135.086V132.957' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M272.422 132.957H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M274.414 135.086V137.215' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M274.414 135.086V137.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M276.41 137.215H272.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M333.086 146.922V145.73' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M333.086 146.922V145.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M331.09 145.73H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M333.086 146.922V148.109' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M333.086 146.922V148.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M335.078 148.109H331.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M102.02 209.23H105.258V142.223H102.02ZM160.688 209.23H163.926V143.851H160.688ZM219.359 209.23H222.594V137.277H219.359ZM278.027 209.23H281.266V131.328H278.027ZM336.695 209.23H339.934V120.934H336.695ZM395.363 209.23H398.602V83.984H395.363Z' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M102.02 209.23H105.258V142.223H102.02ZM160.688 209.23H163.926V143.851H160.688ZM219.359 209.23H222.594V137.277H219.359ZM278.027 209.23H281.266V131.328H278.027ZM336.695 209.23H339.934V120.934H336.695ZM395.363 209.23H398.602V83.984H395.363Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M103.641 142.223V142.098' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M103.641 142.223V142.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M101.644 142.097H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M103.641 142.223V142.351' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M103.641 142.223V142.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M105.633 142.352H101.648' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M162.309 143.851V143.101' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M162.309 143.851V143.101' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M160.316 143.101H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M162.309 143.851V144.605' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M162.309 143.851V144.605' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M164.301 144.605H160.316' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M220.977 137.277V136.902' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M220.977 137.277V136.902' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M218.984 136.903H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M220.977 137.277V137.652' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M220.977 137.277V137.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M222.969 137.652H218.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M279.645 131.328V130.516' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M279.645 131.328V130.516' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M277.652 130.516H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M279.645 131.328V132.141' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M279.645 131.328V132.141' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M281.64 132.14H277.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M338.317 120.934V120.305' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M338.317 120.934V120.305' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M336.32 120.304H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M338.317 120.934V121.559' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M338.317 120.934V121.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M340.308 121.559H336.324' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M396.984 83.984' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M394.992 83.984H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M396.984 83.984' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M394.992 83.984H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M107.25 209.23H110.488V120.367H107.25ZM165.918 209.23H169.156V137.777H165.918ZM224.59 209.23H227.824V111.789H224.59ZM283.258 209.23H286.496V92.187H283.258ZM341.926 209.23H345.164V134.019H341.926ZM400.594 209.23H403.832V118.051H400.594Z' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M107.25 209.23H110.488V120.367H107.25ZM165.918 209.23H169.156V137.777H165.918ZM224.59 209.23H227.824V111.789H224.59ZM283.258 209.23H286.496V92.187H283.258ZM341.926 209.23H345.164V134.019H341.926ZM400.594 209.23H403.832V118.051H400.594Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M108.871 120.367V119.992' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M108.871 120.367V119.992' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M106.875 119.992H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M108.871 120.367V120.746' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M108.871 120.367V120.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M110.864 120.746H106.879' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M167.539 137.777V137.527' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M167.539 137.777V137.527' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M165.547 137.528H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M167.539 137.777V138.027' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M167.539 137.777V138.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M169.532 138.028H165.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M226.207 111.789V111.726' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M226.207 111.789V111.726' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M224.215 111.726H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M226.207 111.789V111.851' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M226.207 111.789V111.851' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M228.2 111.851H224.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M284.875 92.187V90.308' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M284.875 92.187V90.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M282.883 90.309H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M284.875 92.187V94.066' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M284.875 92.187V94.066' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M286.868 94.066H282.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M343.547 134.019V132.894' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M343.547 134.019V132.894' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M341.551 132.895H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M343.547 134.019V135.148' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M343.547 134.019V135.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M345.539 135.148H341.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M402.215 118.051V112.289' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M402.215 118.051V112.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M400.223 112.289H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M402.215 118.051V123.812' fill='#bf80bf' clip-path='url(#clip1)'/> +<path d='M402.215 118.051V123.812' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M404.207 123.812H400.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M112.481 209.23H115.719V145.918H112.481ZM171.149 209.23H174.387V145.105H171.149ZM229.82 209.23H233.055V147.672H229.82ZM288.488 209.23H291.727V149.176H288.488ZM347.156 209.23H350.395V104.211H347.156ZM405.824 209.23H409.063V115.422H405.824Z' fill='#c96' clip-path='url(#clip1)'/> +<path d='M112.481 209.23H115.719V145.918H112.481ZM171.149 209.23H174.387V145.105H171.149ZM229.82 209.23H233.055V147.672H229.82ZM288.488 209.23H291.727V149.176H288.488ZM347.156 209.23H350.395V104.211H347.156ZM405.824 209.23H409.063V115.422H405.824Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M114.098 145.918V145.793' fill='#c96' clip-path='url(#clip1)'/> +<path d='M114.098 145.918V145.793' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M112.105 145.793H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M114.098 145.918V146.043' fill='#c96' clip-path='url(#clip1)'/> +<path d='M114.098 145.918V146.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M116.094 146.043H112.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M172.77 145.105V144.793' fill='#c96' clip-path='url(#clip1)'/> +<path d='M172.77 145.105V144.793' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M170.777 144.793H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M172.77 145.105V145.418' fill='#c96' clip-path='url(#clip1)'/> +<path d='M172.77 145.105V145.418' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M174.762 145.418H170.777' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M231.438 147.672V147.422' fill='#c96' clip-path='url(#clip1)'/> +<path d='M231.438 147.672V147.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M229.445 147.422H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M231.438 147.672V147.922' fill='#c96' clip-path='url(#clip1)'/> +<path d='M231.438 147.672V147.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M233.43 147.922H229.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M290.106 149.176V148.738' fill='#c96' clip-path='url(#clip1)'/> +<path d='M290.106 149.176V148.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M288.113 148.738H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M290.106 149.176V149.613' fill='#c96' clip-path='url(#clip1)'/> +<path d='M290.106 149.176V149.613' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M292.098 149.613H288.113' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M348.777 104.211V100.582' fill='#c96' clip-path='url(#clip1)'/> +<path d='M348.777 104.211V100.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M346.781 100.582H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M348.777 104.211V107.844' fill='#c96' clip-path='url(#clip1)'/> +<path d='M348.777 104.211V107.844' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M350.77 107.843H346.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M407.445 115.422V109.848' fill='#c96' clip-path='url(#clip1)'/> +<path d='M407.445 115.422V109.848' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M405.453 109.847H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M407.445 115.422V120.996' fill='#c96' clip-path='url(#clip1)'/> +<path d='M407.445 115.422V120.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M409.437 120.996H405.453' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M117.711 209.23H120.949V143.226H117.711ZM176.379 209.23H179.617V132.266H176.379ZM235.051 209.23H238.285V132.644H235.051ZM293.719 209.23H296.957V110.539H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M117.711 209.23H120.949V143.226H117.711ZM176.379 209.23H179.617V132.266H176.379ZM235.051 209.23H238.285V132.644H235.051ZM293.719 209.23H296.957V110.539H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M119.328 143.226V142.914' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M119.328 143.226V142.914' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M117.336 142.914H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M119.328 143.226V143.539' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M119.328 143.226V143.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M121.325 143.539H117.34' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M178 132.266V131.641' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M178 132.266V131.641' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M176.008 131.64H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M178 132.266V132.894' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M178 132.266V132.894' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M179.993 132.895H176.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M236.668 132.644V132.078' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M236.668 132.644V132.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M234.676 132.079H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M236.668 132.644V133.207' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M236.668 132.644V133.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M238.66 133.207H234.675' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M295.336 110.539V109.785' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M295.336 110.539V109.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M293.344 109.785H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M295.336 110.539V111.289' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M295.336 110.539V111.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M297.328 111.289H293.343' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M122.941 209.23H126.18V136.59H122.941ZM181.609 209.23H184.848V120.242H181.609ZM240.281 209.23H243.516V140.785H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V87.117H357.617ZM416.285 209.23H419.524V83.984H416.285Z' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M122.941 209.23H126.18V136.59H122.941ZM181.609 209.23H184.848V120.242H181.609ZM240.281 209.23H243.516V140.785H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V87.117H357.617ZM416.285 209.23H419.524V83.984H416.285Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M124.559 136.59V136.465' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M124.559 136.59V136.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M122.566 136.465H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M124.559 136.59V136.715' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M124.559 136.59V136.715' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M126.555 136.715H122.57' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M183.231 120.242V119.305' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M183.231 120.242V119.305' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M181.238 119.304H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M183.231 120.242V121.184' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M183.231 120.242V121.184' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M185.223 121.183H181.238' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M241.899 140.785V140.41' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M241.899 140.785V140.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M239.906 140.41H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M241.899 140.785V141.16' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M241.899 140.785V141.16' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M243.891 141.16H239.906' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M359.238 87.117V85.363' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M359.238 87.117V85.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M357.242 85.363H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M359.238 87.117V88.871' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M359.238 87.117V88.871' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M361.231 88.871H357.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip1)'/> +<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M128.172 209.23H131.41V141.285H128.172ZM186.84 209.23H190.078V131.266H186.84ZM245.512 209.23H248.746V139.781H245.512ZM304.18 209.23H307.418V99.328H304.18ZM362.848 209.23H366.086V105.34H362.848ZM421.516 209.23H424.754V83.984H421.516Z' fill='#399' clip-path='url(#clip1)'/> +<path d='M128.172 209.23H131.41V141.285H128.172ZM186.84 209.23H190.078V131.266H186.84ZM245.512 209.23H248.746V139.781H245.512ZM304.18 209.23H307.418V99.328H304.18ZM362.848 209.23H366.086V105.34H362.848ZM421.516 209.23H424.754V83.984H421.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M129.789 141.285V141.098' fill='#399' clip-path='url(#clip1)'/> +<path d='M129.789 141.285V141.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M127.797 141.097H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M129.789 141.285V141.473' fill='#399' clip-path='url(#clip1)'/> +<path d='M129.789 141.285V141.473' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M131.785 141.473H127.8' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M188.461 131.266V130.891' fill='#399' clip-path='url(#clip1)'/> +<path d='M188.461 131.266V130.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M186.469 130.891H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M188.461 131.266V131.641' fill='#399' clip-path='url(#clip1)'/> +<path d='M188.461 131.266V131.641' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M190.453 131.64H186.468' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M247.129 139.781V139.594' fill='#399' clip-path='url(#clip1)'/> +<path d='M247.129 139.781V139.594' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M245.137 139.593H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M247.129 139.781V139.969' fill='#399' clip-path='url(#clip1)'/> +<path d='M247.129 139.781V139.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M249.121 139.969H245.136' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M305.797 99.328V98.828' fill='#399' clip-path='url(#clip1)'/> +<path d='M305.797 99.328V98.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M303.804 98.828H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M305.797 99.328V99.828' fill='#399' clip-path='url(#clip1)'/> +<path d='M305.797 99.328V99.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M307.789 99.828H303.804' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M364.469 105.34V103.586' fill='#399' clip-path='url(#clip1)'/> +<path d='M364.469 105.34V103.586' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M362.473 103.586H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M364.469 105.34V107.094' fill='#399' clip-path='url(#clip1)'/> +<path d='M364.469 105.34V107.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M366.461 107.094H362.476' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M423.137 83.984' fill='#399' clip-path='url(#clip1)'/> +<path d='M421.144 83.984H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M423.137 83.984' fill='#399' clip-path='url(#clip1)'/> +<path d='M421.144 83.984H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M133.402 209.23H136.641V138.656H133.402ZM192.07 209.23H195.309V138.531H192.07ZM250.742 209.23H253.977V143.914H250.742ZM309.41 209.23H312.649V123H309.41ZM368.078 209.23H371.317V141.285H368.078ZM426.746 209.23H429.984V83.984H426.746Z' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M133.402 209.23H136.641V138.656H133.402ZM192.07 209.23H195.309V138.531H192.07ZM250.742 209.23H253.977V143.914H250.742ZM309.41 209.23H312.649V123H309.41ZM368.078 209.23H371.317V141.285H368.078ZM426.746 209.23H429.984V83.984H426.746Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M135.02 138.656V138.531' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M135.02 138.656V138.531' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M133.027 138.531H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M135.02 138.656V138.781' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M135.02 138.656V138.781' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M137.016 138.781H133.031' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M193.692 138.531V138.215' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M193.692 138.531V138.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M191.699 138.215H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M193.692 138.531V138.844' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M193.692 138.531V138.844' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M195.684 138.844H191.699' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M252.359 143.914V143.539' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M252.359 143.914V143.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M250.367 143.539H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M252.359 143.914V144.293' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M252.359 143.914V144.293' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M254.352 144.293H250.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M311.027 123V122.75' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M311.027 123V122.75' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M309.035 122.75H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M311.027 123V123.25' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M311.027 123V123.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M313.02 123.25H309.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M369.699 141.285V140.41' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M369.699 141.285V140.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M367.703 140.41H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M369.699 141.285V142.16' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M369.699 141.285V142.16' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M371.692 142.16H367.707' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M428.367 83.984' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M426.375 83.984H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M428.367 83.984' fill='#d9b3b3' clip-path='url(#clip1)'/> +<path d='M426.375 83.984H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<g transform='matrix(0 -1 1 0 -99.092 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -40.423 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 18.246 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 76.915 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 135.584 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 194.253 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -93.862 255.634)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -35.193 253.943)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 23.476 255.258)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 82.145 257.513)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 140.814 254.82)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 199.483 241.168)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -88.631 254.82)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -29.962 247.242)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 28.707 250.937)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 87.376 243.548)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 146.045 255.383)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 204.714 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-57'/> +<use x='126.877' y='188.674' xlink:href='#g2-49'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -83.401 250.687)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 -24.732 252.315)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 33.937 245.74)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 92.606 239.79)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 151.275 229.395)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-52'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 209.944 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-54'/> +<use x='126.877' y='188.674' xlink:href='#g2-53'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -78.17 228.831)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-52'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -19.501 246.241)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 39.168 220.252)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 97.837 200.651)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-56'/> +<use x='121.25' y='188.674' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 156.506 242.483)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 215.175 226.514)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-52'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -72.94 254.382)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 -14.271 253.567)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 44.398 256.135)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 103.067 257.638)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 161.736 212.675)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-54'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 220.405 223.884)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -67.709 251.689)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -9.04 240.73)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 49.629 241.105)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 108.298 219)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 166.967 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-49'/> +<use x='126.877' y='188.674' xlink:href='#g2-57'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 225.636 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-49'/> +<use x='126.877' y='188.674' xlink:href='#g2-55'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -62.479 245.051)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -3.81 228.706)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-52'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 54.859 249.246)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 113.528 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-49'/> +<use x='122.76' y='188.674' xlink:href='#g2-53'/> +<use x='125.406' y='188.674' xlink:href='#g2-53'/> +<use x='128.053' y='188.674' xlink:href='#g2-46'/> +<use x='129.523' y='188.674' xlink:href='#g2-50'/> +<use x='132.169' y='188.674' xlink:href='#g2-51'/> +<use x='134.816' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 172.197 195.579)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 230.866 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-55'/> +<use x='126.877' y='188.674' xlink:href='#g2-57'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -57.249 249.747)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 1.42 239.728)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 60.089 248.244)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 118.758 207.79)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-55'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 177.427 213.802)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-54'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 236.096 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-51'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-48'/> +<use x='126.877' y='188.674' xlink:href='#g2-57'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -52.018 247.117)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 6.651 246.992)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 65.32 252.378)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 123.989 231.462)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 182.658 249.747)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 241.327 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-48'/> +<use x='126.877' y='188.674' xlink:href='#g2-51'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -129.314 316.355)'> +<use x='114.487' y='188.674' xlink:href='#g1-82'/> +<use x='120.457' y='188.674' xlink:href='#g1-101'/> +<use x='124.553' y='188.674' xlink:href='#g1-108'/> +<use x='126.753' y='188.674' xlink:href='#g1-97'/> +<use x='131.181' y='188.674' xlink:href='#g1-116'/> +<use x='134.509' y='188.674' xlink:href='#g1-105'/> +<use x='136.709' y='188.674' xlink:href='#g1-118'/> +<use x='140.957' y='188.674' xlink:href='#g1-101'/> +<use x='148.124' y='188.674' xlink:href='#g1-116'/> +<use x='151.452' y='188.674' xlink:href='#g1-105'/> +<use x='153.652' y='188.674' xlink:href='#g1-109'/> +<use x='160.972' y='188.674' xlink:href='#g1-101'/> +<use x='168.139' y='188.674' xlink:href='#g3-40'/> +<use x='171.432' y='188.674' xlink:href='#g3-108'/> +<use x='173.453' y='188.674' xlink:href='#g3-111'/> +<use x='177.452' y='188.674' xlink:href='#g3-119'/> +<use x='183' y='188.674' xlink:href='#g3-101'/> +<use x='186.764' y='188.674' xlink:href='#g3-114'/> +<use x='192.479' y='188.674' xlink:href='#g3-105'/> +<use x='194.499' y='188.674' xlink:href='#g3-115'/> +<use x='200.568' y='188.674' xlink:href='#g3-98'/> +<use x='205.176' y='188.674' xlink:href='#g3-101'/> +<use x='208.94' y='188.674' xlink:href='#g3-116'/> +<use x='211.998' y='188.674' xlink:href='#g3-116'/> +<use x='215.056' y='188.674' xlink:href='#g3-101'/> +<use x='218.819' y='188.674' xlink:href='#g3-114'/> +<use x='221.711' y='188.674' xlink:href='#g3-41'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg new file mode 100644 index 0000000..c748877 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg @@ -0,0 +1,1255 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.628pt' height='255.741pt' viewBox='106.732 54.993 381.628 255.741'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip2'> +<path d='M135.949 249.281H487.961V81.519H135.949Z'/> +</clipPath> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/> +<use id='g3-49' xlink:href='#g0-49' transform='scale(1.143)'/> +<use id='g3-54' xlink:href='#g0-54' transform='scale(1.143)'/> +<use id='g3-56' xlink:href='#g0-56' transform='scale(1.143)'/> +<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-103' xlink:href='#g0-103' transform='scale(1.143)'/> +<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/> +<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/> +<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/> +<use id='g2-65' xlink:href='#g0-65' transform='scale(.714)'/> +<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/> +<use id='g2-68' xlink:href='#g0-68' transform='scale(.714)'/> +<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/> +<use id='g2-77' xlink:href='#g0-77' transform='scale(.714)'/> +<use id='g2-85' xlink:href='#g0-85' transform='scale(.714)'/> +<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/> +<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/> +<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/> +<use id='g2-100' xlink:href='#g0-100' transform='scale(.714)'/> +<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/> +<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/> +<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/> +<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/> +<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/> +<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/> +<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/> +<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/> +<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/> +<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/> +<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/> +<use id='g2-117' xlink:href='#g0-117' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/> +<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/> +<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/> +<path id='g0-65' d='M2.803-4.84H2.127L.209 0H.781L1.325-1.381H3.445L3.989 0H4.721L2.803-4.84ZM2.392-4.31L3.271-1.792H1.499L2.392-4.31Z'/> +<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/> +<path id='g0-68' d='M.683-4.84V0H2.664C3.919 0 4.931-1.06 4.931-2.378C4.931-3.745 3.912-4.84 2.664-4.84H.683ZM1.367-.411V-4.428H2.476C3.431-4.428 4.247-3.668 4.247-2.385C4.247-1.088 3.396-.411 2.476-.411H1.367Z'/> +<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/> +<path id='g0-77' d='M3.884-2.42C3.801-2.211 3.299-.983 3.229-.69H3.222C3.173-.893 2.852-1.695 2.783-1.876L1.583-4.84H.732V0H1.318V-4.282H1.325C1.381-4.038 1.743-3.117 1.778-3.041L2.943-.146H3.494L4.533-2.713C4.533-2.72 5.014-3.905 5.133-4.289H5.14V0H5.726V-4.84H4.868L3.884-2.42Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-85' d='M4.4-4.84H3.794V-1.625C3.794-.69 3.166-.265 2.566-.265S1.381-.697 1.381-1.618V-4.84H.676V-1.632C.676-.607 1.555 .146 2.559 .146C3.557 .146 4.4-.614 4.4-1.632V-4.84Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/> +<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-117' d='M3.243-3.096H2.636V-1.074C2.636-.516 2.162-.342 1.757-.342C1.241-.342 1.186-.481 1.186-.802V-3.096H.579V-.76C.579-.139 .851 .07 1.339 .07C1.625 .07 2.239 .014 2.657-.321V0H3.243V-3.096Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/> +</defs> +<g id='page2'> +<path d='M194.617 258.141V249.281M253.285 258.141V249.281M311.953 258.141V249.281M370.625 258.141V249.281M429.293 258.141V249.281M194.617 72.66V81.519M253.285 72.66V81.519M311.953 72.66V81.519M370.625 72.66V81.519M429.293 72.66V81.519' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.266V81.519M223.953 77.266V81.519M282.621 77.266V81.519M341.289 77.266V81.519M399.957 77.266V81.519M458.629 77.266V81.519' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.519H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.519H483.711' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M135.949 249.281V81.519H487.961V249.281H135.949Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -21.265 74.992)'> +<use x='168.285' y='188.688' xlink:href='#g3-97'/> +<use x='172.353' y='188.688' xlink:href='#g3-108'/> +<use x='174.373' y='188.688' xlink:href='#g3-108'/> +<use x='176.393' y='188.688' xlink:href='#g3-111'/> +<use x='180.863' y='188.688' xlink:href='#g3-99'/> +<use x='184.627' y='188.688' xlink:href='#g3-45'/> +<use x='187.449' y='188.688' xlink:href='#g3-116'/> +<use x='190.507' y='188.688' xlink:href='#g3-101'/> +<use x='194.271' y='188.688' xlink:href='#g3-115'/> +<use x='197.517' y='188.688' xlink:href='#g3-116'/> +<use x='200.575' y='188.688' xlink:href='#g3-49'/> +</g> +<g transform='matrix(1 0 0 1 36.532 74.992)'> +<use x='168.285' y='188.688' xlink:href='#g3-97'/> +<use x='172.353' y='188.688' xlink:href='#g3-108'/> +<use x='174.373' y='188.688' xlink:href='#g3-108'/> +<use x='176.393' y='188.688' xlink:href='#g3-111'/> +<use x='180.863' y='188.688' xlink:href='#g3-99'/> +<use x='184.627' y='188.688' xlink:href='#g3-45'/> +<use x='187.449' y='188.688' xlink:href='#g3-116'/> +<use x='190.507' y='188.688' xlink:href='#g3-101'/> +<use x='194.271' y='188.688' xlink:href='#g3-115'/> +<use x='197.517' y='188.688' xlink:href='#g3-116'/> +<use x='200.575' y='188.688' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 94.98 74.992)'> +<use x='168.285' y='188.688' xlink:href='#g3-115'/> +<use x='171.531' y='188.688' xlink:href='#g3-104'/> +<use x='175.904' y='188.688' xlink:href='#g3-54'/> +<use x='180.138' y='188.688' xlink:href='#g3-98'/> +<use x='184.746' y='188.688' xlink:href='#g3-101'/> +<use x='188.509' y='188.688' xlink:href='#g3-110'/> +<use x='192.882' y='188.688' xlink:href='#g3-99'/> +<use x='196.646' y='188.688' xlink:href='#g3-104'/> +<use x='201.018' y='188.688' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 153.649 74.992)'> +<use x='168.285' y='188.688' xlink:href='#g3-115'/> +<use x='171.531' y='188.688' xlink:href='#g3-104'/> +<use x='175.904' y='188.688' xlink:href='#g3-56'/> +<use x='180.138' y='188.688' xlink:href='#g3-98'/> +<use x='184.746' y='188.688' xlink:href='#g3-101'/> +<use x='188.509' y='188.688' xlink:href='#g3-110'/> +<use x='192.882' y='188.688' xlink:href='#g3-99'/> +<use x='196.646' y='188.688' xlink:href='#g3-104'/> +<use x='201.018' y='188.688' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 207.225 74.992)'> +<use x='168.285' y='188.688' xlink:href='#g3-120'/> +<use x='172.187' y='188.688' xlink:href='#g3-109'/> +<use x='178.912' y='188.688' xlink:href='#g3-97'/> +<use x='182.98' y='188.688' xlink:href='#g3-108'/> +<use x='185' y='188.688' xlink:href='#g3-108'/> +<use x='187.02' y='188.688' xlink:href='#g3-111'/> +<use x='191.49' y='188.688' xlink:href='#g3-99'/> +<use x='195.254' y='188.688' xlink:href='#g3-45'/> +<use x='198.076' y='188.688' xlink:href='#g3-116'/> +<use x='201.134' y='188.688' xlink:href='#g3-101'/> +<use x='204.898' y='188.688' xlink:href='#g3-115'/> +<use x='208.144' y='188.688' xlink:href='#g3-116'/> +<use x='211.202' y='188.688' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 263.494 74.992)'> +<use x='168.285' y='188.688' xlink:href='#g3-99'/> +<use x='172.049' y='188.688' xlink:href='#g3-97'/> +<use x='176.117' y='188.688' xlink:href='#g3-99'/> +<use x='179.88' y='188.688' xlink:href='#g3-104'/> +<use x='184.253' y='188.688' xlink:href='#g3-101'/> +<use x='188.017' y='188.688' xlink:href='#g3-45'/> +<use x='190.839' y='188.688' xlink:href='#g3-115'/> +<use x='194.086' y='188.688' xlink:href='#g3-99'/> +<use x='197.849' y='188.688' xlink:href='#g3-114'/> +<use x='200.741' y='188.688' xlink:href='#g3-97'/> +<use x='204.81' y='188.688' xlink:href='#g3-116'/> +<use x='207.868' y='188.688' xlink:href='#g3-99'/> +<use x='211.631' y='188.688' xlink:href='#g3-104'/> +<use x='216.004' y='188.688' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 62.23)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.677)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-53'/> +<use x='175.048' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -4.876)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -38.43)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-53'/> +<use x='175.048' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.983)'> +<use x='168.285' y='188.688' xlink:href='#g2-50'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -105.536)'> +<use x='168.285' y='188.688' xlink:href='#g2-50'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-53'/> +<use x='175.048' y='188.688' xlink:href='#g2-120'/> +</g> +<path d='M135.949 182.176H487.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' fill='#933' clip-path='url(#clip2)'/> +<path d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M141.746 182.176V181.773' fill='#933' clip-path='url(#clip2)'/> +<path d='M141.746 182.176V181.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M139.754 181.773H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M141.746 182.176V182.578' fill='#933' clip-path='url(#clip2)'/> +<path d='M141.746 182.176V182.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M143.738 182.578H139.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M200.414 182.176V181.508' fill='#933' clip-path='url(#clip2)'/> +<path d='M200.414 182.176V181.508' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M198.422 181.508H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M200.414 182.176V182.848' fill='#933' clip-path='url(#clip2)'/> +<path d='M200.414 182.176V182.848' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M202.406 182.848H198.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M259.082 182.176' fill='#933' clip-path='url(#clip2)'/> +<path d='M257.09 182.176H261.074' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M259.082 182.176' fill='#933' clip-path='url(#clip2)'/> +<path d='M257.09 182.176H261.074' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M317.754 182.176V179.695' fill='#933' clip-path='url(#clip2)'/> +<path d='M317.754 182.176V179.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M315.758 179.695H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M317.754 182.176V184.66' fill='#933' clip-path='url(#clip2)'/> +<path d='M317.754 182.176V184.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M319.746 184.66H315.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M376.422 182.176V180.363' fill='#933' clip-path='url(#clip2)'/> +<path d='M376.422 182.176V180.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M374.43 180.363H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M376.422 182.176V183.988' fill='#933' clip-path='url(#clip2)'/> +<path d='M376.422 182.176V183.988' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M378.414 183.988H374.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M435.09 182.176V179.629' fill='#933' clip-path='url(#clip2)'/> +<path d='M435.09 182.176V179.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M433.098 179.629H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M435.09 182.176V184.727' fill='#933' clip-path='url(#clip2)'/> +<path d='M435.09 182.176V184.727' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M437.082 184.727H433.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M145.356 249.281H148.594V182.312H145.356ZM204.028 249.281H207.266V182.648H204.028ZM262.695 249.281H265.934V167.816H262.695ZM321.363 249.281H324.602V183.922H321.363ZM380.031 249.281H383.27V176.605H380.031ZM438.703 249.281H441.942V180.699H438.703Z' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M145.356 249.281H148.594V182.312H145.356ZM204.028 249.281H207.266V182.648H204.028ZM262.695 249.281H265.934V167.816H262.695ZM321.363 249.281H324.602V183.922H321.363ZM380.031 249.281H383.27V176.605H380.031ZM438.703 249.281H441.942V180.699H438.703Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M146.977 182.312V182.043' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M146.977 182.312V182.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M144.984 182.043H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M146.977 182.312V182.578' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M146.977 182.312V182.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M148.968 182.578H144.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M205.645 182.648V182.379' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M205.645 182.648V182.379' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M203.652 182.379H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M205.645 182.648V182.914' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M205.645 182.648V182.914' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M207.636 182.914H203.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M264.313 167.816V163.051' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M264.313 167.816V163.051' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M262.32 163.051H266.304' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M264.313 167.816V172.582' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M264.313 167.816V172.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M266.308 172.582H262.32' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M322.984 183.922V182.176' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M322.984 183.922V182.176' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M320.988 182.176H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M322.984 183.922V185.668' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M322.984 183.922V185.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M324.976 185.668H320.992' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M381.652 176.605V172.18' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M381.652 176.605V172.18' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M379.66 172.179H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M381.652 176.605V181.035' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M381.652 176.605V181.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M383.644 181.035H379.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M440.32 180.699V177.746' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M440.32 180.699V177.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M438.328 177.746H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M440.32 180.699V183.652' fill='#bf8080' clip-path='url(#clip2)'/> +<path d='M440.32 180.699V183.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M442.312 183.652H438.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M150.586 249.281H153.824V181.707H150.586ZM209.258 249.281H212.496V180.969H209.258ZM267.926 249.281H271.164V143.859H267.926ZM326.594 249.281H329.832V81.519H326.594ZM385.262 249.281H388.5V81.519H385.262ZM443.934 249.281H447.172V81.519H443.934Z' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M150.586 249.281H153.824V181.707H150.586ZM209.258 249.281H212.496V180.969H209.258ZM267.926 249.281H271.164V143.859H267.926ZM326.594 249.281H329.832V81.519H326.594ZM385.262 249.281H388.5V81.519H385.262ZM443.934 249.281H447.172V81.519H443.934Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M152.207 181.707V181.172' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M152.207 181.707V181.172' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M150.215 181.171H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M152.207 181.707V182.242' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M152.207 181.707V182.242' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M154.2 182.242H150.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M210.875 180.969V179.359' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M210.875 180.969V179.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M208.883 179.36H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M210.875 180.969V182.578' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M210.875 180.969V182.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M212.868 182.578H208.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M269.543 143.859V132.117' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M269.543 143.859V132.117' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M267.551 132.117H271.535' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M269.543 143.859V155.602' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M269.543 143.859V155.602' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M271.539 155.602H267.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M328.215 81.519' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M326.219 81.52H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M328.215 81.519' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M326.219 81.52H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M386.883 81.519' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M384.891 81.52H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M386.883 81.519' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M384.891 81.52H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M445.551 81.519' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M443.559 81.52H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M445.551 81.519' fill='#8080bf' clip-path='url(#clip2)'/> +<path d='M443.559 81.52H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M155.817 249.281H159.055V176.273H155.817ZM214.488 249.281H217.727V173.988H214.488ZM273.156 249.281H276.395V81.519H273.156ZM331.824 249.281H335.063V81.519H331.824ZM390.492 249.281H393.731V81.519H390.492ZM449.164 249.281H452.402V81.519H449.164Z' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M155.817 249.281H159.055V176.273H155.817ZM214.488 249.281H217.727V173.988H214.488ZM273.156 249.281H276.395V81.519H273.156ZM331.824 249.281H335.063V81.519H331.824ZM390.492 249.281H393.731V81.519H390.492ZM449.164 249.281H452.402V81.519H449.164Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M157.438 176.273V176.137' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M157.438 176.273V176.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M155.445 176.136H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M157.438 176.273V176.406' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M157.438 176.273V176.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M159.43 176.406H155.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M216.106 173.988V172.715' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M216.106 173.988V172.715' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M214.113 172.715H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M216.106 173.988V175.266' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M216.106 173.988V175.266' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M218.098 175.266H214.113' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M274.774 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M272.781 81.52H276.765' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M274.774 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M272.781 81.52H276.765' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M333.445 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M331.449 81.52H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M333.445 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M331.449 81.52H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M392.113 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M390.121 81.52H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M392.113 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M390.121 81.52H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M450.781 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M448.789 81.52H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M450.781 81.519' fill='#ffb733' clip-path='url(#clip2)'/> +<path d='M448.789 81.52H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M161.047 249.281H164.285V157.48H161.047ZM219.719 249.281H222.957V147.215H219.719ZM278.387 249.281H281.625V81.519H278.387ZM337.055 249.281H340.293V81.519H337.055ZM395.723 249.281H398.961V166.406H395.723ZM454.395 249.281H457.633V182.176H454.395Z' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M161.047 249.281H164.285V157.48H161.047ZM219.719 249.281H222.957V147.215H219.719ZM278.387 249.281H281.625V81.519H278.387ZM337.055 249.281H340.293V81.519H337.055ZM395.723 249.281H398.961V166.406H395.723ZM454.395 249.281H457.633V182.176H454.395Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M162.668 157.48V157.012' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M162.668 157.48V157.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M160.676 157.011H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M162.668 157.48V157.953' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M162.668 157.48V157.953' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M164.661 157.953H160.676' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M221.336 147.215V146.812' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M221.336 147.215V146.812' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M219.344 146.812H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M221.336 147.215V147.617' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M221.336 147.215V147.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M223.329 147.617H219.344' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M280.004 81.519' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M278.012 81.52H281.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M280.004 81.519' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M278.012 81.52H281.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M338.676 81.519' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M336.68 81.52H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M338.676 81.519' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M336.68 81.52H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M397.344 166.406V166.273' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M397.344 166.406V166.273' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M395.352 166.274H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M397.344 166.406V166.543' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M397.344 166.406V166.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M399.336 166.543H395.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M456.012 182.176V179.629' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M456.012 182.176V179.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M454.02 179.629H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M456.012 182.176V184.727' fill='#bf80bf' clip-path='url(#clip2)'/> +<path d='M456.012 182.176V184.727' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M458.004 184.727H454.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M166.278 249.281H169.516V167.949H166.278ZM224.949 249.281H228.188V176.137H224.949ZM283.617 249.281H286.856V110.305H283.617ZM342.285 249.281H345.524V157.48H342.285ZM400.953 249.281H404.192V186.473H400.953ZM459.625 249.281H462.863V183.652H459.625Z' fill='#c96' clip-path='url(#clip2)'/> +<path d='M166.278 249.281H169.516V167.949H166.278ZM224.949 249.281H228.188V176.137H224.949ZM283.617 249.281H286.856V110.305H283.617ZM342.285 249.281H345.524V157.48H342.285ZM400.953 249.281H404.192V186.473H400.953ZM459.625 249.281H462.863V183.652H459.625Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M167.899 167.949V167.816' fill='#c96' clip-path='url(#clip2)'/> +<path d='M167.899 167.949V167.816' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M165.906 167.816H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M167.899 167.949V168.086' fill='#c96' clip-path='url(#clip2)'/> +<path d='M167.899 167.949V168.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M169.891 168.086H165.906' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M226.567 176.137V175.199' fill='#c96' clip-path='url(#clip2)'/> +<path d='M226.567 176.137V175.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M224.574 175.199H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M226.567 176.137V177.078' fill='#c96' clip-path='url(#clip2)'/> +<path d='M226.567 176.137V177.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M228.559 177.078H224.574' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M285.234 110.305V105.543' fill='#c96' clip-path='url(#clip2)'/> +<path d='M285.234 110.305V105.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M283.242 105.543H287.226' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M285.234 110.305V115.07' fill='#c96' clip-path='url(#clip2)'/> +<path d='M285.234 110.305V115.07' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M287.23 115.07H283.242' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M343.906 157.48V153.187' fill='#c96' clip-path='url(#clip2)'/> +<path d='M343.906 157.48V153.187' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M341.91 153.187H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M343.906 157.48V161.777' fill='#c96' clip-path='url(#clip2)'/> +<path d='M343.906 157.48V161.777' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M345.898 161.778H341.914' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M402.574 186.473V186.269' fill='#c96' clip-path='url(#clip2)'/> +<path d='M402.574 186.473V186.269' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M400.582 186.27H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M402.574 186.473V186.672' fill='#c96' clip-path='url(#clip2)'/> +<path d='M402.574 186.473V186.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M404.566 186.672H400.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M461.242 183.652' fill='#c96' clip-path='url(#clip2)'/> +<path d='M459.25 183.652H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M461.242 183.652' fill='#c96' clip-path='url(#clip2)'/> +<path d='M459.25 183.652H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M171.508 249.281H174.746V173.789H171.508ZM230.18 249.281H233.414V173.789H230.18ZM288.848 249.281H292.086V81.519H288.848ZM347.516 249.281H350.754V81.519H347.516ZM406.184 249.281H409.422V81.519H406.184ZM464.856 249.281H468.094V81.519H464.856Z' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M171.508 249.281H174.746V173.789H171.508ZM230.18 249.281H233.414V173.789H230.18ZM288.848 249.281H292.086V81.519H288.848ZM347.516 249.281H350.754V81.519H347.516ZM406.184 249.281H409.422V81.519H406.184ZM464.856 249.281H468.094V81.519H464.856Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M173.129 173.789V173.184' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M173.129 173.789V173.184' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M171.137 173.184H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M173.129 173.789V174.394' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M173.129 173.789V174.394' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M175.122 174.395H171.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M231.797 173.789V173.32' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M231.797 173.789V173.32' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M229.805 173.32H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M231.797 173.789V174.258' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M231.797 173.789V174.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M233.79 174.258H229.805' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M290.465 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M288.473 81.52H292.457' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M290.465 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M288.473 81.52H292.457' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M349.137 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M347.141 81.52H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M349.137 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M347.141 81.52H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M407.805 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M405.813 81.52H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M407.805 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M405.813 81.52H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M466.473 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M464.481 81.52H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M466.473 81.519' fill='#80bf80' clip-path='url(#clip2)'/> +<path d='M464.481 81.52H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M176.738 249.281H179.977V144.664H176.738ZM235.41 249.281H238.645V178.016H235.41ZM294.078 249.281H297.317V81.519H294.078ZM352.746 249.281H355.984V81.519H352.746ZM411.414 249.281H414.652V81.519H411.414ZM470.086 249.281H473.324V183.652H470.086Z' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M176.738 249.281H179.977V144.664H176.738ZM235.41 249.281H238.645V178.016H235.41ZM294.078 249.281H297.317V81.519H294.078ZM352.746 249.281H355.984V81.519H352.746ZM411.414 249.281H414.652V81.519H411.414ZM470.086 249.281H473.324V183.652H470.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M178.36 144.664V142.922' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M178.36 144.664V142.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M176.367 142.922H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M178.36 144.664V146.41' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M178.36 144.664V146.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M180.352 146.41H176.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M237.027 178.016V177.344' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M237.027 178.016V177.344' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M235.035 177.343H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M237.027 178.016V178.687' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M237.027 178.016V178.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M239.02 178.688H235.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M295.695 81.519' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M293.703 81.52H297.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M295.695 81.519' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M293.703 81.52H297.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M354.367 81.519' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M352.371 81.52H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M354.367 81.519' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M352.371 81.52H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M413.035 81.519' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M411.043 81.52H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M413.035 81.519' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M411.043 81.52H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M471.703 183.652' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M469.711 183.652H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M471.703 183.652' fill='#bfbf80' clip-path='url(#clip2)'/> +<path d='M469.711 183.652H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M181.969 249.281H185.207V165.199H181.969ZM240.641 249.281H243.875V163.387H240.641ZM299.309 249.281H302.547V81.519H299.309ZM357.977 249.281H361.215V81.519H357.977ZM416.645 249.281H419.883V116.613H416.645ZM475.317 249.281H478.555V81.519H475.317Z' fill='#399' clip-path='url(#clip2)'/> +<path d='M181.969 249.281H185.207V165.199H181.969ZM240.641 249.281H243.875V163.387H240.641ZM299.309 249.281H302.547V81.519H299.309ZM357.977 249.281H361.215V81.519H357.977ZM416.645 249.281H419.883V116.613H416.645ZM475.317 249.281H478.555V81.519H475.317Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M183.59 165.199V164.664' fill='#399' clip-path='url(#clip2)'/> +<path d='M183.59 165.199V164.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M181.598 164.664H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M183.59 165.199V165.734' fill='#399' clip-path='url(#clip2)'/> +<path d='M183.59 165.199V165.734' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M185.582 165.734H181.597' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M242.258 163.387V162.852' fill='#399' clip-path='url(#clip2)'/> +<path d='M242.258 163.387V162.852' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M240.266 162.851H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M242.258 163.387V163.926' fill='#399' clip-path='url(#clip2)'/> +<path d='M242.258 163.387V163.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M244.25 163.926H240.265' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M300.926 81.519' fill='#399' clip-path='url(#clip2)'/> +<path d='M298.933 81.52H302.917' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M300.926 81.519' fill='#399' clip-path='url(#clip2)'/> +<path d='M298.933 81.52H302.917' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M359.598 81.519' fill='#399' clip-path='url(#clip2)'/> +<path d='M357.602 81.52H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M359.598 81.519' fill='#399' clip-path='url(#clip2)'/> +<path d='M357.602 81.52H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M418.266 116.613V116.211' fill='#399' clip-path='url(#clip2)'/> +<path d='M418.266 116.613V116.211' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M416.274 116.211H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M418.266 116.613V117.016' fill='#399' clip-path='url(#clip2)'/> +<path d='M418.266 116.613V117.016' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M420.257 117.016H416.273' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M476.934 81.519' fill='#399' clip-path='url(#clip2)'/> +<path d='M474.942 81.52H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M476.934 81.519' fill='#399' clip-path='url(#clip2)'/> +<path d='M474.942 81.52H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M187.199 249.281H190.438V175.133H187.199ZM245.871 249.281H249.106V171.574H245.871ZM304.539 249.281H307.777V81.519H304.539ZM363.207 249.281H366.445V81.519H363.207ZM421.875 249.281H425.113V170.836H421.875ZM480.547 249.281H483.785V171.707H480.547Z' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M187.199 249.281H190.438V175.133H187.199ZM245.871 249.281H249.106V171.574H245.871ZM304.539 249.281H307.777V81.519H304.539ZM363.207 249.281H366.445V81.519H363.207ZM421.875 249.281H425.113V170.836H421.875ZM480.547 249.281H483.785V171.707H480.547Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M188.82 175.133V174.797' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M188.82 175.133V174.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M186.828 174.797H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M188.82 175.133V175.465' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M188.82 175.133V175.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M190.813 175.464H186.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M247.488 171.574V171.238' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M247.488 171.574V171.238' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M245.496 171.239H249.48' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M247.488 171.574V171.91' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M247.488 171.574V171.91' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M249.481 171.91H245.496' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M306.156 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M304.164 81.52H308.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M306.156 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M304.164 81.52H308.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M364.828 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M362.832 81.52H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M364.828 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M362.832 81.52H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M423.496 170.836V169.629' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M423.496 170.836V169.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M421.504 169.629H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M423.496 170.836V172.043' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M423.496 170.836V172.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M425.488 172.043H421.504' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M482.164 171.707' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M480.172 171.707H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M482.164 171.707' fill='#d9b3b3' clip-path='url(#clip2)'/> +<path d='M480.172 171.707H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M415.914 310.336H487.762V276.324H415.914Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<g transform='matrix(1 0 0 1 250.949 118.327)'> +<use x='168.285' y='164.777' xlink:href='#g2-97'/> +<use x='170.827' y='164.777' xlink:href='#g2-109'/> +<use x='175.03' y='164.777' xlink:href='#g2-100'/> +<use x='177.763' y='164.777' xlink:href='#g2-53'/> +<use x='180.41' y='164.777' xlink:href='#g2-57'/> +<use x='183.056' y='164.777' xlink:href='#g2-53'/> +<use x='185.702' y='164.777' xlink:href='#g2-48'/> +<use x='188.349' y='164.777' xlink:href='#g2-120'/> +<use x='190.788' y='164.777' xlink:href='#g2-44'/> +<use x='194.022' y='164.777' xlink:href='#g2-51'/> +<use x='196.668' y='164.777' xlink:href='#g2-50'/> +<use x='199.315' y='164.777' xlink:href='#g2-71'/> +<use x='202.843' y='164.777' xlink:href='#g2-98'/> +<use x='207.34' y='164.777' xlink:href='#g2-64'/> +<use x='210.869' y='164.777' xlink:href='#g2-51'/> +<use x='213.515' y='164.777' xlink:href='#g2-54'/> +<use x='216.162' y='164.777' xlink:href='#g2-48'/> +<use x='218.808' y='164.777' xlink:href='#g2-48'/> +<use x='221.454' y='164.777' xlink:href='#g2-77'/> +<use x='226.072' y='164.777' xlink:href='#g2-104'/> +<use x='228.805' y='164.777' xlink:href='#g2-122'/> +<use x='168.285' y='170.755' xlink:href='#g2-49'/> +<use x='170.931' y='170.755' xlink:href='#g2-54'/> +<use x='173.578' y='170.755' xlink:href='#g2-45'/> +<use x='175.342' y='170.755' xlink:href='#g2-99'/> +<use x='177.694' y='170.755' xlink:href='#g2-111'/> +<use x='180.193' y='170.755' xlink:href='#g2-114'/> +<use x='182.001' y='170.755' xlink:href='#g2-101'/> +<use x='186.118' y='170.755' xlink:href='#g2-65'/> +<use x='189.646' y='170.755' xlink:href='#g2-77'/> +<use x='194.264' y='170.755' xlink:href='#g2-68'/> +<use x='199.851' y='170.755' xlink:href='#g2-53'/> +<use x='202.497' y='170.755' xlink:href='#g2-57'/> +<use x='205.144' y='170.755' xlink:href='#g2-53'/> +<use x='207.79' y='170.755' xlink:href='#g2-48'/> +<use x='210.436' y='170.755' xlink:href='#g2-120'/> +<use x='214.639' y='170.755' xlink:href='#g2-64'/> +<use x='218.168' y='170.755' xlink:href='#g2-51'/> +<use x='220.814' y='170.755' xlink:href='#g2-46'/> +<use x='222.285' y='170.755' xlink:href='#g2-52'/> +<use x='224.931' y='170.755' xlink:href='#g2-71'/> +<use x='228.459' y='170.755' xlink:href='#g2-104'/> +<use x='231.192' y='170.755' xlink:href='#g2-122'/> +<use x='168.285' y='176.733' xlink:href='#g2-85'/> +<use x='171.917' y='176.733' xlink:href='#g2-98'/> +<use x='174.65' y='176.733' xlink:href='#g2-117'/> +<use x='177.383' y='176.733' xlink:href='#g2-110'/> +<use x='180.116' y='176.733' xlink:href='#g2-116'/> +<use x='182.027' y='176.733' xlink:href='#g2-117'/> +<use x='186.524' y='176.733' xlink:href='#g2-50'/> +<use x='189.17' y='176.733' xlink:href='#g2-48'/> +<use x='191.817' y='176.733' xlink:href='#g2-46'/> +<use x='193.287' y='176.733' xlink:href='#g2-48'/> +<use x='195.933' y='176.733' xlink:href='#g2-52'/> +<use x='198.58' y='176.733' xlink:href='#g2-44'/> +<use x='201.814' y='176.733' xlink:href='#g2-71'/> +<use x='205.343' y='176.733' xlink:href='#g2-67'/> +<use x='208.724' y='176.733' xlink:href='#g2-67'/> +<use x='213.87' y='176.733' xlink:href='#g2-57'/> +<use x='216.516' y='176.733' xlink:href='#g2-46'/> +<use x='217.986' y='176.733' xlink:href='#g2-51'/> +<use x='220.633' y='176.733' xlink:href='#g2-46'/> +<use x='222.103' y='176.733' xlink:href='#g2-48'/> +<use x='168.285' y='182.71' xlink:href='#g2-51'/> +<use x='170.931' y='182.71' xlink:href='#g2-50'/> +<use x='175.342' y='182.71' xlink:href='#g2-108'/> +<use x='176.604' y='182.71' xlink:href='#g2-111'/> +<use x='179.251' y='182.71' xlink:href='#g2-103'/> +<use x='181.897' y='182.71' xlink:href='#g2-105'/> +<use x='183.16' y='182.71' xlink:href='#g2-99'/> +<use x='185.512' y='182.71' xlink:href='#g2-97'/> +<use x='188.055' y='182.71' xlink:href='#g2-108'/> +<use x='191.082' y='182.71' xlink:href='#g2-99'/> +<use x='193.434' y='182.71' xlink:href='#g2-111'/> +<use x='195.933' y='182.71' xlink:href='#g2-114'/> +<use x='197.741' y='182.71' xlink:href='#g2-101'/> +<use x='200.093' y='182.71' xlink:href='#g2-115'/> +<use x='168.285' y='188.688' xlink:href='#g2-50'/> +<use x='170.931' y='188.688' xlink:href='#g2-48'/> +<use x='173.578' y='188.688' xlink:href='#g2-50'/> +<use x='176.224' y='188.688' xlink:href='#g2-49'/> +<use x='178.87' y='188.688' xlink:href='#g2-45'/> +<use x='180.635' y='188.688' xlink:href='#g2-48'/> +<use x='183.281' y='188.688' xlink:href='#g2-49'/> +<use x='185.927' y='188.688' xlink:href='#g2-45'/> +<use x='187.692' y='188.688' xlink:href='#g2-51'/> +<use x='190.338' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -45.308 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 13.361 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 72.03 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 130.699 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 189.368 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 248.037 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -40.078 344.392)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 18.591 344.728)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-57'/> +<use x='175.048' y='188.688' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 77.26 329.897)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-50'/> +<use x='175.048' y='188.688' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 135.929 346.003)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-57'/> +<use x='175.048' y='188.688' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 194.598 338.688)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 253.267 342.782)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -34.847 343.788)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 23.822 343.05)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 82.491 305.94)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-53'/> +<use x='175.048' y='188.688' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 141.16 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-53'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-52'/> +<use x='183.321' y='188.688' xlink:href='#g2-53'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 199.829 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-54'/> +<use x='176.558' y='188.688' xlink:href='#g2-49'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-49'/> +<use x='183.321' y='188.688' xlink:href='#g2-53'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 258.498 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-50'/> +<use x='176.558' y='188.688' xlink:href='#g2-50'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-52'/> +<use x='183.321' y='188.688' xlink:href='#g2-57'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -29.617 338.353)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 29.052 336.071)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 87.721 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-50'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-55'/> +<use x='180.675' y='188.688' xlink:href='#g2-49'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 146.39 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-50'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-53'/> +<use x='180.675' y='188.688' xlink:href='#g2-48'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 205.059 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-52'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-48'/> +<use x='180.675' y='188.688' xlink:href='#g2-56'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 263.728 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-50'/> +<use x='176.558' y='188.688' xlink:href='#g2-50'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-57'/> +<use x='183.321' y='188.688' xlink:href='#g2-56'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -24.386 319.563)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-51'/> +<use x='175.048' y='188.688' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 34.283 309.296)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-53'/> +<use x='175.048' y='188.688' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 92.952 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-56'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-57'/> +<use x='180.675' y='188.688' xlink:href='#g2-54'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 151.621 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-51'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-51'/> +<use x='180.675' y='188.688' xlink:href='#g2-55'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 210.29 328.488)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-50'/> +<use x='175.048' y='188.688' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 268.959 344.258)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -19.156 330.031)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-50'/> +<use x='175.048' y='188.688' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 39.513 338.218)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 98.182 272.387)'> +<use x='168.285' y='188.688' xlink:href='#g2-50'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 156.851 319.563)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-51'/> +<use x='175.048' y='188.688' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 215.52 348.553)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-57'/> +<use x='175.048' y='188.688' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 274.189 345.734)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-57'/> +<use x='175.048' y='188.688' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 -13.925 335.87)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 44.744 335.87)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 103.413 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-50'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-51'/> +<use x='183.321' y='188.688' xlink:href='#g2-54'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 162.082 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-50'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-57'/> +<use x='183.321' y='188.688' xlink:href='#g2-51'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 220.751 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-48'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-52'/> +<use x='183.321' y='188.688' xlink:href='#g2-50'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 279.42 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-49'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-49'/> +<use x='183.321' y='188.688' xlink:href='#g2-51'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -8.695 306.746)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-53'/> +<use x='175.048' y='188.688' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 49.974 340.097)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-48'/> +<use x='175.048' y='188.688' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 108.643 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-54'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-55'/> +<use x='180.675' y='188.688' xlink:href='#g2-57'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 167.312 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-49'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-49'/> +<use x='183.321' y='188.688' xlink:href='#g2-52'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 225.981 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-56'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-52'/> +<use x='180.675' y='188.688' xlink:href='#g2-50'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 284.65 345.734)'> +<use x='168.285' y='188.688' xlink:href='#g2-48'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-57'/> +<use x='175.048' y='188.688' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 -3.465 327.28)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-50'/> +<use x='175.048' y='188.688' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 55.204 325.468)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-50'/> +<use x='175.048' y='188.688' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 113.873 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-49'/> +<use x='176.558' y='188.688' xlink:href='#g2-56'/> +<use x='179.205' y='188.688' xlink:href='#g2-46'/> +<use x='180.675' y='188.688' xlink:href='#g2-52'/> +<use x='183.321' y='188.688' xlink:href='#g2-51'/> +<use x='185.968' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 172.542 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-53'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-55'/> +<use x='180.675' y='188.688' xlink:href='#g2-56'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 231.211 278.695)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-57'/> +<use x='175.048' y='188.688' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 289.88 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-52'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-56'/> +<use x='180.675' y='188.688' xlink:href='#g2-52'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 1.766 337.212)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 60.435 333.655)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 119.104 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-51'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-53'/> +<use x='180.675' y='188.688' xlink:href='#g2-55'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 177.773 243.599)'> +<use x='163.396' y='188.688' xlink:href='#g4-1'/> +<use x='166.901' y='188.688' xlink:href='#g4-1'/> +<use x='170.407' y='188.688' xlink:href='#g4-1'/> +<use x='173.912' y='188.688' xlink:href='#g2-50'/> +<use x='176.558' y='188.688' xlink:href='#g2-46'/> +<use x='178.029' y='188.688' xlink:href='#g2-53'/> +<use x='180.675' y='188.688' xlink:href='#g2-53'/> +<use x='183.321' y='188.688' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 236.442 332.917)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 295.111 333.789)'> +<use x='168.285' y='188.688' xlink:href='#g2-49'/> +<use x='170.931' y='188.688' xlink:href='#g2-46'/> +<use x='172.401' y='188.688' xlink:href='#g2-49'/> +<use x='175.048' y='188.688' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -75.53 388.945)'> +<use x='168.285' y='188.688' xlink:href='#g1-82'/> +<use x='174.255' y='188.688' xlink:href='#g1-101'/> +<use x='178.351' y='188.688' xlink:href='#g1-108'/> +<use x='180.551' y='188.688' xlink:href='#g1-97'/> +<use x='184.979' y='188.688' xlink:href='#g1-116'/> +<use x='188.307' y='188.688' xlink:href='#g1-105'/> +<use x='190.507' y='188.688' xlink:href='#g1-118'/> +<use x='194.755' y='188.688' xlink:href='#g1-101'/> +<use x='201.922' y='188.688' xlink:href='#g1-116'/> +<use x='205.25' y='188.688' xlink:href='#g1-105'/> +<use x='207.45' y='188.688' xlink:href='#g1-109'/> +<use x='214.77' y='188.688' xlink:href='#g1-101'/> +<use x='221.937' y='188.688' xlink:href='#g3-40'/> +<use x='225.231' y='188.688' xlink:href='#g3-108'/> +<use x='227.251' y='188.688' xlink:href='#g3-111'/> +<use x='231.25' y='188.688' xlink:href='#g3-119'/> +<use x='236.799' y='188.688' xlink:href='#g3-101'/> +<use x='240.562' y='188.688' xlink:href='#g3-114'/> +<use x='246.277' y='188.688' xlink:href='#g3-105'/> +<use x='248.297' y='188.688' xlink:href='#g3-115'/> +<use x='254.366' y='188.688' xlink:href='#g3-98'/> +<use x='258.974' y='188.688' xlink:href='#g3-101'/> +<use x='262.738' y='188.688' xlink:href='#g3-116'/> +<use x='265.796' y='188.688' xlink:href='#g3-116'/> +<use x='268.854' y='188.688' xlink:href='#g3-101'/> +<use x='272.618' y='188.688' xlink:href='#g3-114'/> +<use x='275.51' y='188.688' xlink:href='#g3-41'/> +</g> +<path d='M136.149 309.68H346.746V279.68H136.149Z' fill='#fff'/> +<path d='M136.149 309.68H346.746V279.68H136.149Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#933'/> +<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.354 114.479)'> +<use x='191.843' y='175.681' xlink:href='#g3-120'/> +<use x='195.745' y='175.681' xlink:href='#g3-109'/> +<use x='202.47' y='175.681' xlink:href='#g3-105'/> +<use x='204.49' y='175.681' xlink:href='#g3-58'/> +<use x='206.843' y='175.681' xlink:href='#g0-57'/> +<use x='210.548' y='175.681' xlink:href='#g0-50'/> +</g> +<path d='M177.086 290.168H180.074V282.199H177.086ZM183.063 290.168H186.055V284.191H183.063Z' fill='#bf8080'/> +<path d='M177.086 290.168H180.074V282.199H177.086ZM183.063 290.168H186.055V284.191H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -38.403 114.479)'> +<use x='233.123' y='175.681' xlink:href='#g3-109'/> +<use x='239.848' y='175.681' xlink:href='#g3-105'/> +<use x='241.869' y='175.681' xlink:href='#g3-58'/> +<use x='244.221' y='175.681' xlink:href='#g0-57'/> +<use x='247.926' y='175.681' xlink:href='#g0-50'/> +</g> +<path d='M221.895 290.168H224.883V282.199H221.895ZM227.875 290.168H230.863V284.191H227.875Z' fill='#8080bf'/> +<path d='M221.895 290.168H224.883V282.199H221.895ZM227.875 290.168H230.863V284.191H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.441 114.036)'> +<use x='277.134' y='175.681' xlink:href='#g3-116'/> +<use x='280.192' y='175.681' xlink:href='#g3-99'/> +<use x='283.956' y='175.681' xlink:href='#g3-58'/> +<use x='286.308' y='175.681' xlink:href='#g0-54'/> +<use x='290.013' y='175.681' xlink:href='#g0-49'/> +</g> +<path d='M265.109 290.168H268.098V282.199H265.109ZM271.086 290.168H274.074V284.191H271.086Z' fill='#ffb733'/> +<path d='M265.109 290.168H268.098V282.199H265.109ZM271.086 290.168H274.074V284.191H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.04 114.479)'> +<use x='319.615' y='175.681' xlink:href='#g3-106'/> +<use x='321.871' y='175.681' xlink:href='#g3-101'/> +<use x='325.634' y='175.681' xlink:href='#g3-58'/> +<use x='327.987' y='175.681' xlink:href='#g0-53'/> +<use x='331.691' y='175.681' xlink:href='#g0-56'/> +</g> +<path d='M306.859 290.168H309.848V282.199H306.859ZM312.836 290.168H315.824V284.191H312.836Z' fill='#bf80bf'/> +<path d='M306.859 290.168H309.848V282.199H306.859ZM312.836 290.168H315.824V284.191H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -39.932 114.515)'> +<use x='359.038' y='175.681' xlink:href='#g3-116'/> +<use x='362.096' y='175.681' xlink:href='#g3-98'/> +<use x='366.469' y='175.681' xlink:href='#g3-98'/> +<use x='370.842' y='175.681' xlink:href='#g3-58'/> +<use x='373.194' y='175.681' xlink:href='#g0-52'/> +<use x='376.899' y='175.681' xlink:href='#g0-54'/> +</g> +<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' fill='#c96'/> +<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.662 114.036)'> +<use x='191.843' y='188.688' xlink:href='#g3-114'/> +<use x='194.735' y='188.688' xlink:href='#g3-112'/> +<use x='199.108' y='188.688' xlink:href='#g3-58'/> +<use x='201.46' y='188.688' xlink:href='#g0-55'/> +<use x='205.165' y='188.688' xlink:href='#g0-56'/> +</g> +<path d='M177.086 303.176H180.074V295.207H177.086ZM183.063 303.176H186.055V297.199H183.063Z' fill='#80bf80'/> +<path d='M177.086 303.176H180.074V295.207H177.086ZM183.063 303.176H186.055V297.199H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.882 114.515)'> +<use x='233.123' y='188.688' xlink:href='#g3-104'/> +<use x='237.496' y='188.688' xlink:href='#g3-111'/> +<use x='241.73' y='188.688' xlink:href='#g3-97'/> +<use x='245.563' y='188.688' xlink:href='#g3-114'/> +<use x='248.455' y='188.688' xlink:href='#g3-100'/> +<use x='252.828' y='188.688' xlink:href='#g3-58'/> +<use x='255.18' y='188.688' xlink:href='#g0-52'/> +<use x='258.885' y='188.688' xlink:href='#g0-49'/> +</g> +<path d='M221.895 303.176H224.883V295.207H221.895ZM227.875 303.176H230.863V297.199H227.875Z' fill='#bfbf80'/> +<path d='M221.895 303.176H224.883V295.207H221.895ZM227.875 303.176H230.863V297.199H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.084 114.515)'> +<use x='277.134' y='188.688' xlink:href='#g3-109'/> +<use x='283.859' y='188.688' xlink:href='#g3-101'/> +<use x='287.622' y='188.688' xlink:href='#g3-115'/> +<use x='290.869' y='188.688' xlink:href='#g3-104'/> +<use x='295.241' y='188.688' xlink:href='#g3-58'/> +<use x='297.593' y='188.688' xlink:href='#g0-52'/> +<use x='301.298' y='188.688' xlink:href='#g0-49'/> +</g> +<path d='M265.109 303.176H268.098V295.207H265.109ZM271.086 303.176H274.074V297.199H271.086Z' fill='#399'/> +<path d='M265.109 303.176H268.098V295.207H265.109ZM271.086 303.176H274.074V297.199H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -42.353 114.515)'> +<use x='319.615' y='188.688' xlink:href='#g3-103'/> +<use x='323.849' y='188.688' xlink:href='#g3-108'/> +<use x='325.869' y='188.688' xlink:href='#g3-105'/> +<use x='327.89' y='188.688' xlink:href='#g3-98'/> +<use x='332.498' y='188.688' xlink:href='#g3-99'/> +<use x='336.261' y='188.688' xlink:href='#g3-58'/> +<use x='338.614' y='188.688' xlink:href='#g0-51'/> +<use x='342.318' y='188.688' xlink:href='#g0-57'/> +</g> +<path d='M306.859 303.176H309.848V295.207H306.859ZM312.836 303.176H315.824V297.199H312.836Z' fill='#d9b3b3'/> +<path d='M306.859 303.176H309.848V295.207H306.859ZM312.836 303.176H315.824V297.199H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.026 114.479)'> +<use x='359.038' y='188.688' xlink:href='#g3-115'/> +<use x='362.285' y='188.688' xlink:href='#g3-109'/> +<use x='369.009' y='188.688' xlink:href='#g3-105'/> +<use x='371.03' y='188.688' xlink:href='#g3-58'/> +<use x='373.382' y='188.688' xlink:href='#g0-54'/> +<use x='377.087' y='188.688' xlink:href='#g0-50'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg new file mode 100644 index 0000000..bc91c21 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg @@ -0,0 +1,955 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.629pt' height='170.383pt' viewBox='52.934 54.994 381.629 170.383'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip3'> +<path d='M82.148 209.23H434.164V83.984H82.148Z'/> +</clipPath> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +</defs> +<g id='page3'> +<path d='M140.82 218.086V209.23M199.488 218.086V209.23M258.156 218.086V209.23M316.824 218.086V209.23M375.496 218.086V209.23M140.82 75.129V83.984M199.488 75.129V83.984M258.156 75.129V83.984M316.824 75.129V83.984M375.496 75.129V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M111.484 213.484V209.23M170.152 213.484V209.23M228.824 213.484V209.23M287.492 213.484V209.23M346.16 213.484V209.23M404.828 213.484V209.23M111.484 79.734V83.984M170.152 79.734V83.984M228.824 79.734V83.984M287.492 79.734V83.984M346.16 79.734V83.984M404.828 79.734V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 209.23H86.402M82.148 177.918H86.402M82.148 146.609H86.402M82.148 115.297H86.402M82.148 83.984H86.402M434.164 209.23H429.91M434.164 177.918H429.91M434.164 146.609H429.91M434.164 115.297H429.91M434.164 83.984H429.91' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 209.23V83.984H434.164V209.23H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -11.54 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-99'/> +<use x='118.25' y='188.674' xlink:href='#g3-102'/> +<use x='120.838' y='188.674' xlink:href='#g3-114'/> +<use x='123.73' y='188.674' xlink:href='#g3-97'/> +<use x='127.798' y='188.674' xlink:href='#g3-99'/> +</g> +<g transform='matrix(1 0 0 1 45.565 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-108'/> +<use x='116.507' y='188.674' xlink:href='#g3-101'/> +<use x='120.271' y='188.674' xlink:href='#g3-97'/> +<use x='124.339' y='188.674' xlink:href='#g3-110'/> +<use x='128.711' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 106.188 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-114'/> +<use x='117.379' y='188.674' xlink:href='#g3-101'/> +<use x='121.142' y='188.674' xlink:href='#g3-100'/> +<use x='125.515' y='188.674' xlink:href='#g3-105'/> +<use x='127.535' y='188.674' xlink:href='#g3-115'/> +</g> +<g transform='matrix(1 0 0 1 159.716 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-108'/> +<use x='116.507' y='188.674' xlink:href='#g3-97'/> +<use x='120.34' y='188.674' xlink:href='#g3-114'/> +<use x='123.232' y='188.674' xlink:href='#g3-115'/> +<use x='126.478' y='188.674' xlink:href='#g3-111'/> +<use x='130.712' y='188.674' xlink:href='#g3-110'/> +<use x='135.085' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 215.596 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-109'/> +<use x='121.211' y='188.674' xlink:href='#g3-115'/> +<use x='124.458' y='188.674' xlink:href='#g3-116'/> +<use x='127.516' y='188.674' xlink:href='#g3-114'/> +<use x='130.408' y='188.674' xlink:href='#g3-101'/> +<use x='134.171' y='188.674' xlink:href='#g3-115'/> +<use x='137.418' y='188.674' xlink:href='#g3-115'/> +<use x='140.664' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 277.158 34.954)'> +<use x='114.487' y='188.674' xlink:href='#g3-114'/> +<use x='117.379' y='188.674' xlink:href='#g3-112'/> +<use x='121.751' y='188.674' xlink:href='#g3-116'/> +<use x='124.809' y='188.674' xlink:href='#g3-101'/> +<use x='128.573' y='188.674' xlink:href='#g3-115'/> +<use x='131.819' y='188.674' xlink:href='#g3-116'/> +<use x='134.877' y='188.674' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 22.192)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -9.12)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -40.431)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.743)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -103.054)'> +<use x='114.487' y='188.674' xlink:href='#g2-50'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-120'/> +</g> +<path d='M82.148 146.609H434.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' fill='#933' clip-path='url(#clip3)'/> +<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M87.949 146.609' fill='#933' clip-path='url(#clip3)'/> +<path d='M85.953 146.609H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M87.949 146.609' fill='#933' clip-path='url(#clip3)'/> +<path d='M85.953 146.609H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M146.617 146.609V146.105' fill='#933' clip-path='url(#clip3)'/> +<path d='M146.617 146.609V146.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M144.625 146.105H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M146.617 146.609V147.109' fill='#933' clip-path='url(#clip3)'/> +<path d='M146.617 146.609V147.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M148.61 147.109H144.625' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M205.285 146.609V146.359' fill='#933' clip-path='url(#clip3)'/> +<path d='M205.285 146.609V146.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M203.293 146.36H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M205.285 146.609V146.859' fill='#933' clip-path='url(#clip3)'/> +<path d='M205.285 146.609V146.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M207.278 146.86H203.293' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M263.953 146.609V145.105' fill='#933' clip-path='url(#clip3)'/> +<path d='M263.953 146.609V145.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M261.961 145.105H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M263.953 146.609V148.109' fill='#933' clip-path='url(#clip3)'/> +<path d='M263.953 146.609V148.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M265.949 148.109H261.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M322.625 146.609V144.73' fill='#933' clip-path='url(#clip3)'/> +<path d='M322.625 146.609V144.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M320.629 144.73H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M322.625 146.609V148.488' fill='#933' clip-path='url(#clip3)'/> +<path d='M322.625 146.609V148.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M324.617 148.488H320.633' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M381.293 146.609V140.785' fill='#933' clip-path='url(#clip3)'/> +<path d='M381.293 146.609V140.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M379.301 140.785H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M381.293 146.609V152.434' fill='#933' clip-path='url(#clip3)'/> +<path d='M381.293 146.609V152.434' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M383.285 152.434H379.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M91.559 209.23H94.797V146.23H91.559ZM150.227 209.23H153.465V146.547H150.227ZM208.899 209.23H212.133V145.293H208.899ZM267.567 209.23H270.805V152.117H267.567ZM326.234 209.23H329.473V140.973H326.234ZM384.902 209.23H388.141V154.562H384.902Z' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M91.559 209.23H94.797V146.23H91.559ZM150.227 209.23H153.465V146.547H150.227ZM208.899 209.23H212.133V145.293H208.899ZM267.567 209.23H270.805V152.117H267.567ZM326.234 209.23H329.473V140.973H326.234ZM384.902 209.23H388.141V154.562H384.902Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M93.18 146.23V146.168' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M93.18 146.23V146.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M91.184 146.168H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M93.18 146.23V146.297' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M93.18 146.23V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M95.172 146.297H91.187' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M151.848 146.547V146.297' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M151.848 146.547V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M149.855 146.297H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M151.848 146.547V146.797' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M151.848 146.547V146.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M153.84 146.797H149.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M210.516 145.293V145.105' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M210.516 145.293V145.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M208.523 145.105H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M210.516 145.293V145.48' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M210.516 145.293V145.48' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M212.508 145.481H208.523' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M269.184 152.117V151.555' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M269.184 152.117V151.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M267.191 151.554H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M269.184 152.117V152.684' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M269.184 152.117V152.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M271.179 152.684H267.191' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M327.856 140.973V137.402' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M327.856 140.973V137.402' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M325.859 137.403H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M327.856 140.973V144.543' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M327.856 140.973V144.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M329.847 144.543H325.863' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M386.524 154.562V147.734' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M386.524 154.562V147.734' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M384.531 147.734H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M386.524 154.562V161.387' fill='#bf8080' clip-path='url(#clip3)'/> +<path d='M386.524 154.562V161.387' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M388.515 161.387H384.531' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M96.789 209.23H100.027V145.293H96.789ZM155.457 209.23H158.695V143.101H155.457ZM214.129 209.23H217.363V144.668H214.129ZM272.797 209.23H276.035V141.973H272.797ZM331.465 209.23H334.703V143.101H331.465ZM390.133 209.23H393.371V83.984H390.133Z' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M96.789 209.23H100.027V145.293H96.789ZM155.457 209.23H158.695V143.101H155.457ZM214.129 209.23H217.363V144.668H214.129ZM272.797 209.23H276.035V141.973H272.797ZM331.465 209.23H334.703V143.101H331.465ZM390.133 209.23H393.371V83.984H390.133Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M98.41 145.293V145.23' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M98.41 145.293V145.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M96.414 145.23H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M98.41 145.293V145.355' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M98.41 145.293V145.355' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M100.402 145.356H96.418' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M157.078 143.101V142.601' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M157.078 143.101V142.601' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M155.086 142.601H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M157.078 143.101V143.601' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M157.078 143.101V143.601' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M159.071 143.601H155.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M215.746 144.668V144.543' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M215.746 144.668V144.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M213.754 144.543H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M215.746 144.668V144.793' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M215.746 144.668V144.793' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M217.739 144.793H213.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M274.414 141.973V141.535' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M274.414 141.973V141.535' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M272.422 141.536H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M274.414 141.973V142.414' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M274.414 141.973V142.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M276.41 142.414H272.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M333.086 143.101V141.66' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M333.086 143.101V141.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M331.09 141.66H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M333.086 143.101V144.543' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M333.086 143.101V144.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M335.078 144.543H331.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip3)'/> +<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M102.02 209.23H105.258V143.289H102.02ZM160.688 209.23H163.926V146.484H160.688ZM219.359 209.23H222.594V134.711H219.359ZM278.027 209.23H281.266V139.531H278.027ZM336.695 209.23H339.934V83.984H336.695ZM395.363 209.23H398.602V128.008H395.363Z' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M102.02 209.23H105.258V143.289H102.02ZM160.688 209.23H163.926V146.484H160.688ZM219.359 209.23H222.594V134.711H219.359ZM278.027 209.23H281.266V139.531H278.027ZM336.695 209.23H339.934V83.984H336.695ZM395.363 209.23H398.602V128.008H395.363Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M103.641 143.289' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M101.644 143.289H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M103.641 143.289' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M101.644 143.289H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M162.309 146.484V146.168' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M162.309 146.484V146.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M160.316 146.168H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M162.309 146.484V146.797' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M162.309 146.484V146.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M164.301 146.797H160.316' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M220.977 134.711V134.523' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M220.977 134.711V134.523' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M218.984 134.524H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M220.977 134.711V134.898' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M220.977 134.711V134.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M222.969 134.899H218.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M279.645 139.531V139.469' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M279.645 139.531V139.469' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M277.652 139.469H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M279.645 139.531V139.594' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M279.645 139.531V139.594' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M281.64 139.593H277.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M338.317 83.984' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M336.32 83.984H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M338.317 83.984' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M336.32 83.984H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M396.984 128.008V115.859' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M396.984 128.008V115.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M394.992 115.859H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M396.984 128.008V140.156' fill='#ffb733' clip-path='url(#clip3)'/> +<path d='M396.984 128.008V140.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M398.976 140.156H394.992' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M107.25 209.23H110.488V127.82H107.25ZM165.918 209.23H169.156V145.105H165.918ZM224.59 209.23H227.824V112.98H224.59ZM283.258 209.23H286.496V115.109H283.258ZM341.926 209.23H345.164V103.961H341.926ZM400.594 209.23H403.832V136.715H400.594Z' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M107.25 209.23H110.488V127.82H107.25ZM165.918 209.23H169.156V145.105H165.918ZM224.59 209.23H227.824V112.98H224.59ZM283.258 209.23H286.496V115.109H283.258ZM341.926 209.23H345.164V103.961H341.926ZM400.594 209.23H403.832V136.715H400.594Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M108.871 127.82V127.758' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M108.871 127.82V127.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M106.875 127.758H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M108.871 127.82V127.883' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M108.871 127.82V127.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M110.864 127.883H106.879' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M167.539 145.105V144.668' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M167.539 145.105V144.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M165.547 144.668H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M167.539 145.105V145.543' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M167.539 145.105V145.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M169.532 145.543H165.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M226.207 112.98V112.73' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M226.207 112.98V112.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M224.215 112.73H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M226.207 112.98V113.23' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M226.207 112.98V113.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M228.2 113.23H224.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M284.875 115.109V113.605' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M284.875 115.109V113.605' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M282.883 113.606H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M284.875 115.109V116.613' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M284.875 115.109V116.613' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M286.868 116.614H282.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M343.547 103.961V102.961' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M343.547 103.961V102.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M341.551 102.961H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M343.547 103.961V104.965' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M343.547 103.961V104.965' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M345.539 104.965H341.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M402.215 136.715V130.137' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M402.215 136.715V130.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M400.223 130.136H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M402.215 136.715V143.289' fill='#bf80bf' clip-path='url(#clip3)'/> +<path d='M402.215 136.715V143.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M404.207 143.289H400.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M112.481 209.23H115.719V144.918H112.481ZM171.149 209.23H174.387V147.984H171.149ZM229.82 209.23H233.055V134.461H229.82ZM288.488 209.23H291.727V147.734H288.488ZM347.156 209.23H350.395V83.984H347.156ZM405.824 209.23H409.063V123.562H405.824Z' fill='#c96' clip-path='url(#clip3)'/> +<path d='M112.481 209.23H115.719V144.918H112.481ZM171.149 209.23H174.387V147.984H171.149ZM229.82 209.23H233.055V134.461H229.82ZM288.488 209.23H291.727V147.734H288.488ZM347.156 209.23H350.395V83.984H347.156ZM405.824 209.23H409.063V123.562H405.824Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M114.098 144.918V144.855' fill='#c96' clip-path='url(#clip3)'/> +<path d='M114.098 144.918V144.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M112.105 144.856H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M114.098 144.918V144.98' fill='#c96' clip-path='url(#clip3)'/> +<path d='M114.098 144.918V144.98' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M116.094 144.981H112.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M172.77 147.984V147.359' fill='#c96' clip-path='url(#clip3)'/> +<path d='M172.77 147.984V147.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M170.777 147.36H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M172.77 147.984V148.613' fill='#c96' clip-path='url(#clip3)'/> +<path d='M172.77 147.984V148.613' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M174.762 148.613H170.777' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M231.438 134.461V134.336' fill='#c96' clip-path='url(#clip3)'/> +<path d='M231.438 134.461V134.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M229.445 134.336H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M231.438 134.461V134.586' fill='#c96' clip-path='url(#clip3)'/> +<path d='M231.438 134.461V134.586' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M233.43 134.586H229.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M290.106 147.734V146.297' fill='#c96' clip-path='url(#clip3)'/> +<path d='M290.106 147.734V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M288.113 146.297H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M290.106 147.734V149.176' fill='#c96' clip-path='url(#clip3)'/> +<path d='M290.106 147.734V149.176' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M292.098 149.176H288.113' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M348.777 83.984' fill='#c96' clip-path='url(#clip3)'/> +<path d='M346.781 83.984H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M348.777 83.984' fill='#c96' clip-path='url(#clip3)'/> +<path d='M346.781 83.984H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M407.445 123.562V105.965' fill='#c96' clip-path='url(#clip3)'/> +<path d='M407.445 123.562V105.965' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M405.453 105.965H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M407.445 123.562V141.16' fill='#c96' clip-path='url(#clip3)'/> +<path d='M407.445 123.562V141.16' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M409.437 141.16H405.453' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M117.711 209.23H120.949V143.601H117.711ZM176.379 209.23H179.617V139.781H176.379ZM235.051 209.23H238.285V126.57H235.051ZM293.719 209.23H296.957V83.984H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M117.711 209.23H120.949V143.601H117.711ZM176.379 209.23H179.617V139.781H176.379ZM235.051 209.23H238.285V126.57H235.051ZM293.719 209.23H296.957V83.984H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M119.328 143.601V143.539' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M119.328 143.601V143.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M117.336 143.539H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M119.328 143.601V143.664' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M119.328 143.601V143.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M121.325 143.664H117.34' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M178 139.781V139.469' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M178 139.781V139.469' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M176.008 139.469H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M178 139.781V140.094' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M178 139.781V140.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M179.993 140.093H176.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M236.668 126.57V126.445' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M236.668 126.57V126.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M234.676 126.446H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M236.668 126.57V126.695' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M236.668 126.57V126.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M238.66 126.695H234.675' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M295.336 83.984' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M293.344 83.984H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M295.336 83.984' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M293.344 83.984H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip3)'/> +<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M122.941 209.23H126.18V140.094H122.941ZM181.609 209.23H184.848V131.141H181.609ZM240.281 209.23H243.516V136.902H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V83.984H357.617ZM416.285 209.23H419.524V83.984H416.285Z' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M122.941 209.23H126.18V140.094H122.941ZM181.609 209.23H184.848V131.141H181.609ZM240.281 209.23H243.516V136.902H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V83.984H357.617ZM416.285 209.23H419.524V83.984H416.285Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M124.559 140.094V140.031' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M124.559 140.094V140.031' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M122.566 140.032H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M124.559 140.094V140.156' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M124.559 140.094V140.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M126.555 140.156H122.57' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M183.231 131.141V130.703' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M183.231 131.141V130.703' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M181.238 130.703H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M183.231 131.141V131.578' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M183.231 131.141V131.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M185.223 131.579H181.238' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M241.899 136.902V136.652' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M241.899 136.902V136.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M239.906 136.652H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M241.899 136.902V137.152' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M241.899 136.902V137.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M243.891 137.152H239.906' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M359.238 83.984' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M357.242 83.984H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M359.238 83.984' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M357.242 83.984H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip3)'/> +<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M128.172 209.23H131.41V141.348H128.172ZM186.84 209.23H190.078V135.273H186.84ZM245.512 209.23H248.746V138.344H245.512ZM304.18 209.23H307.418V113.73H304.18ZM362.848 209.23H366.086V83.984H362.848ZM421.516 209.23H424.754V127.195H421.516Z' fill='#399' clip-path='url(#clip3)'/> +<path d='M128.172 209.23H131.41V141.348H128.172ZM186.84 209.23H190.078V135.273H186.84ZM245.512 209.23H248.746V138.344H245.512ZM304.18 209.23H307.418V113.73H304.18ZM362.848 209.23H366.086V83.984H362.848ZM421.516 209.23H424.754V127.195H421.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M129.789 141.348V141.285' fill='#399' clip-path='url(#clip3)'/> +<path d='M129.789 141.348V141.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M127.797 141.285H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M129.789 141.348V141.41' fill='#399' clip-path='url(#clip3)'/> +<path d='M129.789 141.348V141.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M131.785 141.41H127.8' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M188.461 135.273V134.711' fill='#399' clip-path='url(#clip3)'/> +<path d='M188.461 135.273V134.711' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M186.469 134.711H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M188.461 135.273V135.836' fill='#399' clip-path='url(#clip3)'/> +<path d='M188.461 135.273V135.836' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M190.453 135.836H186.468' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M247.129 138.344V138.09' fill='#399' clip-path='url(#clip3)'/> +<path d='M247.129 138.344V138.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M245.137 138.089H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M247.129 138.344V138.594' fill='#399' clip-path='url(#clip3)'/> +<path d='M247.129 138.344V138.594' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M249.121 138.593H245.136' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M305.797 113.73V112.855' fill='#399' clip-path='url(#clip3)'/> +<path d='M305.797 113.73V112.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M303.804 112.855H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M305.797 113.73V114.609' fill='#399' clip-path='url(#clip3)'/> +<path d='M305.797 113.73V114.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M307.789 114.61H303.804' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M364.469 83.984' fill='#399' clip-path='url(#clip3)'/> +<path d='M362.473 83.984H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M364.469 83.984' fill='#399' clip-path='url(#clip3)'/> +<path d='M362.473 83.984H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M423.137 127.195V122.246' fill='#399' clip-path='url(#clip3)'/> +<path d='M423.137 127.195V122.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M421.144 122.246H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M423.137 127.195V132.141' fill='#399' clip-path='url(#clip3)'/> +<path d='M423.137 127.195V132.141' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M425.129 132.14H421.144' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M133.402 209.23H136.641V140.91H133.402ZM192.07 209.23H195.309V145.98H192.07ZM250.742 209.23H253.977V141.098H250.742ZM309.41 209.23H312.649V124.816H309.41ZM368.078 209.23H371.317V83.984H368.078ZM426.746 209.23H429.984V123.937H426.746Z' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M133.402 209.23H136.641V140.91H133.402ZM192.07 209.23H195.309V145.98H192.07ZM250.742 209.23H253.977V141.098H250.742ZM309.41 209.23H312.649V124.816H309.41ZM368.078 209.23H371.317V83.984H368.078ZM426.746 209.23H429.984V123.937H426.746Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M135.02 140.91V140.848' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M135.02 140.91V140.848' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M133.027 140.848H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M135.02 140.91V140.973' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M135.02 140.91V140.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M137.016 140.973H133.031' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M193.692 145.98V144.918' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M193.692 145.98V144.918' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M191.699 144.918H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M193.692 145.98V147.047' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M193.692 145.98V147.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M195.684 147.046H191.699' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M252.359 141.098V140.973' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M252.359 141.098V140.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M250.367 140.973H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M252.359 141.098V141.223' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M252.359 141.098V141.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M254.352 141.223H250.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M311.027 124.816V123.937' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M311.027 124.816V123.937' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M309.035 123.938H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M311.027 124.816V125.691' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M311.027 124.816V125.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M313.02 125.691H309.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M369.699 83.984' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M367.703 83.984H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M369.699 83.984' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M367.703 83.984H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M428.367 123.937V119.867' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M428.367 123.937V119.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M426.375 119.867H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M428.367 123.937V128.008' fill='#d9b3b3' clip-path='url(#clip3)'/> +<path d='M428.367 123.937V128.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<path d='M430.36 128.008H426.375' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/> +<g transform='matrix(0 -1 1 0 -99.092 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -40.423 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 18.246 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 76.915 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 135.584 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 194.253 255.07)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -93.862 254.695)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 -35.193 255.008)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 23.476 253.755)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 82.145 260.581)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 140.814 249.434)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 199.483 263.023)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-56'/> +<use x='121.25' y='188.674' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 -88.631 253.755)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -29.962 251.563)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 28.707 253.129)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 87.376 250.436)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 146.045 251.563)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 204.714 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-51'/> +<use x='126.877' y='188.674' xlink:href='#g2-50'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -83.401 251.751)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -24.732 254.945)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 33.937 243.172)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 92.606 247.994)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 151.275 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-52'/> +<use x='126.877' y='188.674' xlink:href='#g2-55'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 209.944 236.471)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -78.17 236.283)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -19.501 253.567)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 39.168 221.442)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 97.837 223.571)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 156.506 212.424)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-54'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 215.175 245.176)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -72.94 253.38)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 -14.271 256.448)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 44.398 242.922)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 103.067 256.198)'> +<use x='114.487' y='188.674' xlink:href='#g2-48'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-57'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 161.736 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-50'/> +<use x='126.877' y='188.674' xlink:href='#g2-51'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 220.405 232.025)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 -67.709 252.064)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -9.04 248.244)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 49.629 235.031)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 108.298 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-53'/> +<use x='126.877' y='188.674' xlink:href='#g2-54'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 166.967 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-49'/> +<use x='122.76' y='188.674' xlink:href='#g2-48'/> +<use x='125.406' y='188.674' xlink:href='#g2-46'/> +<use x='126.877' y='188.674' xlink:href='#g2-51'/> +<use x='129.523' y='188.674' xlink:href='#g2-50'/> +<use x='132.169' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 225.636 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-51'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-48'/> +<use x='126.877' y='188.674' xlink:href='#g2-56'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -62.479 248.558)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -3.81 239.602)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-50'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 54.859 245.364)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 113.528 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-55'/> +<use x='125.406' y='188.674' xlink:href='#g2-51'/> +<use x='128.053' y='188.674' xlink:href='#g2-46'/> +<use x='129.523' y='188.674' xlink:href='#g2-52'/> +<use x='132.169' y='188.674' xlink:href='#g2-53'/> +<use x='134.816' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 172.197 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-54'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-48'/> +<use x='126.877' y='188.674' xlink:href='#g2-54'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 230.866 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-50'/> +<use x='126.877' y='188.674' xlink:href='#g2-52'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -57.249 249.81)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 1.42 243.736)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 60.089 246.804)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-49'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 118.758 222.193)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-53'/> +<use x='121.25' y='188.674' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 177.427 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-52'/> +<use x='126.877' y='188.674' xlink:href='#g2-56'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 236.096 235.657)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 -52.018 249.372)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 6.651 254.444)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 65.32 249.56)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-48'/> +<use x='121.25' y='188.674' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 123.989 233.278)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 182.658 192.447)'> +<use x='109.598' y='188.674' xlink:href='#g4-1'/> +<use x='113.103' y='188.674' xlink:href='#g4-1'/> +<use x='116.608' y='188.674' xlink:href='#g4-1'/> +<use x='120.114' y='188.674' xlink:href='#g2-50'/> +<use x='122.76' y='188.674' xlink:href='#g2-46'/> +<use x='124.23' y='188.674' xlink:href='#g2-51'/> +<use x='126.877' y='188.674' xlink:href='#g2-49'/> +<use x='129.523' y='188.674' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 241.327 232.401)'> +<use x='114.487' y='188.674' xlink:href='#g2-49'/> +<use x='117.133' y='188.674' xlink:href='#g2-46'/> +<use x='118.603' y='188.674' xlink:href='#g2-51'/> +<use x='121.25' y='188.674' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -129.314 316.355)'> +<use x='114.487' y='188.674' xlink:href='#g1-82'/> +<use x='120.457' y='188.674' xlink:href='#g1-101'/> +<use x='124.553' y='188.674' xlink:href='#g1-108'/> +<use x='126.753' y='188.674' xlink:href='#g1-97'/> +<use x='131.181' y='188.674' xlink:href='#g1-116'/> +<use x='134.509' y='188.674' xlink:href='#g1-105'/> +<use x='136.709' y='188.674' xlink:href='#g1-118'/> +<use x='140.957' y='188.674' xlink:href='#g1-101'/> +<use x='148.124' y='188.674' xlink:href='#g1-116'/> +<use x='151.452' y='188.674' xlink:href='#g1-105'/> +<use x='153.652' y='188.674' xlink:href='#g1-109'/> +<use x='160.972' y='188.674' xlink:href='#g1-101'/> +<use x='168.139' y='188.674' xlink:href='#g3-40'/> +<use x='171.432' y='188.674' xlink:href='#g3-108'/> +<use x='173.453' y='188.674' xlink:href='#g3-111'/> +<use x='177.452' y='188.674' xlink:href='#g3-119'/> +<use x='183' y='188.674' xlink:href='#g3-101'/> +<use x='186.764' y='188.674' xlink:href='#g3-114'/> +<use x='192.479' y='188.674' xlink:href='#g3-105'/> +<use x='194.499' y='188.674' xlink:href='#g3-115'/> +<use x='200.568' y='188.674' xlink:href='#g3-98'/> +<use x='205.176' y='188.674' xlink:href='#g3-101'/> +<use x='208.94' y='188.674' xlink:href='#g3-116'/> +<use x='211.998' y='188.674' xlink:href='#g3-116'/> +<use x='215.056' y='188.674' xlink:href='#g3-101'/> +<use x='218.819' y='188.674' xlink:href='#g3-114'/> +<use x='221.711' y='188.674' xlink:href='#g3-41'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg new file mode 100644 index 0000000..e8b04a0 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg @@ -0,0 +1,1269 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.627pt' height='259.632pt' viewBox='106.732 54.993 381.627 259.632'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip4'> +<path d='M135.949 251.93H487.961V84.164H135.949Z'/> +</clipPath> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/> +<use id='g3-49' xlink:href='#g0-49' transform='scale(1.143)'/> +<use id='g3-54' xlink:href='#g0-54' transform='scale(1.143)'/> +<use id='g3-56' xlink:href='#g0-56' transform='scale(1.143)'/> +<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-103' xlink:href='#g0-103' transform='scale(1.143)'/> +<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/> +<use id='g2-41' xlink:href='#g0-41' transform='scale(.714)'/> +<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/> +<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/> +<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/> +<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/> +<use id='g2-73' xlink:href='#g0-73' transform='scale(.714)'/> +<use id='g2-85' xlink:href='#g0-85' transform='scale(.714)'/> +<use id='g2-88' xlink:href='#g0-88' transform='scale(.714)'/> +<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/> +<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/> +<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/> +<use id='g2-100' xlink:href='#g0-100' transform='scale(.714)'/> +<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/> +<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/> +<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/> +<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/> +<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/> +<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/> +<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/> +<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/> +<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/> +<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/> +<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/> +<use id='g2-117' xlink:href='#g0-117' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<path id='g4-2' d='M4.13-2.481C4.184-2.535 4.204-2.57 4.204-2.615C4.204-2.69 4.139-2.755 4.065-2.755C4.01-2.755 3.985-2.73 3.93-2.675L2.7-1.445L1.465-2.68C1.41-2.735 1.375-2.755 1.33-2.755C1.255-2.755 1.191-2.69 1.191-2.615C1.191-2.56 1.215-2.535 1.27-2.481L2.501-1.245L1.27-.01C1.215 .045 1.191 .07 1.191 .125C1.191 .199 1.255 .264 1.33 .264C1.385 .264 1.41 .239 1.46 .189L2.695-1.046L3.97 .229C3.995 .249 4.03 .264 4.065 .264C4.139 .264 4.204 .199 4.204 .125C4.204 .095 4.194 .075 4.184 .05C4.164 .02 3.238-.892 2.894-1.245L4.13-2.481Z'/> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/> +<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/> +<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/> +<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/> +<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/> +<path id='g0-73' d='M1.381-4.84H.676V0H1.381V-4.84Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-85' d='M4.4-4.84H3.794V-1.625C3.794-.69 3.166-.265 2.566-.265S1.381-.697 1.381-1.618V-4.84H.676V-1.632C.676-.607 1.555 .146 2.559 .146C3.557 .146 4.4-.614 4.4-1.632V-4.84Z'/> +<path id='g0-88' d='M2.755-2.552L4.519-4.84H3.759L2.413-3.055L1.039-4.84H.209L2.071-2.552L.105 0H.865L2.413-2.099L3.996 0H4.826L2.755-2.552Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/> +<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-117' d='M3.243-3.096H2.636V-1.074C2.636-.516 2.162-.342 1.757-.342C1.241-.342 1.186-.481 1.186-.802V-3.096H.579V-.76C.579-.139 .851 .07 1.339 .07C1.625 .07 2.239 .014 2.657-.321V0H3.243V-3.096Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/> +</defs> +<g id='page4'> +<path d='M194.617 260.785V251.93M253.285 260.785V251.93M311.953 260.785V251.93M370.625 260.785V251.93M429.293 260.785V251.93M194.617 75.308V84.164M253.285 75.308V84.164M311.953 75.308V84.164M370.625 75.308V84.164M429.293 75.308V84.164' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M165.281 256.18V251.93M223.953 256.18V251.93M282.621 256.18V251.93M341.289 256.18V251.93M399.957 256.18V251.93M458.629 256.18V251.93M165.281 79.91V84.164M223.953 79.91V84.164M282.621 79.91V84.164M341.289 79.91V84.164M399.957 79.91V84.164M458.629 79.91V84.164' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M135.949 251.93H140.199M135.949 218.375H140.199M135.949 184.824H140.199M135.949 151.269H140.199M135.949 117.719H140.199M135.949 84.164H140.199M487.961 251.93H483.711M487.961 218.375H483.711M487.961 184.824H483.711M487.961 151.269H483.711M487.961 117.719H483.711M487.961 84.164H483.711' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M135.949 251.93V84.164H487.961V251.93H135.949Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -21.265 74.992)'> +<use x='168.285' y='191.334' xlink:href='#g3-97'/> +<use x='172.353' y='191.334' xlink:href='#g3-108'/> +<use x='174.373' y='191.334' xlink:href='#g3-108'/> +<use x='176.393' y='191.334' xlink:href='#g3-111'/> +<use x='180.863' y='191.334' xlink:href='#g3-99'/> +<use x='184.627' y='191.334' xlink:href='#g3-45'/> +<use x='187.449' y='191.334' xlink:href='#g3-116'/> +<use x='190.507' y='191.334' xlink:href='#g3-101'/> +<use x='194.271' y='191.334' xlink:href='#g3-115'/> +<use x='197.517' y='191.334' xlink:href='#g3-116'/> +<use x='200.575' y='191.334' xlink:href='#g3-49'/> +</g> +<g transform='matrix(1 0 0 1 36.532 74.992)'> +<use x='168.285' y='191.334' xlink:href='#g3-97'/> +<use x='172.353' y='191.334' xlink:href='#g3-108'/> +<use x='174.373' y='191.334' xlink:href='#g3-108'/> +<use x='176.393' y='191.334' xlink:href='#g3-111'/> +<use x='180.863' y='191.334' xlink:href='#g3-99'/> +<use x='184.627' y='191.334' xlink:href='#g3-45'/> +<use x='187.449' y='191.334' xlink:href='#g3-116'/> +<use x='190.507' y='191.334' xlink:href='#g3-101'/> +<use x='194.271' y='191.334' xlink:href='#g3-115'/> +<use x='197.517' y='191.334' xlink:href='#g3-116'/> +<use x='200.575' y='191.334' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 94.98 74.992)'> +<use x='168.285' y='191.334' xlink:href='#g3-115'/> +<use x='171.531' y='191.334' xlink:href='#g3-104'/> +<use x='175.904' y='191.334' xlink:href='#g3-54'/> +<use x='180.138' y='191.334' xlink:href='#g3-98'/> +<use x='184.746' y='191.334' xlink:href='#g3-101'/> +<use x='188.509' y='191.334' xlink:href='#g3-110'/> +<use x='192.882' y='191.334' xlink:href='#g3-99'/> +<use x='196.646' y='191.334' xlink:href='#g3-104'/> +<use x='201.018' y='191.334' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 153.649 74.992)'> +<use x='168.285' y='191.334' xlink:href='#g3-115'/> +<use x='171.531' y='191.334' xlink:href='#g3-104'/> +<use x='175.904' y='191.334' xlink:href='#g3-56'/> +<use x='180.138' y='191.334' xlink:href='#g3-98'/> +<use x='184.746' y='191.334' xlink:href='#g3-101'/> +<use x='188.509' y='191.334' xlink:href='#g3-110'/> +<use x='192.882' y='191.334' xlink:href='#g3-99'/> +<use x='196.646' y='191.334' xlink:href='#g3-104'/> +<use x='201.018' y='191.334' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 207.225 74.992)'> +<use x='168.285' y='191.334' xlink:href='#g3-120'/> +<use x='172.187' y='191.334' xlink:href='#g3-109'/> +<use x='178.912' y='191.334' xlink:href='#g3-97'/> +<use x='182.98' y='191.334' xlink:href='#g3-108'/> +<use x='185' y='191.334' xlink:href='#g3-108'/> +<use x='187.02' y='191.334' xlink:href='#g3-111'/> +<use x='191.49' y='191.334' xlink:href='#g3-99'/> +<use x='195.254' y='191.334' xlink:href='#g3-45'/> +<use x='198.076' y='191.334' xlink:href='#g3-116'/> +<use x='201.134' y='191.334' xlink:href='#g3-101'/> +<use x='204.898' y='191.334' xlink:href='#g3-115'/> +<use x='208.144' y='191.334' xlink:href='#g3-116'/> +<use x='211.202' y='191.334' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 263.494 74.992)'> +<use x='168.285' y='191.334' xlink:href='#g3-99'/> +<use x='172.049' y='191.334' xlink:href='#g3-97'/> +<use x='176.117' y='191.334' xlink:href='#g3-99'/> +<use x='179.88' y='191.334' xlink:href='#g3-104'/> +<use x='184.253' y='191.334' xlink:href='#g3-101'/> +<use x='188.017' y='191.334' xlink:href='#g3-45'/> +<use x='190.839' y='191.334' xlink:href='#g3-115'/> +<use x='194.086' y='191.334' xlink:href='#g3-99'/> +<use x='197.849' y='191.334' xlink:href='#g3-114'/> +<use x='200.741' y='191.334' xlink:href='#g3-97'/> +<use x='204.81' y='191.334' xlink:href='#g3-116'/> +<use x='207.868' y='191.334' xlink:href='#g3-99'/> +<use x='211.631' y='191.334' xlink:href='#g3-104'/> +<use x='216.004' y='191.334' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 62.23)'> +<use x='168.285' y='191.334' xlink:href='#g2-48'/> +<use x='170.931' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.677)'> +<use x='168.285' y='191.334' xlink:href='#g2-48'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-53'/> +<use x='175.048' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -4.876)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -38.43)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-53'/> +<use x='175.048' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.983)'> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -105.536)'> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-53'/> +<use x='175.048' y='191.334' xlink:href='#g2-120'/> +</g> +<path d='M135.949 184.824H487.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M140.125 251.93H143.363V184.824H140.125ZM198.797 251.93H202.035V184.824H198.797ZM257.465 251.93H260.703V184.824H257.465ZM316.133 251.93H319.371V184.824H316.133ZM374.801 251.93H378.039V184.824H374.801ZM433.473 251.93H436.711V184.824H433.473Z' fill='#933' clip-path='url(#clip4)'/> +<path d='M140.125 251.93H143.363V184.824H140.125ZM198.797 251.93H202.035V184.824H198.797ZM257.465 251.93H260.703V184.824H257.465ZM316.133 251.93H319.371V184.824H316.133ZM374.801 251.93H378.039V184.824H374.801ZM433.473 251.93H436.711V184.824H433.473Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M141.746 184.824V184.758' fill='#933' clip-path='url(#clip4)'/> +<path d='M141.746 184.824V184.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M139.754 184.758H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M141.746 184.824V184.891' fill='#933' clip-path='url(#clip4)'/> +<path d='M141.746 184.824V184.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M143.738 184.891H139.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M200.414 184.824V184.621' fill='#933' clip-path='url(#clip4)'/> +<path d='M200.414 184.824V184.621' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M198.422 184.621H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M200.414 184.824V185.023' fill='#933' clip-path='url(#clip4)'/> +<path d='M200.414 184.824V185.023' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M202.406 185.023H198.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M259.082 184.824' fill='#933' clip-path='url(#clip4)'/> +<path d='M257.09 184.824H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M259.082 184.824' fill='#933' clip-path='url(#clip4)'/> +<path d='M257.09 184.824H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M317.754 184.824V178.785' fill='#933' clip-path='url(#clip4)'/> +<path d='M317.754 184.824V178.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M315.762 178.785H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M317.754 184.824V190.863' fill='#933' clip-path='url(#clip4)'/> +<path d='M317.754 184.824V190.863' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M319.746 190.864H315.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M376.422 184.824V184.086' fill='#933' clip-path='url(#clip4)'/> +<path d='M376.422 184.824V184.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M374.43 184.086H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M376.422 184.824V185.562' fill='#933' clip-path='url(#clip4)'/> +<path d='M376.422 184.824V185.562' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M378.414 185.562H374.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M435.09 184.824V181.402' fill='#933' clip-path='url(#clip4)'/> +<path d='M435.09 184.824V181.402' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M433.098 181.403H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M435.09 184.824V188.246' fill='#933' clip-path='url(#clip4)'/> +<path d='M435.09 184.824V188.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M437.082 188.246H433.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M145.356 251.93H148.594V184.488H145.356ZM204.028 251.93H207.266V184.621H204.028ZM262.695 251.93H265.934V184.824H262.695ZM321.363 251.93H324.602V182.004H321.363ZM380.031 251.93H383.27V178.648H380.031ZM438.703 251.93H441.942V187.238H438.703Z' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M145.356 251.93H148.594V184.488H145.356ZM204.028 251.93H207.266V184.621H204.028ZM262.695 251.93H265.934V184.824H262.695ZM321.363 251.93H324.602V182.004H321.363ZM380.031 251.93H383.27V178.648H380.031ZM438.703 251.93H441.942V187.238H438.703Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M146.977 184.488V184.422' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M146.977 184.488V184.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M144.984 184.421H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M146.977 184.488V184.555' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M146.977 184.488V184.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M148.968 184.555H144.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M205.645 184.621V184.555' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M205.645 184.621V184.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M203.652 184.555H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M205.645 184.621V184.687' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M205.645 184.621V184.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M207.636 184.688H203.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M264.313 184.824' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M262.32 184.824H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M264.313 184.824' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M262.32 184.824H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M322.984 182.004V177.441' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M322.984 182.004V177.441' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M320.992 177.441H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M322.984 182.004V186.566' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M322.984 182.004V186.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M324.976 186.567H320.988' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M381.652 178.648V176.973' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M381.652 178.648V176.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M379.66 176.973H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M381.652 178.648V180.328' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M381.652 178.648V180.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M383.644 180.328H379.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M440.32 187.238V181.402' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M440.32 187.238V181.402' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M438.328 181.403H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M440.32 187.238V193.078' fill='#bf8080' clip-path='url(#clip4)'/> +<path d='M440.32 187.238V193.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M442.312 193.078H438.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M150.586 251.93H153.824V184.621H150.586ZM209.258 251.93H212.496V171.871H209.258ZM267.926 251.93H271.164V137.312H267.926ZM326.594 251.93H329.832V84.164H326.594ZM385.262 251.93H388.5V84.164H385.262ZM443.934 251.93H447.172V84.164H443.934Z' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M150.586 251.93H153.824V184.621H150.586ZM209.258 251.93H212.496V171.871H209.258ZM267.926 251.93H271.164V137.312H267.926ZM326.594 251.93H329.832V84.164H326.594ZM385.262 251.93H388.5V84.164H385.262ZM443.934 251.93H447.172V84.164H443.934Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M152.207 184.621' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M150.215 184.621H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M152.207 184.621' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M150.215 184.621H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M210.875 171.871V170.461' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M210.875 171.871V170.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M208.883 170.461H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M210.875 171.871V173.281' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M210.875 171.871V173.281' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M212.868 173.281H208.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M269.543 137.312V129.394' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M269.543 137.312V129.394' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M267.551 129.394H271.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M269.543 137.312V145.23' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M269.543 137.312V145.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M271.535 145.23H267.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M328.215 84.164' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M326.223 84.164H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M328.215 84.164' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M326.223 84.164H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M386.883 84.164' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M384.891 84.164H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M386.883 84.164' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M384.891 84.164H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M445.551 84.164' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M443.559 84.164H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M445.551 84.164' fill='#8080bf' clip-path='url(#clip4)'/> +<path d='M443.559 84.164H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M155.817 251.93H159.055V179.926H155.817ZM214.488 251.93H217.727V180.461H214.488ZM273.156 251.93H276.395V131.676H273.156ZM331.824 251.93H335.063V126.105H331.824ZM390.492 251.93H393.731V84.164H390.492ZM449.164 251.93H452.402V84.164H449.164Z' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M155.817 251.93H159.055V179.926H155.817ZM214.488 251.93H217.727V180.461H214.488ZM273.156 251.93H276.395V131.676H273.156ZM331.824 251.93H335.063V126.105H331.824ZM390.492 251.93H393.731V84.164H390.492ZM449.164 251.93H452.402V84.164H449.164Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M157.438 179.926' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M155.445 179.925H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M157.438 179.926' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M155.445 179.925H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M216.106 180.461' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M214.113 180.461H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M216.106 180.461' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M214.113 180.461H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M274.774 131.676V127.715' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M274.774 131.676V127.715' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M272.781 127.715H276.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M274.774 131.676V135.633' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M274.774 131.676V135.633' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M276.765 135.633H272.781' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M333.445 126.105V120.066' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M333.445 126.105V120.066' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M331.453 120.067H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M333.445 126.105V132.144' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M333.445 126.105V132.144' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M335.437 132.145H331.449' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M392.113 84.164' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M390.121 84.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M392.113 84.164' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M390.121 84.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M450.781 84.164' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M448.789 84.164H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M450.781 84.164' fill='#ffb733' clip-path='url(#clip4)'/> +<path d='M448.789 84.164H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M161.047 251.93H164.285V162.141H161.047ZM219.719 251.93H222.957V163.418H219.719ZM278.387 251.93H281.625V84.164H278.387ZM337.055 251.93H340.293V112.148H337.055ZM395.723 251.93H398.961V86.848H395.723ZM454.395 251.93H457.633V184.824H454.395Z' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M161.047 251.93H164.285V162.141H161.047ZM219.719 251.93H222.957V163.418H219.719ZM278.387 251.93H281.625V84.164H278.387ZM337.055 251.93H340.293V112.148H337.055ZM395.723 251.93H398.961V86.848H395.723ZM454.395 251.93H457.633V184.824H454.395Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M162.668 162.141V162.074' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M162.668 162.141V162.074' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M160.676 162.074H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M162.668 162.141V162.207' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M162.668 162.141V162.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M164.661 162.207H160.676' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M221.336 163.418V163.348' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M221.336 163.418V163.348' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M219.344 163.348H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M221.336 163.418V163.484' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M221.336 163.418V163.484' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M223.329 163.484H219.344' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M280.004 84.164' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M278.012 84.164H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M280.004 84.164' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M278.012 84.164H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M338.676 112.148' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M336.684 112.148H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M338.676 112.148' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M336.684 112.148H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M397.344 86.848V86.648' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M397.344 86.848V86.648' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M395.352 86.648H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M397.344 86.848V87.051' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M397.344 86.848V87.051' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M399.336 87.051H395.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M456.012 184.824V175.832' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M456.012 184.824V175.832' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M454.02 175.832H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M456.012 184.824V193.816' fill='#bf80bf' clip-path='url(#clip4)'/> +<path d='M456.012 184.824V193.816' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M458.004 193.816H454.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M166.278 251.93H169.516V171.937H166.278ZM224.949 251.93H228.188V181.066H224.949ZM283.617 251.93H286.856V151.269H283.617ZM342.285 251.93H345.524V162.477H342.285ZM400.953 251.93H404.192V192.34H400.953ZM459.625 251.93H462.863V189.586H459.625Z' fill='#c96' clip-path='url(#clip4)'/> +<path d='M166.278 251.93H169.516V171.937H166.278ZM224.949 251.93H228.188V181.066H224.949ZM283.617 251.93H286.856V151.269H283.617ZM342.285 251.93H345.524V162.477H342.285ZM400.953 251.93H404.192V192.34H400.953ZM459.625 251.93H462.863V189.586H459.625Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M167.899 171.937' fill='#c96' clip-path='url(#clip4)'/> +<path d='M165.906 171.938H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M167.899 171.937' fill='#c96' clip-path='url(#clip4)'/> +<path d='M165.906 171.938H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M226.567 181.066V180.996' fill='#c96' clip-path='url(#clip4)'/> +<path d='M226.567 181.066V180.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M224.574 180.996H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M226.567 181.066V181.133' fill='#c96' clip-path='url(#clip4)'/> +<path d='M226.567 181.066V181.133' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M228.559 181.133H224.574' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M285.234 151.269' fill='#c96' clip-path='url(#clip4)'/> +<path d='M283.242 151.27H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M285.234 151.269' fill='#c96' clip-path='url(#clip4)'/> +<path d='M283.242 151.27H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M343.906 162.477V160.195' fill='#c96' clip-path='url(#clip4)'/> +<path d='M343.906 162.477V160.195' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M341.914 160.195H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M343.906 162.477V164.758' fill='#c96' clip-path='url(#clip4)'/> +<path d='M343.906 162.477V164.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M345.898 164.758H341.91' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M402.574 192.34V191.266' fill='#c96' clip-path='url(#clip4)'/> +<path d='M402.574 192.34V191.266' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M400.582 191.265H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M402.574 192.34V193.414' fill='#c96' clip-path='url(#clip4)'/> +<path d='M402.574 192.34V193.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M404.566 193.414H400.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M461.242 189.586V186.164' fill='#c96' clip-path='url(#clip4)'/> +<path d='M461.242 189.586V186.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M459.25 186.164H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M461.242 189.586V193.012' fill='#c96' clip-path='url(#clip4)'/> +<path d='M461.242 189.586V193.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M463.234 193.012H459.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M171.508 251.93H174.746V180.93H171.508ZM230.18 251.93H233.414V179.051H230.18ZM288.848 251.93H292.086V84.164H288.848ZM347.516 251.93H350.754V84.164H347.516ZM406.184 251.93H409.422V84.164H406.184ZM464.856 251.93H468.094V84.164H464.856Z' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M171.508 251.93H174.746V180.93H171.508ZM230.18 251.93H233.414V179.051H230.18ZM288.848 251.93H292.086V84.164H288.848ZM347.516 251.93H350.754V84.164H347.516ZM406.184 251.93H409.422V84.164H406.184ZM464.856 251.93H468.094V84.164H464.856Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M173.129 180.93' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M171.137 180.93H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M173.129 180.93' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M171.137 180.93H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M231.797 179.051V178.852' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M231.797 179.051V178.852' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M229.805 178.852H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M231.797 179.051V179.254' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M231.797 179.051V179.254' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M233.79 179.254H229.805' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M290.465 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M288.473 84.164H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M290.465 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M288.473 84.164H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M349.137 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M347.145 84.164H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M349.137 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M347.145 84.164H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M407.805 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M405.813 84.164H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M407.805 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M405.813 84.164H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M466.473 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M464.481 84.164H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M466.473 84.164' fill='#80bf80' clip-path='url(#clip4)'/> +<path d='M464.481 84.164H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M176.738 251.93H179.977V154.828H176.738ZM235.41 251.93H238.645V176.168H235.41ZM294.078 251.93H297.317V84.164H294.078ZM352.746 251.93H355.984V84.164H352.746ZM411.414 251.93H414.652V84.164H411.414ZM470.086 251.93H473.324V189.586H470.086Z' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M176.738 251.93H179.977V154.828H176.738ZM235.41 251.93H238.645V176.168H235.41ZM294.078 251.93H297.317V84.164H294.078ZM352.746 251.93H355.984V84.164H352.746ZM411.414 251.93H414.652V84.164H411.414ZM470.086 251.93H473.324V189.586H470.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M178.36 154.828V148.922' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M178.36 154.828V148.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M176.367 148.922H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M178.36 154.828V160.73' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M178.36 154.828V160.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M180.352 160.731H176.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M237.027 176.168V175.832' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M237.027 176.168V175.832' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M235.035 175.832H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M237.027 176.168V176.5' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M237.027 176.168V176.5' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M239.02 176.5H235.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M295.695 84.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M293.703 84.164H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M295.695 84.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M293.703 84.164H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M354.367 84.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M352.375 84.164H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M354.367 84.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M352.375 84.164H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M413.035 84.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M411.043 84.164H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M413.035 84.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M411.043 84.164H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M471.703 189.586V186.164' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M471.703 189.586V186.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M469.711 186.164H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M471.703 189.586V193.012' fill='#bfbf80' clip-path='url(#clip4)'/> +<path d='M471.703 189.586V193.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M473.695 193.012H469.711' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M181.969 251.93H185.207V167.914H181.969ZM240.641 251.93H243.875V168.984H240.641ZM299.309 251.93H302.547V84.164H299.309ZM357.977 251.93H361.215V84.164H357.977ZM416.645 251.93H419.883V84.164H416.645ZM475.317 251.93H478.555V84.164H475.317Z' fill='#399' clip-path='url(#clip4)'/> +<path d='M181.969 251.93H185.207V167.914H181.969ZM240.641 251.93H243.875V168.984H240.641ZM299.309 251.93H302.547V84.164H299.309ZM357.977 251.93H361.215V84.164H357.977ZM416.645 251.93H419.883V84.164H416.645ZM475.317 251.93H478.555V84.164H475.317Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M183.59 167.914V167.844' fill='#399' clip-path='url(#clip4)'/> +<path d='M183.59 167.914V167.844' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M181.598 167.844H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M183.59 167.914V167.98' fill='#399' clip-path='url(#clip4)'/> +<path d='M183.59 167.914V167.98' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M185.582 167.98H181.597' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M242.258 168.984V168.918' fill='#399' clip-path='url(#clip4)'/> +<path d='M242.258 168.984V168.918' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M240.266 168.918H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M242.258 168.984V169.055' fill='#399' clip-path='url(#clip4)'/> +<path d='M242.258 168.984V169.055' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M244.25 169.055H240.265' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M300.926 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M298.933 84.164H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M300.926 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M298.933 84.164H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M359.598 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M357.606 84.164H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M359.598 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M357.606 84.164H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M418.266 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M416.274 84.164H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M418.266 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M416.274 84.164H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M476.934 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M474.942 84.164H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M476.934 84.164' fill='#399' clip-path='url(#clip4)'/> +<path d='M474.942 84.164H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M187.199 251.93H190.438V175.562H187.199ZM245.871 251.93H249.106V176.168H245.871ZM304.539 251.93H307.777V92.551H304.539ZM363.207 251.93H366.445V126.105H363.207ZM421.875 251.93H425.113V109.461H421.875ZM480.547 251.93H483.785V175.227H480.547Z' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M187.199 251.93H190.438V175.562H187.199ZM245.871 251.93H249.106V176.168H245.871ZM304.539 251.93H307.777V92.551H304.539ZM363.207 251.93H366.445V126.105H363.207ZM421.875 251.93H425.113V109.461H421.875ZM480.547 251.93H483.785V175.227H480.547Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M188.82 175.562V175.43' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M188.82 175.562V175.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M186.828 175.43H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M188.82 175.562V175.695' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M188.82 175.562V175.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M190.813 175.696H186.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M247.488 176.168V175.965' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M247.488 176.168V175.965' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M245.496 175.965H249.481' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M247.488 176.168V176.367' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M247.488 176.168V176.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M249.481 176.368H245.496' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M306.156 92.551V74.433' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M306.156 92.551V74.433' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M304.164 74.434H308.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M306.156 92.551V110.672' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M306.156 92.551V110.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M308.149 110.672H304.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M364.828 126.105V123.824' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M364.828 126.105V123.824' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M362.836 123.825H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M364.828 126.105V128.387' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M364.828 126.105V128.387' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M366.82 128.387H362.832' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M423.496 109.461V109.262' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M423.496 109.461V109.262' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M421.504 109.262H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M423.496 109.461V109.664' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M423.496 109.461V109.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M425.488 109.664H421.504' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M482.164 175.227V171.805' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M482.164 175.227V171.805' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M480.172 171.804H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M482.164 175.227V178.648' fill='#d9b3b3' clip-path='url(#clip4)'/> +<path d='M482.164 175.227V178.648' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M484.156 178.648H480.172' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<path d='M369.781 314.227H487.762V278.973H369.781Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/> +<g transform='matrix(1 0 0 1 204.818 118.327)'> +<use x='168.285' y='167.424' xlink:href='#g2-99'/> +<use x='170.637' y='167.424' xlink:href='#g2-53'/> +<use x='173.284' y='167.424' xlink:href='#g2-45'/> +<use x='175.048' y='167.424' xlink:href='#g2-49'/> +<use x='177.694' y='167.424' xlink:href='#g2-56'/> +<use x='180.341' y='167.424' xlink:href='#g2-120'/> +<use x='182.779' y='167.424' xlink:href='#g2-108'/> +<use x='184.042' y='167.424' xlink:href='#g2-97'/> +<use x='186.438' y='167.424' xlink:href='#g2-114'/> +<use x='188.245' y='167.424' xlink:href='#g2-103'/> +<use x='190.891' y='167.424' xlink:href='#g2-101'/> +<use x='193.244' y='167.424' xlink:href='#g2-44'/> +<use x='196.478' y='167.424' xlink:href='#g2-49'/> +<use x='199.124' y='167.424' xlink:href='#g2-52'/> +<use x='201.771' y='167.424' xlink:href='#g2-52'/> +<use x='204.417' y='167.424' xlink:href='#g2-71'/> +<use x='207.946' y='167.424' xlink:href='#g2-98'/> +<use x='168.285' y='173.401' xlink:href='#g2-50'/> +<use x='170.931' y='173.401' xlink:href='#g4-2'/> +<use x='178.092' y='173.401' xlink:href='#g2-49'/> +<use x='180.738' y='173.401' xlink:href='#g2-56'/> +<use x='183.385' y='173.401' xlink:href='#g2-45'/> +<use x='185.149' y='173.401' xlink:href='#g2-99'/> +<use x='187.501' y='173.401' xlink:href='#g2-111'/> +<use x='190.001' y='173.401' xlink:href='#g2-114'/> +<use x='191.808' y='173.401' xlink:href='#g2-101'/> +<use x='195.925' y='173.401' xlink:href='#g2-73'/> +<use x='197.395' y='173.401' xlink:href='#g2-110'/> +<use x='200.128' y='173.401' xlink:href='#g2-116'/> +<use x='202.039' y='173.401' xlink:href='#g2-101'/> +<use x='204.391' y='173.401' xlink:href='#g2-108'/> +<use x='207.418' y='173.401' xlink:href='#g2-88'/> +<use x='210.947' y='173.401' xlink:href='#g2-101'/> +<use x='213.299' y='173.401' xlink:href='#g2-111'/> +<use x='215.945' y='173.401' xlink:href='#g2-110'/> +<use x='220.442' y='173.401' xlink:href='#g2-64'/> +<use x='223.971' y='173.401' xlink:href='#g2-51'/> +<use x='226.617' y='173.401' xlink:href='#g2-71'/> +<use x='230.146' y='173.401' xlink:href='#g2-104'/> +<use x='232.879' y='173.401' xlink:href='#g2-122'/> +<use x='168.285' y='179.379' xlink:href='#g2-85'/> +<use x='171.917' y='179.379' xlink:href='#g2-98'/> +<use x='174.65' y='179.379' xlink:href='#g2-117'/> +<use x='177.383' y='179.379' xlink:href='#g2-110'/> +<use x='180.116' y='179.379' xlink:href='#g2-116'/> +<use x='182.027' y='179.379' xlink:href='#g2-117'/> +<use x='186.524' y='179.379' xlink:href='#g2-50'/> +<use x='189.17' y='179.379' xlink:href='#g2-48'/> +<use x='191.817' y='179.379' xlink:href='#g2-46'/> +<use x='193.287' y='179.379' xlink:href='#g2-48'/> +<use x='195.933' y='179.379' xlink:href='#g2-52'/> +<use x='198.58' y='179.379' xlink:href='#g2-44'/> +<use x='201.814' y='179.379' xlink:href='#g2-71'/> +<use x='205.343' y='179.379' xlink:href='#g2-67'/> +<use x='208.724' y='179.379' xlink:href='#g2-67'/> +<use x='213.87' y='179.379' xlink:href='#g2-57'/> +<use x='216.516' y='179.379' xlink:href='#g2-46'/> +<use x='217.986' y='179.379' xlink:href='#g2-51'/> +<use x='220.633' y='179.379' xlink:href='#g2-46'/> +<use x='222.103' y='179.379' xlink:href='#g2-48'/> +<use x='224.749' y='179.379' xlink:href='#g2-44'/> +<use x='227.984' y='179.379' xlink:href='#g2-103'/> +<use x='230.63' y='179.379' xlink:href='#g2-108'/> +<use x='231.893' y='179.379' xlink:href='#g2-105'/> +<use x='233.155' y='179.379' xlink:href='#g2-98'/> +<use x='236.035' y='179.379' xlink:href='#g2-99'/> +<use x='240.152' y='179.379' xlink:href='#g2-50'/> +<use x='242.798' y='179.379' xlink:href='#g2-46'/> +<use x='244.268' y='179.379' xlink:href='#g2-51'/> +<use x='246.915' y='179.379' xlink:href='#g2-49'/> +<use x='249.561' y='179.379' xlink:href='#g2-44'/> +<use x='252.796' y='179.379' xlink:href='#g2-99'/> +<use x='255.148' y='179.379' xlink:href='#g2-108'/> +<use x='256.41' y='179.379' xlink:href='#g2-97'/> +<use x='258.953' y='179.379' xlink:href='#g2-110'/> +<use x='261.686' y='179.379' xlink:href='#g2-103'/> +<use x='266.097' y='179.379' xlink:href='#g2-49'/> +<use x='268.743' y='179.379' xlink:href='#g2-48'/> +<use x='271.389' y='179.379' xlink:href='#g2-46'/> +<use x='272.859' y='179.379' xlink:href='#g2-48'/> +<use x='275.506' y='179.379' xlink:href='#g2-46'/> +<use x='276.976' y='179.379' xlink:href='#g2-48'/> +<use x='168.285' y='185.357' xlink:href='#g2-55'/> +<use x='170.931' y='185.357' xlink:href='#g2-50'/> +<use x='175.342' y='185.357' xlink:href='#g2-108'/> +<use x='176.604' y='185.357' xlink:href='#g2-111'/> +<use x='179.251' y='185.357' xlink:href='#g2-103'/> +<use x='181.897' y='185.357' xlink:href='#g2-105'/> +<use x='183.16' y='185.357' xlink:href='#g2-99'/> +<use x='185.512' y='185.357' xlink:href='#g2-97'/> +<use x='188.055' y='185.357' xlink:href='#g2-108'/> +<use x='191.082' y='185.357' xlink:href='#g2-99'/> +<use x='193.434' y='185.357' xlink:href='#g2-111'/> +<use x='195.933' y='185.357' xlink:href='#g2-114'/> +<use x='197.741' y='185.357' xlink:href='#g2-101'/> +<use x='200.093' y='185.357' xlink:href='#g2-115'/> +<use x='203.886' y='185.357' xlink:href='#g2-111'/> +<use x='206.533' y='185.357' xlink:href='#g2-110'/> +<use x='211.03' y='185.357' xlink:href='#g2-50'/> +<use x='215.44' y='185.357' xlink:href='#g2-110'/> +<use x='218.173' y='185.357' xlink:href='#g2-117'/> +<use x='220.906' y='185.357' xlink:href='#g2-109'/> +<use x='225.109' y='185.357' xlink:href='#g2-97'/> +<use x='229.416' y='185.357' xlink:href='#g2-110'/> +<use x='232.149' y='185.357' xlink:href='#g2-111'/> +<use x='234.942' y='185.357' xlink:href='#g2-100'/> +<use x='237.675' y='185.357' xlink:href='#g2-101'/> +<use x='240.027' y='185.357' xlink:href='#g2-115'/> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-48'/> +<use x='173.578' y='191.334' xlink:href='#g2-50'/> +<use x='176.224' y='191.334' xlink:href='#g2-49'/> +<use x='178.87' y='191.334' xlink:href='#g2-45'/> +<use x='180.635' y='191.334' xlink:href='#g2-48'/> +<use x='183.281' y='191.334' xlink:href='#g2-49'/> +<use x='185.927' y='191.334' xlink:href='#g2-45'/> +<use x='187.692' y='191.334' xlink:href='#g2-51'/> +<use x='190.338' y='191.334' xlink:href='#g2-48'/> +<use x='192.984' y='191.334' xlink:href='#g2-41'/> +</g> +<g transform='matrix(0 -1 1 0 -47.954 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 10.715 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 69.384 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 128.053 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 186.722 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 245.391 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -42.724 346.568)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 15.945 346.703)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 74.614 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 133.283 344.086)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 191.952 340.73)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 250.621 349.32)'> +<use x='168.285' y='191.334' xlink:href='#g2-48'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-57'/> +<use x='175.048' y='191.334' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -37.493 346.703)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 21.176 333.952)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 79.845 299.393)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-55'/> +<use x='175.048' y='191.334' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 138.514 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-49'/> +<use x='176.558' y='191.334' xlink:href='#g2-53'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-49'/> +<use x='183.321' y='191.334' xlink:href='#g2-56'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 197.183 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-51'/> +<use x='176.558' y='191.334' xlink:href='#g2-56'/> +<use x='179.205' y='191.334' xlink:href='#g2-48'/> +<use x='181.851' y='191.334' xlink:href='#g2-46'/> +<use x='183.321' y='191.334' xlink:href='#g2-49'/> +<use x='185.968' y='191.334' xlink:href='#g2-57'/> +<use x='188.614' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 255.852 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-49'/> +<use x='176.558' y='191.334' xlink:href='#g2-55'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-48'/> +<use x='183.321' y='191.334' xlink:href='#g2-55'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -32.263 342.005)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 26.406 342.542)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 85.075 293.756)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-55'/> +<use x='175.048' y='191.334' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 143.744 288.186)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-56'/> +<use x='175.048' y='191.334' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 202.413 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-49'/> +<use x='176.558' y='191.334' xlink:href='#g2-49'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-54'/> +<use x='183.321' y='191.334' xlink:href='#g2-55'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 261.082 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-49'/> +<use x='176.558' y='191.334' xlink:href='#g2-55'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-50'/> +<use x='183.321' y='191.334' xlink:href='#g2-53'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -27.032 324.222)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-51'/> +<use x='175.048' y='191.334' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 31.637 325.497)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-51'/> +<use x='175.048' y='191.334' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 90.306 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-53'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-50'/> +<use x='180.675' y='191.334' xlink:href='#g2-57'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 148.975 274.228)'> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 207.644 248.929)'> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-52'/> +<use x='175.048' y='191.334' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 266.313 346.904)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -21.802 334.02)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 36.867 343.146)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 95.536 313.351)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-53'/> +<use x='175.048' y='191.334' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 154.205 324.558)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-51'/> +<use x='175.048' y='191.334' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 212.874 354.42)'> +<use x='168.285' y='191.334' xlink:href='#g2-48'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-56'/> +<use x='175.048' y='191.334' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 271.543 351.668)'> +<use x='168.285' y='191.334' xlink:href='#g2-48'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-57'/> +<use x='175.048' y='191.334' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 -16.571 343.012)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 42.098 341.133)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-48'/> +<use x='175.048' y='191.334' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 100.767 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-55'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-50'/> +<use x='180.675' y='191.334' xlink:href='#g2-53'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 159.436 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-51'/> +<use x='176.558' y='191.334' xlink:href='#g2-54'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-54'/> +<use x='183.321' y='191.334' xlink:href='#g2-53'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 218.105 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-51'/> +<use x='176.558' y='191.334' xlink:href='#g2-56'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-53'/> +<use x='183.321' y='191.334' xlink:href='#g2-51'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 276.774 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-49'/> +<use x='176.558' y='191.334' xlink:href='#g2-50'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-56'/> +<use x='183.321' y='191.334' xlink:href='#g2-50'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -11.341 316.908)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-52'/> +<use x='175.048' y='191.334' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 47.328 338.247)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 105.997 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-55'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-49'/> +<use x='180.675' y='191.334' xlink:href='#g2-50'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 164.666 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-55'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-50'/> +<use x='180.675' y='191.334' xlink:href='#g2-53'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 223.335 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-53'/> +<use x='176.558' y='191.334' xlink:href='#g2-55'/> +<use x='179.205' y='191.334' xlink:href='#g2-46'/> +<use x='180.675' y='191.334' xlink:href='#g2-52'/> +<use x='183.321' y='191.334' xlink:href='#g2-53'/> +<use x='185.968' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 282.004 351.668)'> +<use x='168.285' y='191.334' xlink:href='#g2-48'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-57'/> +<use x='175.048' y='191.334' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 -6.111 329.993)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-50'/> +<use x='175.048' y='191.334' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 52.558 331.067)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-50'/> +<use x='175.048' y='191.334' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 111.227 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-53'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-52'/> +<use x='180.675' y='191.334' xlink:href='#g2-54'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 169.896 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-52'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-50'/> +<use x='180.675' y='191.334' xlink:href='#g2-54'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 228.565 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-53'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-53'/> +<use x='180.675' y='191.334' xlink:href='#g2-54'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 287.234 246.245)'> +<use x='163.396' y='191.334' xlink:href='#g4-1'/> +<use x='166.901' y='191.334' xlink:href='#g4-1'/> +<use x='170.407' y='191.334' xlink:href='#g4-1'/> +<use x='173.912' y='191.334' xlink:href='#g2-54'/> +<use x='176.558' y='191.334' xlink:href='#g2-46'/> +<use x='178.029' y='191.334' xlink:href='#g2-48'/> +<use x='180.675' y='191.334' xlink:href='#g2-55'/> +<use x='183.321' y='191.334' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -.88 337.643)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 57.789 338.247)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 116.458 254.633)'> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-51'/> +<use x='175.048' y='191.334' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 175.127 288.186)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-56'/> +<use x='175.048' y='191.334' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 233.796 271.544)'> +<use x='168.285' y='191.334' xlink:href='#g2-50'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 292.465 337.308)'> +<use x='168.285' y='191.334' xlink:href='#g2-49'/> +<use x='170.931' y='191.334' xlink:href='#g2-46'/> +<use x='172.401' y='191.334' xlink:href='#g2-49'/> +<use x='175.048' y='191.334' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 -78.176 391.591)'> +<use x='168.285' y='191.334' xlink:href='#g1-82'/> +<use x='174.255' y='191.334' xlink:href='#g1-101'/> +<use x='178.351' y='191.334' xlink:href='#g1-108'/> +<use x='180.551' y='191.334' xlink:href='#g1-97'/> +<use x='184.979' y='191.334' xlink:href='#g1-116'/> +<use x='188.307' y='191.334' xlink:href='#g1-105'/> +<use x='190.507' y='191.334' xlink:href='#g1-118'/> +<use x='194.755' y='191.334' xlink:href='#g1-101'/> +<use x='201.922' y='191.334' xlink:href='#g1-116'/> +<use x='205.25' y='191.334' xlink:href='#g1-105'/> +<use x='207.45' y='191.334' xlink:href='#g1-109'/> +<use x='214.77' y='191.334' xlink:href='#g1-101'/> +<use x='221.937' y='191.334' xlink:href='#g3-40'/> +<use x='225.231' y='191.334' xlink:href='#g3-108'/> +<use x='227.251' y='191.334' xlink:href='#g3-111'/> +<use x='231.25' y='191.334' xlink:href='#g3-119'/> +<use x='236.799' y='191.334' xlink:href='#g3-101'/> +<use x='240.562' y='191.334' xlink:href='#g3-114'/> +<use x='246.277' y='191.334' xlink:href='#g3-105'/> +<use x='248.297' y='191.334' xlink:href='#g3-115'/> +<use x='254.366' y='191.334' xlink:href='#g3-98'/> +<use x='258.974' y='191.334' xlink:href='#g3-101'/> +<use x='262.738' y='191.334' xlink:href='#g3-116'/> +<use x='265.796' y='191.334' xlink:href='#g3-116'/> +<use x='268.854' y='191.334' xlink:href='#g3-101'/> +<use x='272.618' y='191.334' xlink:href='#g3-114'/> +<use x='275.51' y='191.334' xlink:href='#g3-41'/> +</g> +<path d='M136.149 312.324H346.746V282.324H136.149Z' fill='#fff'/> +<path d='M136.149 312.324H346.746V282.324H136.149Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='#933'/> +<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.354 114.479)'> +<use x='191.843' y='178.327' xlink:href='#g3-120'/> +<use x='195.745' y='178.327' xlink:href='#g3-109'/> +<use x='202.47' y='178.327' xlink:href='#g3-105'/> +<use x='204.49' y='178.327' xlink:href='#g3-58'/> +<use x='206.843' y='178.327' xlink:href='#g0-57'/> +<use x='210.548' y='178.327' xlink:href='#g0-52'/> +</g> +<path d='M177.086 292.816H180.074V284.844H177.086ZM183.063 292.816H186.055V286.836H183.063Z' fill='#bf8080'/> +<path d='M177.086 292.816H180.074V284.844H177.086ZM183.063 292.816H186.055V286.836H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -38.403 114.479)'> +<use x='233.123' y='178.327' xlink:href='#g3-109'/> +<use x='239.848' y='178.327' xlink:href='#g3-105'/> +<use x='241.869' y='178.327' xlink:href='#g3-58'/> +<use x='244.221' y='178.327' xlink:href='#g0-56'/> +<use x='247.926' y='178.327' xlink:href='#g0-57'/> +</g> +<path d='M221.895 292.816H224.883V284.844H221.895ZM227.875 292.816H230.863V286.836H227.875Z' fill='#8080bf'/> +<path d='M221.895 292.816H224.883V284.844H221.895ZM227.875 292.816H230.863V286.836H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.441 114.036)'> +<use x='277.134' y='178.327' xlink:href='#g3-116'/> +<use x='280.192' y='178.327' xlink:href='#g3-99'/> +<use x='283.956' y='178.327' xlink:href='#g3-58'/> +<use x='286.308' y='178.327' xlink:href='#g0-53'/> +<use x='290.013' y='178.327' xlink:href='#g0-56'/> +</g> +<path d='M265.109 292.816H268.098V284.844H265.109ZM271.086 292.816H274.074V286.836H271.086Z' fill='#ffb733'/> +<path d='M265.109 292.816H268.098V284.844H265.109ZM271.086 292.816H274.074V286.836H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.04 114.479)'> +<use x='319.615' y='178.327' xlink:href='#g3-106'/> +<use x='321.871' y='178.327' xlink:href='#g3-101'/> +<use x='325.634' y='178.327' xlink:href='#g3-58'/> +<use x='327.987' y='178.327' xlink:href='#g0-53'/> +<use x='331.691' y='178.327' xlink:href='#g0-56'/> +</g> +<path d='M306.859 292.816H309.848V284.844H306.859ZM312.836 292.816H315.824V286.836H312.836Z' fill='#bf80bf'/> +<path d='M306.859 292.816H309.848V284.844H306.859ZM312.836 292.816H315.824V286.836H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -39.932 114.515)'> +<use x='359.038' y='178.327' xlink:href='#g3-116'/> +<use x='362.096' y='178.327' xlink:href='#g3-98'/> +<use x='366.469' y='178.327' xlink:href='#g3-98'/> +<use x='370.842' y='178.327' xlink:href='#g3-58'/> +<use x='373.194' y='178.327' xlink:href='#g0-53'/> +<use x='376.899' y='178.327' xlink:href='#g0-48'/> +</g> +<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='#c96'/> +<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.662 114.036)'> +<use x='191.843' y='191.334' xlink:href='#g3-114'/> +<use x='194.735' y='191.334' xlink:href='#g3-112'/> +<use x='199.108' y='191.334' xlink:href='#g3-58'/> +<use x='201.46' y='191.334' xlink:href='#g0-55'/> +<use x='205.165' y='191.334' xlink:href='#g0-53'/> +</g> +<path d='M177.086 305.82H180.074V297.852H177.086ZM183.063 305.82H186.055V299.844H183.063Z' fill='#80bf80'/> +<path d='M177.086 305.82H180.074V297.852H177.086ZM183.063 305.82H186.055V299.844H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.882 114.515)'> +<use x='233.123' y='191.334' xlink:href='#g3-104'/> +<use x='237.496' y='191.334' xlink:href='#g3-111'/> +<use x='241.73' y='191.334' xlink:href='#g3-97'/> +<use x='245.563' y='191.334' xlink:href='#g3-114'/> +<use x='248.455' y='191.334' xlink:href='#g3-100'/> +<use x='252.828' y='191.334' xlink:href='#g3-58'/> +<use x='255.18' y='191.334' xlink:href='#g0-51'/> +<use x='258.885' y='191.334' xlink:href='#g0-56'/> +</g> +<path d='M221.895 305.82H224.883V297.852H221.895ZM227.875 305.82H230.863V299.844H227.875Z' fill='#bfbf80'/> +<path d='M221.895 305.82H224.883V297.852H221.895ZM227.875 305.82H230.863V299.844H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.084 114.515)'> +<use x='277.134' y='191.334' xlink:href='#g3-109'/> +<use x='283.859' y='191.334' xlink:href='#g3-101'/> +<use x='287.622' y='191.334' xlink:href='#g3-115'/> +<use x='290.869' y='191.334' xlink:href='#g3-104'/> +<use x='295.241' y='191.334' xlink:href='#g3-58'/> +<use x='297.593' y='191.334' xlink:href='#g0-51'/> +<use x='301.298' y='191.334' xlink:href='#g0-54'/> +</g> +<path d='M265.109 305.82H268.098V297.852H265.109ZM271.086 305.82H274.074V299.844H271.086Z' fill='#399'/> +<path d='M265.109 305.82H268.098V297.852H265.109ZM271.086 305.82H274.074V299.844H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -42.353 114.515)'> +<use x='319.615' y='191.334' xlink:href='#g3-103'/> +<use x='323.849' y='191.334' xlink:href='#g3-108'/> +<use x='325.869' y='191.334' xlink:href='#g3-105'/> +<use x='327.89' y='191.334' xlink:href='#g3-98'/> +<use x='332.498' y='191.334' xlink:href='#g3-99'/> +<use x='336.261' y='191.334' xlink:href='#g3-58'/> +<use x='338.614' y='191.334' xlink:href='#g0-52'/> +<use x='342.318' y='191.334' xlink:href='#g0-54'/> +</g> +<path d='M306.859 305.82H309.848V297.852H306.859ZM312.836 305.82H315.824V299.844H312.836Z' fill='#d9b3b3'/> +<path d='M306.859 305.82H309.848V297.852H306.859ZM312.836 305.82H315.824V299.844H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.026 114.479)'> +<use x='359.038' y='191.334' xlink:href='#g3-115'/> +<use x='362.285' y='191.334' xlink:href='#g3-109'/> +<use x='369.009' y='191.334' xlink:href='#g3-105'/> +<use x='371.03' y='191.334' xlink:href='#g3-58'/> +<use x='373.382' y='191.334' xlink:href='#g0-53'/> +<use x='377.087' y='191.334' xlink:href='#g0-57'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg new file mode 100644 index 0000000..6cd36aa --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg @@ -0,0 +1,836 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.628pt' height='207.789pt' viewBox='52.934 54.993 381.628 207.789'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip1'> +<path d='M82.148 246.637H434.164V78.871H82.148Z'/> +</clipPath> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-114' d='M1.462-1.91C1.462-2.851 2.197-3.425 3.013-3.434V-4.08C2.367-4.071 1.775-3.748 1.408-3.219V-4.035H.744V0H1.462V-1.91Z'/> +<path id='g1-115' d='M3.165-3.847C2.609-4.098 2.197-4.133 1.829-4.133C1.623-4.133 .305-4.133 .305-2.95C.305-2.52 .565-2.251 .664-2.152C1.004-1.856 1.237-1.811 1.847-1.695C2.134-1.641 2.645-1.542 2.645-1.085C2.645-.502 1.919-.502 1.802-.502C1.273-.502 .762-.681 .377-.95L.26-.296C.798-.009 1.345 .099 1.802 .099C2.385 .099 3.318-.09 3.318-1.157C3.318-1.47 3.192-1.784 2.878-2.053C2.573-2.313 2.304-2.367 1.748-2.475C1.426-2.537 .977-2.618 .977-3.04C.977-3.569 1.614-3.569 1.748-3.569C2.403-3.569 2.789-3.362 3.049-3.219L3.165-3.847Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +</defs> +<g id='page1'> +<path d='M140.82 255.492V246.637M199.488 255.492V246.637M258.156 255.492V246.637M316.824 255.492V246.637M375.496 255.492V246.637M140.82 70.016V78.871M199.488 70.016V78.871M258.156 70.016V78.871M316.824 70.016V78.871M375.496 70.016V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M111.484 250.887V246.637M170.152 250.887V246.637M228.824 250.887V246.637M287.492 250.887V246.637M346.16 250.887V246.637M404.828 250.887V246.637M111.484 74.617V78.871M170.152 74.617V78.871M228.824 74.617V78.871M287.492 74.617V78.871M346.16 74.617V78.871M404.828 74.617V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 246.637H86.402M82.148 213.082H86.402M82.148 179.531H86.402M82.148 145.977H86.402M82.148 112.426H86.402M82.148 78.871H86.402M434.164 246.637H429.91M434.164 213.082H429.91M434.164 179.531H429.91M434.164 145.977H429.91M434.164 112.426H429.91M434.164 78.871H429.91' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 246.637V78.871H434.164V246.637H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -11.54 34.954)'> +<use x='114.487' y='226.079' xlink:href='#g3-99'/> +<use x='118.25' y='226.079' xlink:href='#g3-102'/> +<use x='120.838' y='226.079' xlink:href='#g3-114'/> +<use x='123.73' y='226.079' xlink:href='#g3-97'/> +<use x='127.798' y='226.079' xlink:href='#g3-99'/> +</g> +<g transform='matrix(1 0 0 1 45.565 34.954)'> +<use x='114.487' y='226.079' xlink:href='#g3-108'/> +<use x='116.507' y='226.079' xlink:href='#g3-101'/> +<use x='120.271' y='226.079' xlink:href='#g3-97'/> +<use x='124.339' y='226.079' xlink:href='#g3-110'/> +<use x='128.711' y='226.079' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 106.188 34.954)'> +<use x='114.487' y='226.079' xlink:href='#g3-114'/> +<use x='117.379' y='226.079' xlink:href='#g3-101'/> +<use x='121.142' y='226.079' xlink:href='#g3-100'/> +<use x='125.515' y='226.079' xlink:href='#g3-105'/> +<use x='127.535' y='226.079' xlink:href='#g3-115'/> +</g> +<g transform='matrix(1 0 0 1 159.716 34.954)'> +<use x='114.487' y='226.079' xlink:href='#g3-108'/> +<use x='116.507' y='226.079' xlink:href='#g3-97'/> +<use x='120.34' y='226.079' xlink:href='#g3-114'/> +<use x='123.232' y='226.079' xlink:href='#g3-115'/> +<use x='126.478' y='226.079' xlink:href='#g3-111'/> +<use x='130.712' y='226.079' xlink:href='#g3-110'/> +<use x='135.085' y='226.079' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 215.596 34.954)'> +<use x='114.487' y='226.079' xlink:href='#g3-109'/> +<use x='121.211' y='226.079' xlink:href='#g3-115'/> +<use x='124.458' y='226.079' xlink:href='#g3-116'/> +<use x='127.516' y='226.079' xlink:href='#g3-114'/> +<use x='130.408' y='226.079' xlink:href='#g3-101'/> +<use x='134.171' y='226.079' xlink:href='#g3-115'/> +<use x='137.418' y='226.079' xlink:href='#g3-115'/> +<use x='140.664' y='226.079' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 277.158 34.954)'> +<use x='114.487' y='226.079' xlink:href='#g3-114'/> +<use x='117.379' y='226.079' xlink:href='#g3-112'/> +<use x='121.751' y='226.079' xlink:href='#g3-116'/> +<use x='124.809' y='226.079' xlink:href='#g3-101'/> +<use x='128.573' y='226.079' xlink:href='#g3-115'/> +<use x='131.819' y='226.079' xlink:href='#g3-116'/> +<use x='134.877' y='226.079' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 22.192)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -11.361)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -44.915)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -78.468)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -112.021)'> +<use x='114.487' y='226.079' xlink:href='#g2-50'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -145.574)'> +<use x='114.487' y='226.079' xlink:href='#g2-50'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-120'/> +</g> +<path d='M82.148 179.531H434.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M86.328 246.637H89.566V179.531H86.328ZM144.996 246.637H148.234V179.531H144.996ZM203.668 246.637H206.902V179.531H203.668ZM262.336 246.637H265.574V179.531H262.336ZM321.004 246.637H324.242V179.531H321.004ZM379.672 246.637H382.91V179.531H379.672Z' fill='#fff' clip-path='url(#clip1)'/> +<path d='M86.328 246.637H89.566V179.531H86.328ZM144.996 246.637H148.234V179.531H144.996ZM203.668 246.637H206.902V179.531H203.668ZM262.336 246.637H265.574V179.531H262.336ZM321.004 246.637H324.242V179.531H321.004ZM379.672 246.637H382.91V179.531H379.672Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M87.949 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M85.953 179.531H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M87.949 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M85.953 179.531H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M146.617 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M144.625 179.531H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M146.617 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M144.625 179.531H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M205.285 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M203.293 179.531H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M205.285 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M203.293 179.531H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M263.953 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M261.961 179.531H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M263.953 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M261.961 179.531H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M322.625 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M320.629 179.531H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M322.625 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M320.629 179.531H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M381.293 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M379.301 179.531H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M381.293 179.531' fill='#fff' clip-path='url(#clip1)'/> +<path d='M379.301 179.531H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M91.559 246.637H94.797V180.336H91.559ZM150.227 246.637H153.465V177.449H150.227ZM208.899 246.637H212.133V179.598H208.899ZM267.567 246.637H270.805V186.441H267.567ZM326.234 246.637H329.473V78.871H326.234ZM384.902 246.637H388.141V162.754H384.902Z' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M91.559 246.637H94.797V180.336H91.559ZM150.227 246.637H153.465V177.449H150.227ZM208.899 246.637H212.133V179.598H208.899ZM267.567 246.637H270.805V186.441H267.567ZM326.234 246.637H329.473V78.871H326.234ZM384.902 246.637H388.141V162.754H384.902Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M93.18 180.336' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M91.184 180.336H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M93.18 180.336' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M91.184 180.336H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M151.848 177.449' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M149.855 177.45H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M151.848 177.449' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M149.855 177.45H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M210.516 179.598' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M208.523 179.598H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M210.516 179.598' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M208.523 179.598H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M269.184 186.441' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M267.191 186.442H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M269.184 186.441' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M267.191 186.442H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M327.856 78.871' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M325.859 78.871H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M327.856 78.871' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M325.859 78.871H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M386.524 162.754' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M384.531 162.753H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M386.524 162.754' fill='#f0e0f0' clip-path='url(#clip1)'/> +<path d='M384.531 162.753H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M96.789 246.637H100.027V87.73H96.789ZM155.457 246.637H158.695V189.262H155.457ZM214.129 246.637H217.363V161.074H214.129ZM272.797 246.637H276.035V221.738H272.797ZM331.465 246.637H334.703V194.965H331.465ZM390.133 246.637H393.371V212.949H390.133Z' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M96.789 246.637H100.027V87.73H96.789ZM155.457 246.637H158.695V189.262H155.457ZM214.129 246.637H217.363V161.074H214.129ZM272.797 246.637H276.035V221.738H272.797ZM331.465 246.637H334.703V194.965H331.465ZM390.133 246.637H393.371V212.949H390.133Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M98.41 87.73' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M96.414 87.73H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M98.41 87.73' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M96.414 87.73H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M157.078 189.262' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M155.086 189.261H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M157.078 189.262' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M155.086 189.261H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M215.746 161.074' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M213.754 161.074H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M215.746 161.074' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M213.754 161.074H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M274.414 221.738' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M272.422 221.739H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M274.414 221.738' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M272.422 221.739H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M333.086 194.965' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M331.09 194.964H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M333.086 194.965' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M331.09 194.964H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M391.754 212.949' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M389.762 212.949H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M391.754 212.949' fill='#e1c2e1' clip-path='url(#clip1)'/> +<path d='M389.762 212.949H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M102.02 246.637H105.258V152.219H102.02ZM160.688 246.637H163.926V180.535H160.688ZM219.359 246.637H222.594V174.766H219.359ZM278.027 246.637H281.266V206.172H278.027ZM336.695 246.637H339.934V192.953H336.695ZM395.363 246.637H398.602V183.223H395.363Z' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M102.02 246.637H105.258V152.219H102.02ZM160.688 246.637H163.926V180.535H160.688ZM219.359 246.637H222.594V174.766H219.359ZM278.027 246.637H281.266V206.172H278.027ZM336.695 246.637H339.934V192.953H336.695ZM395.363 246.637H398.602V183.223H395.363Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M103.641 152.219' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M101.644 152.219H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M103.641 152.219' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M101.644 152.219H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M162.309 180.535' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M160.316 180.536H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M162.309 180.535' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M160.316 180.536H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M220.977 174.766' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M218.984 174.765H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M220.977 174.766' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M218.984 174.765H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M279.645 206.172' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M277.652 206.172H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M279.645 206.172' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M277.652 206.172H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M338.317 192.953' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M336.32 192.953H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M338.317 192.953' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M336.32 192.953H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M396.984 183.223' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M394.992 183.223H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M396.984 183.223' fill='#d1a3d1' clip-path='url(#clip1)'/> +<path d='M394.992 183.223H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M107.25 246.637H110.488V154.5H107.25ZM165.918 246.637H169.156V169.734H165.918ZM224.59 246.637H227.824V134.703H224.59ZM283.258 246.637H286.496V192.281H283.258ZM341.926 246.637H345.164V197.313H341.926ZM400.594 246.637H403.832V195.703H400.594Z' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M107.25 246.637H110.488V154.5H107.25ZM165.918 246.637H169.156V169.734H165.918ZM224.59 246.637H227.824V134.703H224.59ZM283.258 246.637H286.496V192.281H283.258ZM341.926 246.637H345.164V197.313H341.926ZM400.594 246.637H403.832V195.703H400.594Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M108.871 154.5' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M106.875 154.5H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M108.871 154.5' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M106.875 154.5H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M167.539 169.734' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M165.547 169.734H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M167.539 169.734' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M165.547 169.734H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M226.207 134.703' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M224.215 134.703H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M226.207 134.703' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M224.215 134.703H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M284.875 192.281' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M282.883 192.281H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M284.875 192.281' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M282.883 192.281H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M343.547 197.313' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M341.551 197.312H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M343.547 197.313' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M341.551 197.312H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M402.215 195.703' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M400.223 195.704H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M402.215 195.703' fill='#c285c2' clip-path='url(#clip1)'/> +<path d='M400.223 195.704H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M112.481 246.637H115.719V167.922H112.481ZM171.149 246.637H174.387V172.148H171.149ZM229.82 246.637H233.055V160.07H229.82ZM288.488 246.637H291.727V196.305H288.488ZM347.156 246.637H350.395V78.871H347.156ZM405.824 246.637H409.063V146.379H405.824Z' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M112.481 246.637H115.719V167.922H112.481ZM171.149 246.637H174.387V172.148H171.149ZM229.82 246.637H233.055V160.07H229.82ZM288.488 246.637H291.727V196.305H288.488ZM347.156 246.637H350.395V78.871H347.156ZM405.824 246.637H409.063V146.379H405.824Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M114.098 167.922' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M112.105 167.922H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M114.098 167.922' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M112.105 167.922H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M172.77 172.148' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M170.777 172.148H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M172.77 172.148' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M170.777 172.148H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M231.438 160.07' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M229.445 160.07H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M231.438 160.07' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M229.445 160.07H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M290.106 196.305' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M288.113 196.304H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M290.106 196.305' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M288.113 196.304H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M348.777 78.871' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M346.781 78.871H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M348.777 78.871' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M346.781 78.871H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M407.445 146.379' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M405.453 146.379H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M407.445 146.379' fill='#b366b3' clip-path='url(#clip1)'/> +<path d='M405.453 146.379H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M117.711 246.637H120.949V153.223H117.711ZM176.379 246.637H179.617V169.465H176.379ZM235.051 246.637H238.285V174.633H235.051ZM293.719 246.637H296.957V215.766H293.719ZM352.387 246.637H355.625V78.871H352.387ZM411.055 246.637H414.293V191.742H411.055Z' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M117.711 246.637H120.949V153.223H117.711ZM176.379 246.637H179.617V169.465H176.379ZM235.051 246.637H238.285V174.633H235.051ZM293.719 246.637H296.957V215.766H293.719ZM352.387 246.637H355.625V78.871H352.387ZM411.055 246.637H414.293V191.742H411.055Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M119.328 153.223' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M117.336 153.222H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M119.328 153.223' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M117.336 153.222H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M178 169.465' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M176.008 169.465H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M178 169.465' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M176.008 169.465H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M236.668 174.633' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M234.676 174.633H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M236.668 174.633' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M234.676 174.633H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M295.336 215.766' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M293.344 215.765H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M295.336 215.766' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M293.344 215.765H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M354.008 78.871' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M352.012 78.871H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M354.008 78.871' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M352.012 78.871H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M412.676 191.742' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M410.684 191.742H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M412.676 191.742' fill='#a447a4' clip-path='url(#clip1)'/> +<path d='M410.684 191.742H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M122.941 246.637H126.18V177.047H122.941ZM181.609 246.637H184.848V178.457H181.609ZM240.281 246.637H243.516V178.992H240.281ZM298.949 246.637H302.188V221.875H298.949ZM357.617 246.637H360.856V78.871H357.617ZM416.285 246.637H419.524V157.25H416.285Z' fill='#942994' clip-path='url(#clip1)'/> +<path d='M122.941 246.637H126.18V177.047H122.941ZM181.609 246.637H184.848V178.457H181.609ZM240.281 246.637H243.516V178.992H240.281ZM298.949 246.637H302.188V221.875H298.949ZM357.617 246.637H360.856V78.871H357.617ZM416.285 246.637H419.524V157.25H416.285Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M124.559 177.047' fill='#942994' clip-path='url(#clip1)'/> +<path d='M122.566 177.047H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M124.559 177.047' fill='#942994' clip-path='url(#clip1)'/> +<path d='M122.566 177.047H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M183.231 178.457' fill='#942994' clip-path='url(#clip1)'/> +<path d='M181.238 178.457H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M183.231 178.457' fill='#942994' clip-path='url(#clip1)'/> +<path d='M181.238 178.457H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M241.899 178.992' fill='#942994' clip-path='url(#clip1)'/> +<path d='M239.906 178.992H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M241.899 178.992' fill='#942994' clip-path='url(#clip1)'/> +<path d='M239.906 178.992H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M300.567 221.875' fill='#942994' clip-path='url(#clip1)'/> +<path d='M298.574 221.875H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M300.567 221.875' fill='#942994' clip-path='url(#clip1)'/> +<path d='M298.574 221.875H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M359.238 78.871' fill='#942994' clip-path='url(#clip1)'/> +<path d='M357.242 78.871H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M359.238 78.871' fill='#942994' clip-path='url(#clip1)'/> +<path d='M357.242 78.871H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M417.906 157.25' fill='#942994' clip-path='url(#clip1)'/> +<path d='M415.914 157.25H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M417.906 157.25' fill='#942994' clip-path='url(#clip1)'/> +<path d='M415.914 157.25H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M128.172 246.637H131.41V182.414H128.172ZM186.84 246.637H190.078V170.805H186.84ZM245.512 246.637H248.746V179.059H245.512ZM304.18 246.637H307.418V207.176H304.18ZM362.848 246.637H366.086V153.629H362.848ZM421.516 246.637H424.754V207.313H421.516Z' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M128.172 246.637H131.41V182.414H128.172ZM186.84 246.637H190.078V170.805H186.84ZM245.512 246.637H248.746V179.059H245.512ZM304.18 246.637H307.418V207.176H304.18ZM362.848 246.637H366.086V153.629H362.848ZM421.516 246.637H424.754V207.313H421.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M129.789 182.414' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M127.797 182.415H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M129.789 182.414' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M127.797 182.415H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M188.461 170.805' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M186.469 170.805H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M188.461 170.805' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M186.469 170.805H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M247.129 179.059' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M245.137 179.058H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M247.129 179.059' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M245.137 179.058H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M305.797 207.176' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M303.804 207.176H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M305.797 207.176' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M303.804 207.176H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M364.469 153.629' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M362.473 153.629H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M364.469 153.629' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M362.473 153.629H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M423.137 207.313' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M421.144 207.313H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M423.137 207.313' fill='#850a85' clip-path='url(#clip1)'/> +<path d='M421.144 207.313H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M133.402 246.637H136.641V178.055H133.402ZM192.07 246.637H195.309V164.969H192.07ZM250.742 246.637H253.977V175.703H250.742ZM309.41 246.637H312.649V184.027H309.41ZM368.078 246.637H371.317V99.809H368.078ZM426.746 246.637H429.984V143.023H426.746Z' fill='#760076' clip-path='url(#clip1)'/> +<path d='M133.402 246.637H136.641V178.055H133.402ZM192.07 246.637H195.309V164.969H192.07ZM250.742 246.637H253.977V175.703H250.742ZM309.41 246.637H312.649V184.027H309.41ZM368.078 246.637H371.317V99.809H368.078ZM426.746 246.637H429.984V143.023H426.746Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M135.02 178.055' fill='#760076' clip-path='url(#clip1)'/> +<path d='M133.027 178.055H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M135.02 178.055' fill='#760076' clip-path='url(#clip1)'/> +<path d='M133.027 178.055H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M193.692 164.969' fill='#760076' clip-path='url(#clip1)'/> +<path d='M191.699 164.969H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M193.692 164.969' fill='#760076' clip-path='url(#clip1)'/> +<path d='M191.699 164.969H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M252.359 175.703' fill='#760076' clip-path='url(#clip1)'/> +<path d='M250.367 175.703H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M252.359 175.703' fill='#760076' clip-path='url(#clip1)'/> +<path d='M250.367 175.703H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M311.027 184.027' fill='#760076' clip-path='url(#clip1)'/> +<path d='M309.035 184.027H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M311.027 184.027' fill='#760076' clip-path='url(#clip1)'/> +<path d='M309.035 184.027H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M369.699 99.809' fill='#760076' clip-path='url(#clip1)'/> +<path d='M367.703 99.809H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M369.699 99.809' fill='#760076' clip-path='url(#clip1)'/> +<path d='M367.703 99.809H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M428.367 143.023' fill='#760076' clip-path='url(#clip1)'/> +<path d='M426.375 143.023H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M428.367 143.023' fill='#760076' clip-path='url(#clip1)'/> +<path d='M426.375 143.023H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<g transform='matrix(0 -1 1 0 -136.497 287.813)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -77.828 287.813)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -19.159 287.813)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 39.51 287.813)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 98.179 287.813)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 156.848 287.813)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -131.267 288.618)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-57'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -72.598 285.733)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 -13.929 287.88)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 44.74 294.725)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-57'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 103.409 187.154)'> +<use x='109.598' y='226.079' xlink:href='#g4-1'/> +<use x='113.103' y='226.079' xlink:href='#g4-1'/> +<use x='116.608' y='226.079' xlink:href='#g4-1'/> +<use x='120.114' y='226.079' xlink:href='#g2-51'/> +<use x='122.76' y='226.079' xlink:href='#g2-46'/> +<use x='124.23' y='226.079' xlink:href='#g2-49'/> +<use x='126.877' y='226.079' xlink:href='#g2-55'/> +<use x='129.523' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 162.078 271.036)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-50'/> +<use x='121.25' y='226.079' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -126.036 196.012)'> +<use x='114.487' y='226.079' xlink:href='#g2-50'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 -67.367 297.543)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-56'/> +<use x='121.25' y='226.079' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -8.698 269.359)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-50'/> +<use x='121.25' y='226.079' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 49.971 330.023)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 108.64 303.247)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-55'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 167.309 321.232)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -120.806 260.501)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-52'/> +<use x='121.25' y='226.079' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 -62.137 288.819)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-57'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -3.468 283.048)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 55.201 314.454)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-54'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 113.87 301.234)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-56'/> +<use x='121.25' y='226.079' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 172.539 291.504)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-57'/> +<use x='121.25' y='226.079' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 -115.575 262.782)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 -56.906 278.015)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-49'/> +<use x='121.25' y='226.079' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 1.763 242.986)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-54'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 60.432 300.563)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-56'/> +<use x='121.25' y='226.079' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 119.101 305.596)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-55'/> +<use x='121.25' y='226.079' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 177.77 303.985)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-55'/> +<use x='121.25' y='226.079' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -110.345 276.204)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-49'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 -51.676 280.431)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-49'/> +<use x='121.25' y='226.079' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 6.993 268.352)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-50'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 65.662 304.589)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-55'/> +<use x='121.25' y='226.079' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 124.331 187.154)'> +<use x='109.598' y='226.079' xlink:href='#g4-1'/> +<use x='113.103' y='226.079' xlink:href='#g4-1'/> +<use x='116.608' y='226.079' xlink:href='#g4-1'/> +<use x='120.114' y='226.079' xlink:href='#g2-53'/> +<use x='122.76' y='226.079' xlink:href='#g2-46'/> +<use x='124.23' y='226.079' xlink:href='#g2-51'/> +<use x='126.877' y='226.079' xlink:href='#g2-50'/> +<use x='129.523' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 183 254.663)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-52'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -105.114 261.507)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -46.445 277.747)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-49'/> +<use x='121.25' y='226.079' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 12.224 282.914)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 70.893 324.05)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-52'/> +<use x='121.25' y='226.079' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 129.562 187.154)'> +<use x='109.598' y='226.079' xlink:href='#g4-1'/> +<use x='113.103' y='226.079' xlink:href='#g4-1'/> +<use x='116.608' y='226.079' xlink:href='#g4-1'/> +<use x='120.114' y='226.079' xlink:href='#g2-50'/> +<use x='122.76' y='226.079' xlink:href='#g2-46'/> +<use x='124.23' y='226.079' xlink:href='#g2-56'/> +<use x='126.877' y='226.079' xlink:href='#g2-53'/> +<use x='129.523' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 188.231 300.026)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-56'/> +<use x='121.25' y='226.079' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -99.884 285.33)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 -41.215 286.739)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 17.454 287.276)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 76.123 330.157)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 134.792 187.154)'> +<use x='109.598' y='226.079' xlink:href='#g4-1'/> +<use x='113.103' y='226.079' xlink:href='#g4-1'/> +<use x='116.608' y='226.079' xlink:href='#g4-1'/> +<use x='120.114' y='226.079' xlink:href='#g2-52'/> +<use x='122.76' y='226.079' xlink:href='#g2-46'/> +<use x='124.23' y='226.079' xlink:href='#g2-50'/> +<use x='126.877' y='226.079' xlink:href='#g2-51'/> +<use x='129.523' y='226.079' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 193.461 265.534)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 -94.654 290.698)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-57'/> +<use x='121.25' y='226.079' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -35.985 279.089)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-49'/> +<use x='121.25' y='226.079' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 22.684 287.343)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 81.353 315.461)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 140.022 261.91)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-51'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 198.691 315.595)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -89.423 286.337)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -30.754 273.251)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-50'/> +<use x='121.25' y='226.079' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 27.915 283.988)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-48'/> +<use x='121.25' y='226.079' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 86.584 292.309)'> +<use x='114.487' y='226.079' xlink:href='#g2-48'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-57'/> +<use x='121.25' y='226.079' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 145.253 208.091)'> +<use x='114.487' y='226.079' xlink:href='#g2-50'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-49'/> +<use x='121.25' y='226.079' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 203.922 251.307)'> +<use x='114.487' y='226.079' xlink:href='#g2-49'/> +<use x='117.133' y='226.079' xlink:href='#g2-46'/> +<use x='118.603' y='226.079' xlink:href='#g2-53'/> +<use x='121.25' y='226.079' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 -166.719 329.135)'> +<use x='114.487' y='226.079' xlink:href='#g1-82'/> +<use x='120.457' y='226.079' xlink:href='#g1-101'/> +<use x='124.553' y='226.079' xlink:href='#g1-108'/> +<use x='126.753' y='226.079' xlink:href='#g1-97'/> +<use x='131.181' y='226.079' xlink:href='#g1-116'/> +<use x='134.509' y='226.079' xlink:href='#g1-105'/> +<use x='136.709' y='226.079' xlink:href='#g1-118'/> +<use x='140.957' y='226.079' xlink:href='#g1-101'/> +<use x='148.124' y='226.079' xlink:href='#g1-114'/> +<use x='151.272' y='226.079' xlink:href='#g1-115'/> +<use x='154.805' y='226.079' xlink:href='#g1-115'/> +<use x='161.409' y='226.079' xlink:href='#g3-40'/> +<use x='164.702' y='226.079' xlink:href='#g3-108'/> +<use x='166.722' y='226.079' xlink:href='#g3-111'/> +<use x='170.721' y='226.079' xlink:href='#g3-119'/> +<use x='176.27' y='226.079' xlink:href='#g3-101'/> +<use x='180.034' y='226.079' xlink:href='#g3-114'/> +<use x='185.749' y='226.079' xlink:href='#g3-105'/> +<use x='187.769' y='226.079' xlink:href='#g3-115'/> +<use x='193.838' y='226.079' xlink:href='#g3-98'/> +<use x='198.446' y='226.079' xlink:href='#g3-101'/> +<use x='202.209' y='226.079' xlink:href='#g3-116'/> +<use x='205.267' y='226.079' xlink:href='#g3-116'/> +<use x='208.325' y='226.079' xlink:href='#g3-101'/> +<use x='212.089' y='226.079' xlink:href='#g3-114'/> +<use x='214.981' y='226.079' xlink:href='#g3-41'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg new file mode 100644 index 0000000..c81072e --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg @@ -0,0 +1,1131 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.627pt' height='254.34pt' viewBox='106.732 54.992 381.627 254.34'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip2'> +<path d='M135.949 246.637H487.961V78.871H135.949Z'/> +</clipPath> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-114' d='M1.462-1.91C1.462-2.851 2.197-3.425 3.013-3.434V-4.08C2.367-4.071 1.775-3.748 1.408-3.219V-4.035H.744V0H1.462V-1.91Z'/> +<path id='g1-115' d='M3.165-3.847C2.609-4.098 2.197-4.133 1.829-4.133C1.623-4.133 .305-4.133 .305-2.95C.305-2.52 .565-2.251 .664-2.152C1.004-1.856 1.237-1.811 1.847-1.695C2.134-1.641 2.645-1.542 2.645-1.085C2.645-.502 1.919-.502 1.802-.502C1.273-.502 .762-.681 .377-.95L.26-.296C.798-.009 1.345 .099 1.802 .099C2.385 .099 3.318-.09 3.318-1.157C3.318-1.47 3.192-1.784 2.878-2.053C2.573-2.313 2.304-2.367 1.748-2.475C1.426-2.537 .977-2.618 .977-3.04C.977-3.569 1.614-3.569 1.748-3.569C2.403-3.569 2.789-3.362 3.049-3.219L3.165-3.847Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/> +<use id='g3-49' xlink:href='#g0-49' transform='scale(1.143)'/> +<use id='g3-54' xlink:href='#g0-54' transform='scale(1.143)'/> +<use id='g3-56' xlink:href='#g0-56' transform='scale(1.143)'/> +<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-103' xlink:href='#g0-103' transform='scale(1.143)'/> +<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/> +<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/> +<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/> +<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/> +<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/> +<path id='g0-73' d='M1.381-4.84H.676V0H1.381V-4.84Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-85' d='M4.4-4.84H3.794V-1.625C3.794-.69 3.166-.265 2.566-.265S1.381-.697 1.381-1.618V-4.84H.676V-1.632C.676-.607 1.555 .146 2.559 .146C3.557 .146 4.4-.614 4.4-1.632V-4.84Z'/> +<path id='g0-88' d='M2.755-2.552L4.519-4.84H3.759L2.413-3.055L1.039-4.84H.209L2.071-2.552L.105 0H.865L2.413-2.099L3.996 0H4.826L2.755-2.552Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/> +<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-117' d='M3.243-3.096H2.636V-1.074C2.636-.516 2.162-.342 1.757-.342C1.241-.342 1.186-.481 1.186-.802V-3.096H.579V-.76C.579-.139 .851 .07 1.339 .07C1.625 .07 2.239 .014 2.657-.321V0H3.243V-3.096Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<path id='g4-2' d='M4.13-2.481C4.184-2.535 4.204-2.57 4.204-2.615C4.204-2.69 4.139-2.755 4.065-2.755C4.01-2.755 3.985-2.73 3.93-2.675L2.7-1.445L1.465-2.68C1.41-2.735 1.375-2.755 1.33-2.755C1.255-2.755 1.191-2.69 1.191-2.615C1.191-2.56 1.215-2.535 1.27-2.481L2.501-1.245L1.27-.01C1.215 .045 1.191 .07 1.191 .125C1.191 .199 1.255 .264 1.33 .264C1.385 .264 1.41 .239 1.46 .189L2.695-1.046L3.97 .229C3.995 .249 4.03 .264 4.065 .264C4.139 .264 4.204 .199 4.204 .125C4.204 .095 4.194 .075 4.184 .05C4.164 .02 3.238-.892 2.894-1.245L4.13-2.481Z'/> +<use id='g2-41' xlink:href='#g0-41' transform='scale(.714)'/> +<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/> +<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/> +<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/> +<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/> +<use id='g2-73' xlink:href='#g0-73' transform='scale(.714)'/> +<use id='g2-85' xlink:href='#g0-85' transform='scale(.714)'/> +<use id='g2-88' xlink:href='#g0-88' transform='scale(.714)'/> +<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/> +<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/> +<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/> +<use id='g2-100' xlink:href='#g0-100' transform='scale(.714)'/> +<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/> +<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/> +<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/> +<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/> +<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/> +<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/> +<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/> +<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/> +<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/> +<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/> +<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/> +<use id='g2-117' xlink:href='#g0-117' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/> +</defs> +<g id='page2'> +<path d='M194.617 255.492V246.637M253.285 255.492V246.637M311.953 255.492V246.637M370.625 255.492V246.637M429.293 255.492V246.637M194.617 70.016V78.871M253.285 70.016V78.871M311.953 70.016V78.871M370.625 70.016V78.871M429.293 70.016V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M165.281 250.887V246.637M223.953 250.887V246.637M282.621 250.887V246.637M341.289 250.887V246.637M399.957 250.887V246.637M458.629 250.887V246.637M165.281 74.617V78.871M223.953 74.617V78.871M282.621 74.617V78.871M341.289 74.617V78.871M399.957 74.617V78.871M458.629 74.617V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M135.949 246.637H140.199M135.949 213.082H140.199M135.949 179.531H140.199M135.949 145.976H140.199M135.949 112.426H140.199M135.949 78.871H140.199M487.961 246.637H483.711M487.961 213.082H483.711M487.961 179.531H483.711M487.961 145.976H483.711M487.961 112.426H483.711M487.961 78.871H483.711' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M135.949 246.637V78.871H487.961V246.637H135.949Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -21.265 74.992)'> +<use x='168.285' y='186.041' xlink:href='#g3-97'/> +<use x='172.353' y='186.041' xlink:href='#g3-108'/> +<use x='174.373' y='186.041' xlink:href='#g3-108'/> +<use x='176.393' y='186.041' xlink:href='#g3-111'/> +<use x='180.863' y='186.041' xlink:href='#g3-99'/> +<use x='184.627' y='186.041' xlink:href='#g3-45'/> +<use x='187.449' y='186.041' xlink:href='#g3-116'/> +<use x='190.507' y='186.041' xlink:href='#g3-101'/> +<use x='194.271' y='186.041' xlink:href='#g3-115'/> +<use x='197.517' y='186.041' xlink:href='#g3-116'/> +<use x='200.575' y='186.041' xlink:href='#g3-49'/> +</g> +<g transform='matrix(1 0 0 1 36.532 74.992)'> +<use x='168.285' y='186.041' xlink:href='#g3-97'/> +<use x='172.353' y='186.041' xlink:href='#g3-108'/> +<use x='174.373' y='186.041' xlink:href='#g3-108'/> +<use x='176.393' y='186.041' xlink:href='#g3-111'/> +<use x='180.863' y='186.041' xlink:href='#g3-99'/> +<use x='184.627' y='186.041' xlink:href='#g3-45'/> +<use x='187.449' y='186.041' xlink:href='#g3-116'/> +<use x='190.507' y='186.041' xlink:href='#g3-101'/> +<use x='194.271' y='186.041' xlink:href='#g3-115'/> +<use x='197.517' y='186.041' xlink:href='#g3-116'/> +<use x='200.575' y='186.041' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 94.98 74.992)'> +<use x='168.285' y='186.041' xlink:href='#g3-115'/> +<use x='171.531' y='186.041' xlink:href='#g3-104'/> +<use x='175.904' y='186.041' xlink:href='#g3-54'/> +<use x='180.138' y='186.041' xlink:href='#g3-98'/> +<use x='184.746' y='186.041' xlink:href='#g3-101'/> +<use x='188.509' y='186.041' xlink:href='#g3-110'/> +<use x='192.882' y='186.041' xlink:href='#g3-99'/> +<use x='196.646' y='186.041' xlink:href='#g3-104'/> +<use x='201.018' y='186.041' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 153.649 74.992)'> +<use x='168.285' y='186.041' xlink:href='#g3-115'/> +<use x='171.531' y='186.041' xlink:href='#g3-104'/> +<use x='175.904' y='186.041' xlink:href='#g3-56'/> +<use x='180.138' y='186.041' xlink:href='#g3-98'/> +<use x='184.746' y='186.041' xlink:href='#g3-101'/> +<use x='188.509' y='186.041' xlink:href='#g3-110'/> +<use x='192.882' y='186.041' xlink:href='#g3-99'/> +<use x='196.646' y='186.041' xlink:href='#g3-104'/> +<use x='201.018' y='186.041' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 207.225 74.992)'> +<use x='168.285' y='186.041' xlink:href='#g3-120'/> +<use x='172.187' y='186.041' xlink:href='#g3-109'/> +<use x='178.912' y='186.041' xlink:href='#g3-97'/> +<use x='182.98' y='186.041' xlink:href='#g3-108'/> +<use x='185' y='186.041' xlink:href='#g3-108'/> +<use x='187.02' y='186.041' xlink:href='#g3-111'/> +<use x='191.49' y='186.041' xlink:href='#g3-99'/> +<use x='195.254' y='186.041' xlink:href='#g3-45'/> +<use x='198.076' y='186.041' xlink:href='#g3-116'/> +<use x='201.134' y='186.041' xlink:href='#g3-101'/> +<use x='204.898' y='186.041' xlink:href='#g3-115'/> +<use x='208.144' y='186.041' xlink:href='#g3-116'/> +<use x='211.202' y='186.041' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 263.494 74.992)'> +<use x='168.285' y='186.041' xlink:href='#g3-99'/> +<use x='172.049' y='186.041' xlink:href='#g3-97'/> +<use x='176.117' y='186.041' xlink:href='#g3-99'/> +<use x='179.88' y='186.041' xlink:href='#g3-104'/> +<use x='184.253' y='186.041' xlink:href='#g3-101'/> +<use x='188.017' y='186.041' xlink:href='#g3-45'/> +<use x='190.839' y='186.041' xlink:href='#g3-115'/> +<use x='194.086' y='186.041' xlink:href='#g3-99'/> +<use x='197.849' y='186.041' xlink:href='#g3-114'/> +<use x='200.741' y='186.041' xlink:href='#g3-97'/> +<use x='204.81' y='186.041' xlink:href='#g3-116'/> +<use x='207.868' y='186.041' xlink:href='#g3-99'/> +<use x='211.631' y='186.041' xlink:href='#g3-104'/> +<use x='216.004' y='186.041' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 62.23)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.677)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -4.876)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -38.43)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -71.983)'> +<use x='168.285' y='186.041' xlink:href='#g2-50'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -105.536)'> +<use x='168.285' y='186.041' xlink:href='#g2-50'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-120'/> +</g> +<path d='M135.949 179.531H487.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M140.125 246.637H143.363V179.531H140.125ZM198.797 246.637H202.035V179.531H198.797ZM257.465 246.637H260.703V179.531H257.465ZM316.133 246.637H319.371V179.531H316.133ZM374.801 246.637H378.039V179.531H374.801ZM433.473 246.637H436.711V179.531H433.473Z' fill='#fff' clip-path='url(#clip2)'/> +<path d='M140.125 246.637H143.363V179.531H140.125ZM198.797 246.637H202.035V179.531H198.797ZM257.465 246.637H260.703V179.531H257.465ZM316.133 246.637H319.371V179.531H316.133ZM374.801 246.637H378.039V179.531H374.801ZM433.473 246.637H436.711V179.531H433.473Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M141.746 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M139.754 179.531H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M141.746 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M139.754 179.531H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M200.414 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M198.422 179.531H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M200.414 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M198.422 179.531H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M259.082 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M257.09 179.531H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M259.082 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M257.09 179.531H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M317.754 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M315.762 179.531H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M317.754 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M315.762 179.531H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M376.422 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M374.43 179.531H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M376.422 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M374.43 179.531H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M435.09 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M433.098 179.531H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M435.09 179.531' fill='#fff' clip-path='url(#clip2)'/> +<path d='M433.098 179.531H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M145.356 246.637H148.594V180.066H145.356ZM204.028 246.637H207.266V179.195H204.028ZM262.695 246.637H265.934V181.008H262.695ZM321.363 246.637H324.602V179.934H321.363ZM380.031 246.637H383.27V175.637H380.031ZM438.703 246.637H441.942V179.664H438.703Z' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M145.356 246.637H148.594V180.066H145.356ZM204.028 246.637H207.266V179.195H204.028ZM262.695 246.637H265.934V181.008H262.695ZM321.363 246.637H324.602V179.934H321.363ZM380.031 246.637H383.27V175.637H380.031ZM438.703 246.637H441.942V179.664H438.703Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M146.977 180.066' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M144.984 180.067H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M146.977 180.066' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M144.984 180.067H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M205.645 179.195' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M203.652 179.196H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M205.645 179.195' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M203.652 179.196H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M264.313 181.008' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M262.32 181.007H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M264.313 181.008' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M262.32 181.007H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M322.984 179.934' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M320.992 179.934H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M322.984 179.934' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M320.992 179.934H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M381.652 175.637' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M379.66 175.637H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M381.652 175.637' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M379.66 175.637H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M440.32 179.664' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M438.328 179.664H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M440.32 179.664' fill='#f0e0f0' clip-path='url(#clip2)'/> +<path d='M438.328 179.664H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M150.586 246.637H153.824V163.426H150.586ZM209.258 246.637H212.496V159.062H209.258ZM267.926 246.637H271.164V184.027H267.926ZM326.594 246.637H329.832V203.687H326.594ZM385.262 246.637H388.5V219.859H385.262ZM443.934 246.637H447.172V139.734H443.934Z' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M150.586 246.637H153.824V163.426H150.586ZM209.258 246.637H212.496V159.062H209.258ZM267.926 246.637H271.164V184.027H267.926ZM326.594 246.637H329.832V203.687H326.594ZM385.262 246.637H388.5V219.859H385.262ZM443.934 246.637H447.172V139.734H443.934Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M152.207 163.426' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M150.215 163.426H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M152.207 163.426' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M150.215 163.426H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M210.875 159.062' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M208.883 159.063H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M210.875 159.062' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M208.883 159.063H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M269.543 184.027' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M267.551 184.027H271.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M269.543 184.027' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M267.551 184.027H271.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M328.215 203.687' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M326.223 203.687H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M328.215 203.687' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M326.223 203.687H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M386.883 219.859' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M384.891 219.86H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M386.883 219.859' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M384.891 219.86H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M445.551 139.734' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M443.559 139.734H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M445.551 139.734' fill='#e1c2e1' clip-path='url(#clip2)'/> +<path d='M443.559 139.734H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M155.817 246.637H159.055V183.824H155.817ZM214.488 246.637H217.727V176.109H214.488ZM273.156 246.637H276.395V181.344H273.156ZM331.824 246.637H335.063V193.086H331.824ZM390.492 246.637H393.731V195.164H390.492ZM449.164 246.637H452.402V144.566H449.164Z' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M155.817 246.637H159.055V183.824H155.817ZM214.488 246.637H217.727V176.109H214.488ZM273.156 246.637H276.395V181.344H273.156ZM331.824 246.637H335.063V193.086H331.824ZM390.492 246.637H393.731V195.164H390.492ZM449.164 246.637H452.402V144.566H449.164Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M157.438 183.824' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M155.445 183.824H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M157.438 183.824' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M155.445 183.824H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M216.106 176.109' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M214.113 176.11H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M216.106 176.109' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M214.113 176.11H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M274.774 181.344' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M272.781 181.344H276.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M274.774 181.344' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M272.781 181.344H276.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M333.445 193.086' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M331.453 193.085H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M333.445 193.086' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M331.453 193.085H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M392.113 195.164' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M390.121 195.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M392.113 195.164' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M390.121 195.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M450.781 144.566' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M448.789 144.567H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M450.781 144.566' fill='#d1a3d1' clip-path='url(#clip2)'/> +<path d='M448.789 144.567H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M161.047 246.637H164.285V178.926H161.047ZM219.719 246.637H222.957V169.934H219.719ZM278.387 246.637H281.625V176.644H278.387ZM337.055 246.637H340.293V195.234H337.055ZM395.723 246.637H398.961V182.078H395.723ZM454.395 246.637H457.633V177.652H454.395Z' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M161.047 246.637H164.285V178.926H161.047ZM219.719 246.637H222.957V169.934H219.719ZM278.387 246.637H281.625V176.644H278.387ZM337.055 246.637H340.293V195.234H337.055ZM395.723 246.637H398.961V182.078H395.723ZM454.395 246.637H457.633V177.652H454.395Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M162.668 178.926' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M160.676 178.926H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M162.668 178.926' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M160.676 178.926H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M221.336 169.934' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M219.344 169.934H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M221.336 169.934' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M219.344 169.934H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M280.004 176.644' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M278.012 176.644H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M280.004 176.644' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M278.012 176.644H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M338.676 195.234' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M336.684 195.235H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M338.676 195.234' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M336.684 195.235H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M397.344 182.078' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M395.352 182.078H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M397.344 182.078' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M395.352 182.078H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M456.012 177.652' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M454.02 177.652H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M456.012 177.652' fill='#c285c2' clip-path='url(#clip2)'/> +<path d='M454.02 177.652H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M166.278 246.637H169.516V179.598H166.278ZM224.949 246.637H228.188V144.098H224.949ZM283.617 246.637H286.856V172.82H283.617ZM342.285 246.637H345.524V155.91H342.285ZM400.953 246.637H404.192V172.484H400.953ZM459.625 246.637H462.863V172.016H459.625Z' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M166.278 246.637H169.516V179.598H166.278ZM224.949 246.637H228.188V144.098H224.949ZM283.617 246.637H286.856V172.82H283.617ZM342.285 246.637H345.524V155.91H342.285ZM400.953 246.637H404.192V172.484H400.953ZM459.625 246.637H462.863V172.016H459.625Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M167.899 179.598' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M165.906 179.598H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M167.899 179.598' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M165.906 179.598H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M226.567 144.098' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M224.574 144.098H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M226.567 144.098' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M224.574 144.098H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M285.234 172.82' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M283.242 172.82H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M285.234 172.82' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M283.242 172.82H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M343.906 155.91' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M341.914 155.91H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M343.906 155.91' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M341.914 155.91H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M402.574 172.484' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M400.582 172.484H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M402.574 172.484' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M400.582 172.484H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M461.242 172.016' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M459.25 172.015H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M461.242 172.016' fill='#b366b3' clip-path='url(#clip2)'/> +<path d='M459.25 172.015H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M171.508 246.637H174.746V177.113H171.508ZM230.18 246.637H233.414V179.465H230.18ZM288.848 246.637H292.086V166.176H288.848ZM347.516 246.637H350.754V160.605H347.516ZM406.184 246.637H409.422V78.871H406.184ZM464.856 246.637H468.094V189.797H464.856Z' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M171.508 246.637H174.746V177.113H171.508ZM230.18 246.637H233.414V179.465H230.18ZM288.848 246.637H292.086V166.176H288.848ZM347.516 246.637H350.754V160.605H347.516ZM406.184 246.637H409.422V78.871H406.184ZM464.856 246.637H468.094V189.797H464.856Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M173.129 177.113' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M171.137 177.113H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M173.129 177.113' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M171.137 177.113H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M231.797 179.465' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M229.805 179.465H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M231.797 179.465' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M229.805 179.465H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M290.465 166.176' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M288.473 166.176H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M290.465 166.176' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M288.473 166.176H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M349.137 160.605' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M347.145 160.605H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M349.137 160.605' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M347.145 160.605H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M407.805 78.871' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M405.813 78.871H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M407.805 78.871' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M405.813 78.871H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M466.473 189.797' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M464.481 189.797H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M466.473 189.797' fill='#a447a4' clip-path='url(#clip2)'/> +<path d='M464.481 189.797H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M176.738 246.637H179.977V167.383H176.738ZM235.41 246.637H238.645V78.871H235.41ZM294.078 246.637H297.317V143.09H294.078ZM352.746 246.637H355.984V166.711H352.746ZM411.414 246.637H414.652V219.391H411.414ZM470.086 246.637H473.324V160.336H470.086Z' fill='#942994' clip-path='url(#clip2)'/> +<path d='M176.738 246.637H179.977V167.383H176.738ZM235.41 246.637H238.645V78.871H235.41ZM294.078 246.637H297.317V143.09H294.078ZM352.746 246.637H355.984V166.711H352.746ZM411.414 246.637H414.652V219.391H411.414ZM470.086 246.637H473.324V160.336H470.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M178.36 167.383' fill='#942994' clip-path='url(#clip2)'/> +<path d='M176.367 167.383H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M178.36 167.383' fill='#942994' clip-path='url(#clip2)'/> +<path d='M176.367 167.383H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M237.027 78.871' fill='#942994' clip-path='url(#clip2)'/> +<path d='M235.035 78.871H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M237.027 78.871' fill='#942994' clip-path='url(#clip2)'/> +<path d='M235.035 78.871H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M295.695 143.09' fill='#942994' clip-path='url(#clip2)'/> +<path d='M293.703 143.089H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M295.695 143.09' fill='#942994' clip-path='url(#clip2)'/> +<path d='M293.703 143.089H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M354.367 166.711' fill='#942994' clip-path='url(#clip2)'/> +<path d='M352.375 166.711H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M354.367 166.711' fill='#942994' clip-path='url(#clip2)'/> +<path d='M352.375 166.711H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M413.035 219.391' fill='#942994' clip-path='url(#clip2)'/> +<path d='M411.043 219.391H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M413.035 219.391' fill='#942994' clip-path='url(#clip2)'/> +<path d='M411.043 219.391H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M471.703 160.336' fill='#942994' clip-path='url(#clip2)'/> +<path d='M469.711 160.336H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M471.703 160.336' fill='#942994' clip-path='url(#clip2)'/> +<path d='M469.711 160.336H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M181.969 246.637H185.207V176.711H181.969ZM240.641 246.637H243.875V169.062H240.641ZM299.309 246.637H302.547V151.547H299.309ZM357.977 246.637H361.215V113.43H357.977ZM416.645 246.637H419.883V188.387H416.645ZM475.317 246.637H478.555V190.402H475.317Z' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M181.969 246.637H185.207V176.711H181.969ZM240.641 246.637H243.875V169.062H240.641ZM299.309 246.637H302.547V151.547H299.309ZM357.977 246.637H361.215V113.43H357.977ZM416.645 246.637H419.883V188.387H416.645ZM475.317 246.637H478.555V190.402H475.317Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M183.59 176.711' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M181.598 176.711H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M183.59 176.711' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M181.598 176.711H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M242.258 169.062' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M240.266 169.062H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M242.258 169.062' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M240.266 169.062H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M300.926 151.547' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M298.933 151.547H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M300.926 151.547' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M298.933 151.547H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M359.598 113.43' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M357.606 113.43H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M359.598 113.43' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M357.606 113.43H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M418.266 188.387' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M416.274 188.387H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M418.266 188.387' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M416.274 188.387H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M476.934 190.402' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M474.942 190.402H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M476.934 190.402' fill='#850a85' clip-path='url(#clip2)'/> +<path d='M474.942 190.402H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M187.199 246.637H190.438V179.465H187.199ZM245.871 246.637H249.106V113.094H245.871ZM304.539 246.637H307.777V164.094H304.539ZM363.207 246.637H366.445V156.578H363.207ZM421.875 246.637H425.113V174.496H421.875ZM480.547 246.637H483.785V176.375H480.547Z' fill='#760076' clip-path='url(#clip2)'/> +<path d='M187.199 246.637H190.438V179.465H187.199ZM245.871 246.637H249.106V113.094H245.871ZM304.539 246.637H307.777V164.094H304.539ZM363.207 246.637H366.445V156.578H363.207ZM421.875 246.637H425.113V174.496H421.875ZM480.547 246.637H483.785V176.375H480.547Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M188.82 179.465' fill='#760076' clip-path='url(#clip2)'/> +<path d='M186.828 179.465H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M188.82 179.465' fill='#760076' clip-path='url(#clip2)'/> +<path d='M186.828 179.465H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M247.488 113.094' fill='#760076' clip-path='url(#clip2)'/> +<path d='M245.496 113.094H249.481' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M247.488 113.094' fill='#760076' clip-path='url(#clip2)'/> +<path d='M245.496 113.094H249.481' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M306.156 164.094' fill='#760076' clip-path='url(#clip2)'/> +<path d='M304.164 164.094H308.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M306.156 164.094' fill='#760076' clip-path='url(#clip2)'/> +<path d='M304.164 164.094H308.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M364.828 156.578' fill='#760076' clip-path='url(#clip2)'/> +<path d='M362.836 156.578H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M364.828 156.578' fill='#760076' clip-path='url(#clip2)'/> +<path d='M362.836 156.578H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M423.496 174.496' fill='#760076' clip-path='url(#clip2)'/> +<path d='M421.504 174.496H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M423.496 174.496' fill='#760076' clip-path='url(#clip2)'/> +<path d='M421.504 174.496H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M482.164 176.375' fill='#760076' clip-path='url(#clip2)'/> +<path d='M480.172 176.375H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M482.164 176.375' fill='#760076' clip-path='url(#clip2)'/> +<path d='M480.172 176.375H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<path d='M369.781 308.934H487.762V273.68H369.781Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/> +<g transform='matrix(1 0 0 1 204.818 118.327)'> +<use x='168.285' y='162.131' xlink:href='#g2-99'/> +<use x='170.637' y='162.131' xlink:href='#g2-53'/> +<use x='173.284' y='162.131' xlink:href='#g2-45'/> +<use x='175.048' y='162.131' xlink:href='#g2-49'/> +<use x='177.694' y='162.131' xlink:href='#g2-56'/> +<use x='180.341' y='162.131' xlink:href='#g2-120'/> +<use x='182.779' y='162.131' xlink:href='#g2-108'/> +<use x='184.042' y='162.131' xlink:href='#g2-97'/> +<use x='186.438' y='162.131' xlink:href='#g2-114'/> +<use x='188.245' y='162.131' xlink:href='#g2-103'/> +<use x='190.891' y='162.131' xlink:href='#g2-101'/> +<use x='193.244' y='162.131' xlink:href='#g2-44'/> +<use x='196.478' y='162.131' xlink:href='#g2-49'/> +<use x='199.124' y='162.131' xlink:href='#g2-52'/> +<use x='201.771' y='162.131' xlink:href='#g2-52'/> +<use x='204.417' y='162.131' xlink:href='#g2-71'/> +<use x='207.946' y='162.131' xlink:href='#g2-98'/> +<use x='168.285' y='168.109' xlink:href='#g2-50'/> +<use x='170.931' y='168.109' xlink:href='#g4-2'/> +<use x='178.092' y='168.109' xlink:href='#g2-49'/> +<use x='180.738' y='168.109' xlink:href='#g2-56'/> +<use x='183.385' y='168.109' xlink:href='#g2-45'/> +<use x='185.149' y='168.109' xlink:href='#g2-99'/> +<use x='187.501' y='168.109' xlink:href='#g2-111'/> +<use x='190.001' y='168.109' xlink:href='#g2-114'/> +<use x='191.808' y='168.109' xlink:href='#g2-101'/> +<use x='195.925' y='168.109' xlink:href='#g2-73'/> +<use x='197.395' y='168.109' xlink:href='#g2-110'/> +<use x='200.128' y='168.109' xlink:href='#g2-116'/> +<use x='202.039' y='168.109' xlink:href='#g2-101'/> +<use x='204.391' y='168.109' xlink:href='#g2-108'/> +<use x='207.418' y='168.109' xlink:href='#g2-88'/> +<use x='210.947' y='168.109' xlink:href='#g2-101'/> +<use x='213.299' y='168.109' xlink:href='#g2-111'/> +<use x='215.945' y='168.109' xlink:href='#g2-110'/> +<use x='220.442' y='168.109' xlink:href='#g2-64'/> +<use x='223.971' y='168.109' xlink:href='#g2-51'/> +<use x='226.617' y='168.109' xlink:href='#g2-71'/> +<use x='230.146' y='168.109' xlink:href='#g2-104'/> +<use x='232.879' y='168.109' xlink:href='#g2-122'/> +<use x='168.285' y='174.086' xlink:href='#g2-85'/> +<use x='171.917' y='174.086' xlink:href='#g2-98'/> +<use x='174.65' y='174.086' xlink:href='#g2-117'/> +<use x='177.383' y='174.086' xlink:href='#g2-110'/> +<use x='180.116' y='174.086' xlink:href='#g2-116'/> +<use x='182.027' y='174.086' xlink:href='#g2-117'/> +<use x='186.524' y='174.086' xlink:href='#g2-50'/> +<use x='189.17' y='174.086' xlink:href='#g2-48'/> +<use x='191.817' y='174.086' xlink:href='#g2-46'/> +<use x='193.287' y='174.086' xlink:href='#g2-48'/> +<use x='195.933' y='174.086' xlink:href='#g2-52'/> +<use x='198.58' y='174.086' xlink:href='#g2-44'/> +<use x='201.814' y='174.086' xlink:href='#g2-71'/> +<use x='205.343' y='174.086' xlink:href='#g2-67'/> +<use x='208.724' y='174.086' xlink:href='#g2-67'/> +<use x='213.87' y='174.086' xlink:href='#g2-57'/> +<use x='216.516' y='174.086' xlink:href='#g2-46'/> +<use x='217.986' y='174.086' xlink:href='#g2-51'/> +<use x='220.633' y='174.086' xlink:href='#g2-46'/> +<use x='222.103' y='174.086' xlink:href='#g2-48'/> +<use x='224.749' y='174.086' xlink:href='#g2-44'/> +<use x='227.984' y='174.086' xlink:href='#g2-103'/> +<use x='230.63' y='174.086' xlink:href='#g2-108'/> +<use x='231.893' y='174.086' xlink:href='#g2-105'/> +<use x='233.155' y='174.086' xlink:href='#g2-98'/> +<use x='236.035' y='174.086' xlink:href='#g2-99'/> +<use x='240.152' y='174.086' xlink:href='#g2-50'/> +<use x='242.798' y='174.086' xlink:href='#g2-46'/> +<use x='244.268' y='174.086' xlink:href='#g2-51'/> +<use x='246.915' y='174.086' xlink:href='#g2-49'/> +<use x='249.561' y='174.086' xlink:href='#g2-44'/> +<use x='252.796' y='174.086' xlink:href='#g2-99'/> +<use x='255.148' y='174.086' xlink:href='#g2-108'/> +<use x='256.41' y='174.086' xlink:href='#g2-97'/> +<use x='258.953' y='174.086' xlink:href='#g2-110'/> +<use x='261.686' y='174.086' xlink:href='#g2-103'/> +<use x='266.097' y='174.086' xlink:href='#g2-49'/> +<use x='268.743' y='174.086' xlink:href='#g2-48'/> +<use x='271.389' y='174.086' xlink:href='#g2-46'/> +<use x='272.859' y='174.086' xlink:href='#g2-48'/> +<use x='275.506' y='174.086' xlink:href='#g2-46'/> +<use x='276.976' y='174.086' xlink:href='#g2-48'/> +<use x='168.285' y='180.064' xlink:href='#g2-55'/> +<use x='170.931' y='180.064' xlink:href='#g2-50'/> +<use x='175.342' y='180.064' xlink:href='#g2-108'/> +<use x='176.604' y='180.064' xlink:href='#g2-111'/> +<use x='179.251' y='180.064' xlink:href='#g2-103'/> +<use x='181.897' y='180.064' xlink:href='#g2-105'/> +<use x='183.16' y='180.064' xlink:href='#g2-99'/> +<use x='185.512' y='180.064' xlink:href='#g2-97'/> +<use x='188.055' y='180.064' xlink:href='#g2-108'/> +<use x='191.082' y='180.064' xlink:href='#g2-99'/> +<use x='193.434' y='180.064' xlink:href='#g2-111'/> +<use x='195.933' y='180.064' xlink:href='#g2-114'/> +<use x='197.741' y='180.064' xlink:href='#g2-101'/> +<use x='200.093' y='180.064' xlink:href='#g2-115'/> +<use x='203.886' y='180.064' xlink:href='#g2-111'/> +<use x='206.533' y='180.064' xlink:href='#g2-110'/> +<use x='211.03' y='180.064' xlink:href='#g2-50'/> +<use x='215.44' y='180.064' xlink:href='#g2-110'/> +<use x='218.173' y='180.064' xlink:href='#g2-117'/> +<use x='220.906' y='180.064' xlink:href='#g2-109'/> +<use x='225.109' y='180.064' xlink:href='#g2-97'/> +<use x='229.416' y='180.064' xlink:href='#g2-110'/> +<use x='232.149' y='180.064' xlink:href='#g2-111'/> +<use x='234.942' y='180.064' xlink:href='#g2-100'/> +<use x='237.675' y='180.064' xlink:href='#g2-101'/> +<use x='240.027' y='180.064' xlink:href='#g2-115'/> +<use x='168.285' y='186.041' xlink:href='#g2-50'/> +<use x='170.931' y='186.041' xlink:href='#g2-48'/> +<use x='173.578' y='186.041' xlink:href='#g2-50'/> +<use x='176.224' y='186.041' xlink:href='#g2-49'/> +<use x='178.87' y='186.041' xlink:href='#g2-45'/> +<use x='180.635' y='186.041' xlink:href='#g2-48'/> +<use x='183.281' y='186.041' xlink:href='#g2-49'/> +<use x='185.927' y='186.041' xlink:href='#g2-45'/> +<use x='187.692' y='186.041' xlink:href='#g2-51'/> +<use x='190.338' y='186.041' xlink:href='#g2-48'/> +<use x='192.984' y='186.041' xlink:href='#g2-41'/> +</g> +<g transform='matrix(0 -1 1 0 -42.661 341.611)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 16.008 341.611)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 74.677 341.611)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 133.346 341.611)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 192.015 341.611)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 250.684 341.611)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -37.431 342.148)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 21.238 341.275)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 79.907 343.087)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 138.576 342.014)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 197.245 337.719)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 255.914 341.745)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -32.2 325.505)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-50'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 26.469 321.144)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-51'/> +<use x='175.048' y='186.041' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 85.138 346.107)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 143.807 365.769)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-54'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 202.476 381.942)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-52'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 261.145 301.817)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -26.97 345.906)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 31.699 338.189)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 90.368 343.423)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 149.037 355.166)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-56'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 207.706 357.247)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-55'/> +<use x='175.048' y='186.041' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 266.375 306.649)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 -21.739 341.007)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 36.93 332.015)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 95.599 338.725)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 154.268 357.314)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-55'/> +<use x='175.048' y='186.041' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 212.937 344.161)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 271.606 339.732)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 -16.509 341.678)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 42.16 306.179)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 100.829 334.9)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 159.498 317.99)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-51'/> +<use x='175.048' y='186.041' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 218.167 334.565)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 276.836 334.095)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 -11.278 339.195)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 47.391 341.544)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 106.06 328.257)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-50'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 164.729 322.687)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-50'/> +<use x='175.048' y='186.041' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 223.398 240.952)'> +<use x='163.396' y='186.041' xlink:href='#g4-1'/> +<use x='166.901' y='186.041' xlink:href='#g4-1'/> +<use x='170.407' y='186.041' xlink:href='#g4-1'/> +<use x='173.912' y='186.041' xlink:href='#g2-57'/> +<use x='176.558' y='186.041' xlink:href='#g2-46'/> +<use x='178.029' y='186.041' xlink:href='#g2-54'/> +<use x='180.675' y='186.041' xlink:href='#g2-56'/> +<use x='183.321' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 282.067 351.878)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-56'/> +<use x='175.048' y='186.041' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -6.048 329.465)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 52.621 240.952)'> +<use x='163.396' y='186.041' xlink:href='#g4-1'/> +<use x='166.901' y='186.041' xlink:href='#g4-1'/> +<use x='170.407' y='186.041' xlink:href='#g4-1'/> +<use x='173.912' y='186.041' xlink:href='#g2-50'/> +<use x='176.558' y='186.041' xlink:href='#g2-46'/> +<use x='178.029' y='186.041' xlink:href='#g2-54'/> +<use x='180.675' y='186.041' xlink:href='#g2-50'/> +<use x='183.321' y='186.041' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 111.29 305.172)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-53'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 169.959 328.794)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 228.628 381.472)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-52'/> +<use x='175.048' y='186.041' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 287.297 322.419)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-50'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 -.818 338.793)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 57.851 331.142)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-49'/> +<use x='175.048' y='186.041' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 116.52 313.628)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-52'/> +<use x='175.048' y='186.041' xlink:href='#g2-50'/> +</g> +<g transform='matrix(0 -1 1 0 175.189 275.511)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 233.858 350.469)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-56'/> +<use x='175.048' y='186.041' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 292.527 352.482)'> +<use x='168.285' y='186.041' xlink:href='#g2-48'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-56'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 4.413 341.544)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 63.082 275.176)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-57'/> +<use x='175.048' y='186.041' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 121.751 326.177)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-50'/> +<use x='175.048' y='186.041' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 180.42 318.661)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-51'/> +<use x='175.048' y='186.041' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 239.089 336.578)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 297.758 338.457)'> +<use x='168.285' y='186.041' xlink:href='#g2-49'/> +<use x='170.931' y='186.041' xlink:href='#g2-46'/> +<use x='172.401' y='186.041' xlink:href='#g2-48'/> +<use x='175.048' y='186.041' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -72.883 382.933)'> +<use x='168.285' y='186.041' xlink:href='#g1-82'/> +<use x='174.255' y='186.041' xlink:href='#g1-101'/> +<use x='178.351' y='186.041' xlink:href='#g1-108'/> +<use x='180.551' y='186.041' xlink:href='#g1-97'/> +<use x='184.979' y='186.041' xlink:href='#g1-116'/> +<use x='188.307' y='186.041' xlink:href='#g1-105'/> +<use x='190.507' y='186.041' xlink:href='#g1-118'/> +<use x='194.755' y='186.041' xlink:href='#g1-101'/> +<use x='201.922' y='186.041' xlink:href='#g1-114'/> +<use x='205.07' y='186.041' xlink:href='#g1-115'/> +<use x='208.603' y='186.041' xlink:href='#g1-115'/> +<use x='215.207' y='186.041' xlink:href='#g3-40'/> +<use x='218.5' y='186.041' xlink:href='#g3-108'/> +<use x='220.521' y='186.041' xlink:href='#g3-111'/> +<use x='224.52' y='186.041' xlink:href='#g3-119'/> +<use x='230.068' y='186.041' xlink:href='#g3-101'/> +<use x='233.832' y='186.041' xlink:href='#g3-114'/> +<use x='239.547' y='186.041' xlink:href='#g3-105'/> +<use x='241.567' y='186.041' xlink:href='#g3-115'/> +<use x='247.636' y='186.041' xlink:href='#g3-98'/> +<use x='252.244' y='186.041' xlink:href='#g3-101'/> +<use x='256.008' y='186.041' xlink:href='#g3-116'/> +<use x='259.066' y='186.041' xlink:href='#g3-116'/> +<use x='262.124' y='186.041' xlink:href='#g3-101'/> +<use x='265.887' y='186.041' xlink:href='#g3-114'/> +<use x='268.779' y='186.041' xlink:href='#g3-41'/> +</g> +<path d='M136.149 307.031H346.746V277.031H136.149Z' fill='#fff'/> +<path d='M136.149 307.031H346.746V277.031H136.149Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<path d='M139.336 287.523H142.324V279.551H139.336ZM145.313 287.523H148.301V281.543H145.313Z' fill='#fff'/> +<path d='M139.336 287.523H142.324V279.551H139.336ZM145.313 287.523H148.301V281.543H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.354 114.479)'> +<use x='191.843' y='173.035' xlink:href='#g3-120'/> +<use x='195.745' y='173.035' xlink:href='#g3-109'/> +<use x='202.47' y='173.035' xlink:href='#g3-105'/> +<use x='204.49' y='173.035' xlink:href='#g3-58'/> +<use x='206.843' y='173.035' xlink:href='#g0-54'/> +<use x='210.548' y='173.035' xlink:href='#g0-56'/> +</g> +<path d='M177.086 287.523H180.074V279.551H177.086ZM183.063 287.523H186.055V281.543H183.063Z' fill='#f0e0f0'/> +<path d='M177.086 287.523H180.074V279.551H177.086ZM183.063 287.523H186.055V281.543H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -38.403 114.479)'> +<use x='233.123' y='173.035' xlink:href='#g3-109'/> +<use x='239.848' y='173.035' xlink:href='#g3-105'/> +<use x='241.869' y='173.035' xlink:href='#g3-58'/> +<use x='244.221' y='173.035' xlink:href='#g0-54'/> +<use x='247.926' y='173.035' xlink:href='#g0-56'/> +</g> +<path d='M221.895 287.523H224.883V279.551H221.895ZM227.875 287.523H230.863V281.543H227.875Z' fill='#e1c2e1'/> +<path d='M221.895 287.523H224.883V279.551H221.895ZM227.875 287.523H230.863V281.543H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.441 114.036)'> +<use x='277.134' y='173.035' xlink:href='#g3-116'/> +<use x='280.192' y='173.035' xlink:href='#g3-99'/> +<use x='283.956' y='173.035' xlink:href='#g3-58'/> +<use x='286.308' y='173.035' xlink:href='#g0-55'/> +<use x='290.013' y='173.035' xlink:href='#g0-50'/> +</g> +<path d='M265.109 287.523H268.098V279.551H265.109ZM271.086 287.523H274.074V281.543H271.086Z' fill='#d1a3d1'/> +<path d='M265.109 287.523H268.098V279.551H265.109ZM271.086 287.523H274.074V281.543H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.04 114.479)'> +<use x='319.615' y='173.035' xlink:href='#g3-106'/> +<use x='321.871' y='173.035' xlink:href='#g3-101'/> +<use x='325.634' y='173.035' xlink:href='#g3-58'/> +<use x='327.987' y='173.035' xlink:href='#g0-55'/> +<use x='331.691' y='173.035' xlink:href='#g0-49'/> +</g> +<path d='M306.859 287.523H309.848V279.551H306.859ZM312.836 287.523H315.824V281.543H312.836Z' fill='#c285c2'/> +<path d='M306.859 287.523H309.848V279.551H306.859ZM312.836 287.523H315.824V281.543H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -39.932 114.515)'> +<use x='359.038' y='173.035' xlink:href='#g3-116'/> +<use x='362.096' y='173.035' xlink:href='#g3-98'/> +<use x='366.469' y='173.035' xlink:href='#g3-98'/> +<use x='370.842' y='173.035' xlink:href='#g3-58'/> +<use x='373.194' y='173.035' xlink:href='#g0-54'/> +<use x='376.899' y='173.035' xlink:href='#g0-51'/> +</g> +<path d='M139.336 300.527H142.324V292.559H139.336ZM145.313 300.527H148.301V294.551H145.313Z' fill='#b366b3'/> +<path d='M139.336 300.527H142.324V292.559H139.336ZM145.313 300.527H148.301V294.551H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.662 114.036)'> +<use x='191.843' y='186.041' xlink:href='#g3-114'/> +<use x='194.735' y='186.041' xlink:href='#g3-112'/> +<use x='199.108' y='186.041' xlink:href='#g3-58'/> +<use x='201.46' y='186.041' xlink:href='#g0-52'/> +<use x='205.165' y='186.041' xlink:href='#g0-50'/> +</g> +<path d='M177.086 300.527H180.074V292.559H177.086ZM183.063 300.527H186.055V294.551H183.063Z' fill='#a447a4'/> +<path d='M177.086 300.527H180.074V292.559H177.086ZM183.063 300.527H186.055V294.551H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.882 114.515)'> +<use x='233.123' y='186.041' xlink:href='#g3-104'/> +<use x='237.496' y='186.041' xlink:href='#g3-111'/> +<use x='241.73' y='186.041' xlink:href='#g3-97'/> +<use x='245.563' y='186.041' xlink:href='#g3-114'/> +<use x='248.455' y='186.041' xlink:href='#g3-100'/> +<use x='252.828' y='186.041' xlink:href='#g3-58'/> +<use x='255.18' y='186.041' xlink:href='#g0-53'/> +<use x='258.885' y='186.041' xlink:href='#g0-51'/> +</g> +<path d='M221.895 300.527H224.883V292.559H221.895ZM227.875 300.527H230.863V294.551H227.875Z' fill='#942994'/> +<path d='M221.895 300.527H224.883V292.559H221.895ZM227.875 300.527H230.863V294.551H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.084 114.515)'> +<use x='277.134' y='186.041' xlink:href='#g3-109'/> +<use x='283.859' y='186.041' xlink:href='#g3-101'/> +<use x='287.622' y='186.041' xlink:href='#g3-115'/> +<use x='290.869' y='186.041' xlink:href='#g3-104'/> +<use x='295.241' y='186.041' xlink:href='#g3-58'/> +<use x='297.593' y='186.041' xlink:href='#g0-53'/> +<use x='301.298' y='186.041' xlink:href='#g0-50'/> +</g> +<path d='M265.109 300.527H268.098V292.559H265.109ZM271.086 300.527H274.074V294.551H271.086Z' fill='#850a85'/> +<path d='M265.109 300.527H268.098V292.559H265.109ZM271.086 300.527H274.074V294.551H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -42.353 114.515)'> +<use x='319.615' y='186.041' xlink:href='#g3-103'/> +<use x='323.849' y='186.041' xlink:href='#g3-108'/> +<use x='325.869' y='186.041' xlink:href='#g3-105'/> +<use x='327.89' y='186.041' xlink:href='#g3-98'/> +<use x='332.498' y='186.041' xlink:href='#g3-99'/> +<use x='336.261' y='186.041' xlink:href='#g3-58'/> +<use x='338.614' y='186.041' xlink:href='#g0-54'/> +<use x='342.318' y='186.041' xlink:href='#g0-52'/> +</g> +<path d='M306.859 300.527H309.848V292.559H306.859ZM312.836 300.527H315.824V294.551H312.836Z' fill='#760076'/> +<path d='M306.859 300.527H309.848V292.559H306.859ZM312.836 300.527H315.824V294.551H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.026 114.479)'> +<use x='359.038' y='186.041' xlink:href='#g3-115'/> +<use x='362.285' y='186.041' xlink:href='#g3-109'/> +<use x='369.009' y='186.041' xlink:href='#g3-105'/> +<use x='371.03' y='186.041' xlink:href='#g3-58'/> +<use x='373.382' y='186.041' xlink:href='#g0-52'/> +<use x='377.087' y='186.041' xlink:href='#g0-51'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg new file mode 100644 index 0000000..ece6418 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg @@ -0,0 +1,766 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- This file was generated by dvisvgm 2.9.1 --> +<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='315.585pt' height='208.604pt' viewBox='52.934 54.994 315.585 208.604'> +<rect width="1000%" height="1000%" fill="white"/> +<defs> +<clipPath id='clip1'> +<path d='M82.148 203.938H368.121V78.692H82.148Z'/> +</clipPath> +<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/> +<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/> +<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/> +<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/> +<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/> +<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/> +<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/> +<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/> +<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/> +<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/> +<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/> +<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/> +<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/> +<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/> +<use id='g2-65' xlink:href='#g0-65' transform='scale(.714)'/> +<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/> +<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/> +<use id='g2-73' xlink:href='#g0-73' transform='scale(.714)'/> +<use id='g2-79' xlink:href='#g0-79' transform='scale(.714)'/> +<use id='g2-83' xlink:href='#g0-83' transform='scale(.714)'/> +<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/> +<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/> +<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/> +<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/> +<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/> +<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/> +<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/> +<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/> +<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/> +<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/> +<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/> +<use id='g2-112' xlink:href='#g0-112' transform='scale(.714)'/> +<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/> +<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/> +<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/> +<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/> +<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/> +<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/> +<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/> +<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/> +<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/> +<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/> +<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/> +<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/> +<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/> +<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/> +<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/> +<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/> +<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/> +<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/> +<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/> +<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/> +<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/> +<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/> +<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/> +<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/> +<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/> +<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/> +<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/> +<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/> +<use id='g3-121' xlink:href='#g0-121' transform='scale(1.143)'/> +<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/> +<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/> +<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/> +<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/> +<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/> +<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/> +<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/> +<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/> +<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/> +<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/> +<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/> +<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/> +<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/> +<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/> +<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/> +<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/> +<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/> +<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/> +<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/> +<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/> +<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/> +<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/> +<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/> +<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/> +<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/> +<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/> +<path id='g0-65' d='M2.803-4.84H2.127L.209 0H.781L1.325-1.381H3.445L3.989 0H4.721L2.803-4.84ZM2.392-4.31L3.271-1.792H1.499L2.392-4.31Z'/> +<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/> +<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/> +<path id='g0-73' d='M1.381-4.84H.676V0H1.381V-4.84Z'/> +<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/> +<path id='g0-79' d='M5.056-2.399C5.056-3.843 3.996-4.986 2.734-4.986S.411-3.843 .411-2.399S1.485 .146 2.734 .146C3.989 .146 5.056-.962 5.056-2.399ZM2.734-.349C1.89-.349 1.116-1.193 1.116-2.511C1.116-3.745 1.897-4.505 2.734-4.505S4.352-3.745 4.352-2.511C4.352-1.186 3.578-.349 2.734-.349Z'/> +<path id='g0-83' d='M3.445-4.645C2.999-4.875 2.601-4.986 2.085-4.986C1.032-4.986 .411-4.275 .411-3.605C.411-3.32 .502-2.985 .844-2.664C1.151-2.378 1.471-2.308 1.904-2.204C2.49-2.064 2.65-2.029 2.852-1.82C2.985-1.688 3.096-1.492 3.096-1.255C3.096-.823 2.706-.377 2.029-.377C1.632-.377 .99-.495 .439-.962L.328-.335C.676-.133 1.255 .146 2.036 .146C3.006 .146 3.696-.558 3.696-1.339C3.696-1.904 3.368-2.225 3.229-2.371C2.936-2.657 2.615-2.734 2.078-2.859C1.653-2.957 1.43-3.013 1.262-3.173C1.172-3.264 1.011-3.424 1.011-3.689C1.011-4.08 1.402-4.484 2.078-4.484C2.608-4.484 2.978-4.317 3.333-4.017L3.445-4.645Z'/> +<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/> +<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/> +<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/> +<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/> +<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/> +<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/> +<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/> +<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/> +<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/> +<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/> +<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/> +<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/> +<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/> +<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/> +<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/> +<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/> +<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/> +<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/> +<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/> +<path id='g0-121' d='M3.306-3.096H2.741C2.176-1.764 1.785-.865 1.757-.439C1.743-.635 1.618-.983 1.492-1.311C1.381-1.59 1.269-1.869 1.144-2.141L.704-3.096H.105L1.548 0C1.465 .202 1.325 .523 1.283 .614C1.137 .907 1.039 1.004 .851 1.004C.823 1.004 .565 1.004 .265 .879L.307 1.367C.37 1.381 .628 1.423 .844 1.423C1.123 1.423 1.374 1.318 1.667 .649L3.306-3.096Z'/> +<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/> +</defs> +<g id='page1'> +<path d='M139.344 212.797V203.938M196.539 212.797V203.938M253.734 212.797V203.938M310.926 212.797V203.938M139.344 69.836V78.692M196.539 69.836V78.692M253.734 69.836V78.692M310.926 69.836V78.692' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M110.746 208.192V203.938M167.941 208.192V203.938M225.137 208.192V203.938M282.332 208.192V203.938M339.524 208.192V203.938M110.746 74.442V78.692M167.941 74.442V78.692M225.137 74.442V78.692M282.332 74.442V78.692M339.524 74.442V78.692' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 203.938H86.402M82.148 172.629H86.402M82.148 141.317H86.402M82.148 110.004H86.402M82.148 78.692H86.402M368.121 203.938H363.871M368.121 172.629H363.871M368.121 141.317H363.871M368.121 110.004H363.871M368.121 78.692H363.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/> +<path d='M82.148 203.938V78.692H368.121V203.938H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -12.278 72.902)'> +<use x='114.487' y='145.434' xlink:href='#g3-99'/> +<use x='118.25' y='145.434' xlink:href='#g3-102'/> +<use x='120.838' y='145.434' xlink:href='#g3-114'/> +<use x='123.73' y='145.434' xlink:href='#g3-97'/> +<use x='127.798' y='145.434' xlink:href='#g3-99'/> +</g> +<g transform='matrix(1 0 0 1 43.353 72.902)'> +<use x='114.487' y='145.434' xlink:href='#g3-108'/> +<use x='116.507' y='145.434' xlink:href='#g3-101'/> +<use x='120.271' y='145.434' xlink:href='#g3-97'/> +<use x='124.339' y='145.434' xlink:href='#g3-110'/> +<use x='128.711' y='145.434' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 97.361 72.902)'> +<use x='114.487' y='145.434' xlink:href='#g3-108'/> +<use x='116.507' y='145.434' xlink:href='#g3-97'/> +<use x='120.34' y='145.434' xlink:href='#g3-114'/> +<use x='123.232' y='145.434' xlink:href='#g3-115'/> +<use x='126.478' y='145.434' xlink:href='#g3-111'/> +<use x='130.712' y='145.434' xlink:href='#g3-110'/> +<use x='135.085' y='145.434' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 151.766 72.902)'> +<use x='114.487' y='145.434' xlink:href='#g3-109'/> +<use x='121.211' y='145.434' xlink:href='#g3-115'/> +<use x='124.458' y='145.434' xlink:href='#g3-116'/> +<use x='127.516' y='145.434' xlink:href='#g3-114'/> +<use x='130.408' y='145.434' xlink:href='#g3-101'/> +<use x='134.171' y='145.434' xlink:href='#g3-115'/> +<use x='137.418' y='145.434' xlink:href='#g3-115'/> +<use x='140.664' y='145.434' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 200.59 72.902)'> +<use x='114.487' y='145.434' xlink:href='#g3-120'/> +<use x='118.389' y='145.434' xlink:href='#g3-109'/> +<use x='125.114' y='145.434' xlink:href='#g3-97'/> +<use x='129.182' y='145.434' xlink:href='#g3-108'/> +<use x='131.202' y='145.434' xlink:href='#g3-108'/> +<use x='133.222' y='145.434' xlink:href='#g3-111'/> +<use x='137.692' y='145.434' xlink:href='#g3-99'/> +<use x='141.455' y='145.434' xlink:href='#g3-45'/> +<use x='144.278' y='145.434' xlink:href='#g3-116'/> +<use x='147.336' y='145.434' xlink:href='#g3-101'/> +<use x='151.1' y='145.434' xlink:href='#g3-115'/> +<use x='154.346' y='145.434' xlink:href='#g3-116'/> +<use x='157.404' y='145.434' xlink:href='#g3-78'/> +</g> +<g transform='matrix(1 0 0 1 -40.942 60.139)'> +<use x='114.487' y='145.434' xlink:href='#g2-48'/> +<use x='117.133' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 28.828)'> +<use x='114.487' y='145.434' xlink:href='#g2-48'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-53'/> +<use x='121.25' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -2.484)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -33.795)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-53'/> +<use x='121.25' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(1 0 0 1 -45.059 -65.107)'> +<use x='114.487' y='145.434' xlink:href='#g2-50'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-120'/> +</g> +<path d='M82.148 141.317H368.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M96.051 203.938H99.289V141.317H96.051ZM153.246 203.938H156.484V141.317H153.246ZM210.442 203.938H213.68V141.317H210.442ZM267.637 203.938H270.875V141.317H267.637ZM324.828 203.938H328.067V141.317H324.828Z' fill='#933' clip-path='url(#clip1)'/> +<path d='M96.051 203.938H99.289V141.317H96.051ZM153.246 203.938H156.484V141.317H153.246ZM210.442 203.938H213.68V141.317H210.442ZM267.637 203.938H270.875V141.317H267.637ZM324.828 203.938H328.067V141.317H324.828Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M97.672 141.317' fill='#933' clip-path='url(#clip1)'/> +<path d='M95.68 141.317H99.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M97.672 141.317' fill='#933' clip-path='url(#clip1)'/> +<path d='M95.68 141.317H99.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M154.867 141.317V141.067' fill='#933' clip-path='url(#clip1)'/> +<path d='M154.867 141.317V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M152.871 141.066H156.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M154.867 141.317V141.567' fill='#933' clip-path='url(#clip1)'/> +<path d='M154.867 141.317V141.567' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M156.86 141.566H152.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M212.059 141.317V141.067' fill='#933' clip-path='url(#clip1)'/> +<path d='M212.059 141.317V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M210.066 141.066H214.05' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M212.059 141.317V141.567' fill='#933' clip-path='url(#clip1)'/> +<path d='M212.059 141.317V141.567' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M214.054 141.566H210.066' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M269.254 141.317V141.254' fill='#933' clip-path='url(#clip1)'/> +<path d='M269.254 141.317V141.254' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M267.262 141.254H271.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M269.254 141.317V141.379' fill='#933' clip-path='url(#clip1)'/> +<path d='M269.254 141.317V141.379' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M271.246 141.379H267.262' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M326.449 141.317V141.067' fill='#933' clip-path='url(#clip1)'/> +<path d='M326.449 141.317V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M324.457 141.066H328.441' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M326.449 141.317V141.567' fill='#933' clip-path='url(#clip1)'/> +<path d='M326.449 141.317V141.567' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M328.441 141.566H324.457' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M101.281 203.938H104.52V142.067H101.281ZM158.477 203.938H161.715V140.817H158.477ZM215.672 203.938H218.91V143.696H215.672ZM272.867 203.938H276.106V141.442H272.867ZM330.059 203.938H333.297V138.122H330.059Z' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M101.281 203.938H104.52V142.067H101.281ZM158.477 203.938H161.715V140.817H158.477ZM215.672 203.938H218.91V143.696H215.672ZM272.867 203.938H276.106V141.442H272.867ZM330.059 203.938H333.297V138.122H330.059Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M102.902 142.067' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M100.91 142.066H104.895' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M102.902 142.067' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M100.91 142.066H104.895' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M160.098 140.817V140.563' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M160.098 140.817V140.563' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M158.101 140.562H162.089' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M160.098 140.817V141.067' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M160.098 140.817V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M162.09 141.066H158.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M217.289 143.696V143.508' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M217.289 143.696V143.508' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M215.297 143.507H219.282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M217.289 143.696V143.883' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M217.289 143.696V143.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M219.285 143.883H215.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M274.484 141.442' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M272.492 141.442H276.476' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M274.484 141.442' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M272.492 141.442H276.476' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M331.68 138.122V138.059' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M331.68 138.122V138.059' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M329.688 138.058H333.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M331.68 138.122V138.184' fill='#bf8080' clip-path='url(#clip1)'/> +<path d='M331.68 138.122V138.184' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M333.671 138.183H329.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M106.512 203.938H109.75V122.028H106.512ZM163.707 203.938H166.945V128.918H163.707ZM220.902 203.938H224.141V119.961H220.902ZM278.098 203.938H281.336V139.375H278.098ZM335.289 203.938H338.527V78.692H335.289Z' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M106.512 203.938H109.75V122.028H106.512ZM163.707 203.938H166.945V128.918H163.707ZM220.902 203.938H224.141V119.961H220.902ZM278.098 203.938H281.336V139.375H278.098ZM335.289 203.938H338.527V78.692H335.289Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M108.133 122.028' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M106.14 122.028H110.125' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M108.133 122.028' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M106.14 122.028H110.125' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M165.328 128.918V128.856' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M165.328 128.918V128.856' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M163.332 128.856H167.317' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M165.328 128.918V128.981' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M165.328 128.918V128.981' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M167.321 128.981H163.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M222.52 119.961V119.836' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M222.52 119.961V119.836' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M220.527 119.836H224.512' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M222.52 119.961V120.086' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M222.52 119.961V120.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M224.512 120.086H220.527' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M279.715 139.375V139.125' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M279.715 139.375V139.125' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M277.723 139.125H281.707' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M279.715 139.375V139.625' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M279.715 139.375V139.625' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M281.708 139.625H277.723' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M336.91 78.692' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M334.918 78.691H338.902' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M336.91 78.692' fill='#8080bf' clip-path='url(#clip1)'/> +<path d='M334.918 78.691H338.902' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M111.742 203.938H114.981V120.086H111.742ZM168.938 203.938H172.176V136.43H168.938ZM226.133 203.938H229.371V136.809H226.133ZM283.328 203.938H286.567V78.692H283.328ZM340.52 203.938H343.758V112.571H340.52Z' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M111.742 203.938H114.981V120.086H111.742ZM168.938 203.938H172.176V136.43H168.938ZM226.133 203.938H229.371V136.809H226.133ZM283.328 203.938H286.567V78.692H283.328ZM340.52 203.938H343.758V112.571H340.52Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M113.363 120.086V119.899' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M113.363 120.086V119.899' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M111.371 119.899H115.356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M113.363 120.086V120.274' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M113.363 120.086V120.274' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M115.356 120.273H111.371' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M170.559 136.43' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M168.562 136.43H172.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M170.559 136.43' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M168.562 136.43H172.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M227.75 136.809' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M225.758 136.809H229.743' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M227.75 136.809' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M225.758 136.809H229.743' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M284.945 78.692' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M282.953 78.691H286.937' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M284.945 78.692' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M282.953 78.691H286.937' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M342.141 112.571V112.383' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M342.141 112.571V112.383' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M340.149 112.383H344.133' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M342.141 112.571V112.758' fill='#ffb733' clip-path='url(#clip1)'/> +<path d='M342.141 112.571V112.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M344.132 112.757H340.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M116.973 203.938H120.211V137.059H116.973ZM174.168 203.938H177.406V131.235H174.168ZM231.363 203.938H234.602V78.692H231.363ZM288.559 203.938H291.797V79.696H288.559ZM345.75 203.938H348.988V78.692H345.75Z' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M116.973 203.938H120.211V137.059H116.973ZM174.168 203.938H177.406V131.235H174.168ZM231.363 203.938H234.602V78.692H231.363ZM288.559 203.938H291.797V79.696H288.559ZM345.75 203.938H348.988V78.692H345.75Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M118.594 137.059V136.809' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M118.594 137.059V136.809' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M116.601 136.809H120.586' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M118.594 137.059V137.309' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M118.594 137.059V137.309' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M120.586 137.309H116.601' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M175.789 131.235V131.047' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M175.789 131.235V131.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M173.793 131.046H177.778' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M175.789 131.235V131.422' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M175.789 131.235V131.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M177.782 131.422H173.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M232.981 78.692' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M230.988 78.691H234.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M232.981 78.692' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M230.988 78.691H234.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M290.176 79.696V79.383' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M290.176 79.696V79.383' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M288.184 79.383H292.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M290.176 79.696V80.008' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M290.176 79.696V80.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M292.168 80.008H288.183' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M347.371 78.692' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M345.379 78.691H349.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M347.371 78.692' fill='#80bf80' clip-path='url(#clip1)'/> +<path d='M345.379 78.691H349.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M122.203 203.938H125.441V78.692H122.203ZM179.399 203.938H182.637V93.286H179.399ZM236.594 203.938H239.832V78.692H236.594ZM293.789 203.938H297.024V78.692H293.789ZM350.981 203.938H354.219V78.692H350.981Z' fill='#399' clip-path='url(#clip1)'/> +<path d='M122.203 203.938H125.441V78.692H122.203ZM179.399 203.938H182.637V93.286H179.399ZM236.594 203.938H239.832V78.692H236.594ZM293.789 203.938H297.024V78.692H293.789ZM350.981 203.938H354.219V78.692H350.981Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M123.824 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M121.832 78.691H125.817' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M123.824 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M121.832 78.691H125.817' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M181.02 93.286V93.161' fill='#399' clip-path='url(#clip1)'/> +<path d='M181.02 93.286V93.161' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M179.023 93.16H183.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M181.02 93.286V93.411' fill='#399' clip-path='url(#clip1)'/> +<path d='M181.02 93.286V93.411' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M183.012 93.41H179.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M238.211 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M236.219 78.691H240.204' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M238.211 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M236.219 78.691H240.204' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M295.406 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M293.414 78.691H297.398' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M295.406 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M293.414 78.691H297.398' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M352.602 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M350.609 78.691H354.593' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M352.602 78.692' fill='#399' clip-path='url(#clip1)'/> +<path d='M350.609 78.691H354.593' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<path d='M263.02 263.2H367.922V229.188H263.02Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/> +<g transform='matrix(1 0 0 1 151.853 114.444)'> +<use x='114.487' y='121.524' xlink:href='#g2-109'/> +<use x='118.69' y='121.524' xlink:href='#g2-97'/> +<use x='121.232' y='121.524' xlink:href='#g2-99'/> +<use x='125.349' y='121.524' xlink:href='#g2-109'/> +<use x='129.552' y='121.524' xlink:href='#g2-105'/> +<use x='130.814' y='121.524' xlink:href='#g2-110'/> +<use x='133.547' y='121.524' xlink:href='#g2-105'/> +<use x='134.81' y='121.524' xlink:href='#g2-44'/> +<use x='138.044' y='121.524' xlink:href='#g2-49'/> +<use x='140.691' y='121.524' xlink:href='#g2-54'/> +<use x='143.337' y='121.524' xlink:href='#g2-71'/> +<use x='146.866' y='121.524' xlink:href='#g2-98'/> +<use x='114.487' y='127.501' xlink:href='#g2-52'/> +<use x='117.133' y='127.501' xlink:href='#g2-45'/> +<use x='118.897' y='127.501' xlink:href='#g2-99'/> +<use x='121.25' y='127.501' xlink:href='#g2-111'/> +<use x='123.749' y='127.501' xlink:href='#g2-114'/> +<use x='125.556' y='127.501' xlink:href='#g2-101'/> +<use x='129.673' y='127.501' xlink:href='#g2-73'/> +<use x='131.143' y='127.501' xlink:href='#g2-110'/> +<use x='133.876' y='127.501' xlink:href='#g2-116'/> +<use x='135.787' y='127.501' xlink:href='#g2-101'/> +<use x='138.14' y='127.501' xlink:href='#g2-108'/> +<use x='141.166' y='127.501' xlink:href='#g2-105'/> +<use x='142.429' y='127.501' xlink:href='#g2-51'/> +<use x='146.84' y='127.501' xlink:href='#g2-64'/> +<use x='150.368' y='127.501' xlink:href='#g2-51'/> +<use x='153.015' y='127.501' xlink:href='#g2-46'/> +<use x='154.485' y='127.501' xlink:href='#g2-54'/> +<use x='157.131' y='127.501' xlink:href='#g2-71'/> +<use x='160.66' y='127.501' xlink:href='#g2-104'/> +<use x='163.392' y='127.501' xlink:href='#g2-122'/> +<use x='114.487' y='133.479' xlink:href='#g2-109'/> +<use x='118.69' y='133.479' xlink:href='#g2-97'/> +<use x='121.232' y='133.479' xlink:href='#g2-99'/> +<use x='123.585' y='133.479' xlink:href='#g2-79'/> +<use x='127.494' y='133.479' xlink:href='#g2-83'/> +<use x='132.198' y='133.479' xlink:href='#g2-67'/> +<use x='135.58' y='133.479' xlink:href='#g2-97'/> +<use x='138.122' y='133.479' xlink:href='#g2-116'/> +<use x='140.034' y='133.479' xlink:href='#g2-97'/> +<use x='142.576' y='133.479' xlink:href='#g2-108'/> +<use x='143.839' y='133.479' xlink:href='#g2-105'/> +<use x='145.101' y='133.479' xlink:href='#g2-110'/> +<use x='147.834' y='133.479' xlink:href='#g2-97'/> +<use x='152.141' y='133.479' xlink:href='#g2-49'/> +<use x='154.787' y='133.479' xlink:href='#g2-48'/> +<use x='157.434' y='133.479' xlink:href='#g2-46'/> +<use x='158.904' y='133.479' xlink:href='#g2-49'/> +<use x='161.55' y='133.479' xlink:href='#g2-53'/> +<use x='164.197' y='133.479' xlink:href='#g2-46'/> +<use x='165.667' y='133.479' xlink:href='#g2-55'/> +<use x='168.313' y='133.479' xlink:href='#g2-44'/> +<use x='171.548' y='133.479' xlink:href='#g2-65'/> +<use x='175.076' y='133.479' xlink:href='#g2-112'/> +<use x='177.809' y='133.479' xlink:href='#g2-112'/> +<use x='180.542' y='133.479' xlink:href='#g2-108'/> +<use x='181.805' y='133.479' xlink:href='#g2-101'/> +<use x='185.921' y='133.479' xlink:href='#g2-99'/> +<use x='188.273' y='133.479' xlink:href='#g2-108'/> +<use x='189.536' y='133.479' xlink:href='#g2-97'/> +<use x='192.079' y='133.479' xlink:href='#g2-110'/> +<use x='194.812' y='133.479' xlink:href='#g2-103'/> +<use x='199.222' y='133.479' xlink:href='#g2-49'/> +<use x='201.868' y='133.479' xlink:href='#g2-49'/> +<use x='204.515' y='133.479' xlink:href='#g2-46'/> +<use x='205.985' y='133.479' xlink:href='#g2-48'/> +<use x='208.631' y='133.479' xlink:href='#g2-46'/> +<use x='210.102' y='133.479' xlink:href='#g2-51'/> +<use x='114.487' y='139.456' xlink:href='#g2-56'/> +<use x='118.897' y='139.456' xlink:href='#g2-108'/> +<use x='120.16' y='139.456' xlink:href='#g2-111'/> +<use x='122.806' y='139.456' xlink:href='#g2-103'/> +<use x='125.453' y='139.456' xlink:href='#g2-105'/> +<use x='126.715' y='139.456' xlink:href='#g2-99'/> +<use x='129.068' y='139.456' xlink:href='#g2-97'/> +<use x='131.61' y='139.456' xlink:href='#g2-108'/> +<use x='134.637' y='139.456' xlink:href='#g2-99'/> +<use x='136.989' y='139.456' xlink:href='#g2-111'/> +<use x='139.489' y='139.456' xlink:href='#g2-114'/> +<use x='141.296' y='139.456' xlink:href='#g2-101'/> +<use x='143.648' y='139.456' xlink:href='#g2-115'/> +<use x='114.487' y='145.434' xlink:href='#g2-50'/> +<use x='117.133' y='145.434' xlink:href='#g2-48'/> +<use x='119.779' y='145.434' xlink:href='#g2-50'/> +<use x='122.426' y='145.434' xlink:href='#g2-49'/> +<use x='125.072' y='145.434' xlink:href='#g2-45'/> +<use x='126.836' y='145.434' xlink:href='#g2-48'/> +<use x='129.483' y='145.434' xlink:href='#g2-49'/> +<use x='132.129' y='145.434' xlink:href='#g2-45'/> +<use x='133.893' y='145.434' xlink:href='#g2-51'/> +<use x='136.54' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -46.129 249.778)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 11.066 249.778)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 68.26 249.778)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 125.455 249.778)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 182.649 249.778)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 -40.898 250.529)'> +<use x='114.487' y='145.434' xlink:href='#g2-48'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-57'/> +<use x='121.25' y='145.434' xlink:href='#g2-57'/> +</g> +<g transform='matrix(0 -1 1 0 16.296 249.277)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 73.491 252.158)'> +<use x='114.487' y='145.434' xlink:href='#g2-48'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-57'/> +<use x='121.25' y='145.434' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 130.685 249.903)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 187.88 246.584)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-53'/> +</g> +<g transform='matrix(0 -1 1 0 -35.668 230.49)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-51'/> +<use x='121.25' y='145.434' xlink:href='#g2-49'/> +</g> +<g transform='matrix(0 -1 1 0 21.527 237.378)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-50'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 78.721 228.423)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-51'/> +<use x='121.25' y='145.434' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 135.916 247.837)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-51'/> +</g> +<g transform='matrix(0 -1 1 0 193.11 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-53'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-52'/> +<use x='126.877' y='145.434' xlink:href='#g2-55'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -30.437 228.549)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-51'/> +<use x='121.25' y='145.434' xlink:href='#g2-52'/> +</g> +<g transform='matrix(0 -1 1 0 26.757 244.893)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 83.952 245.269)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 141.146 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-51'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-50'/> +<use x='126.877' y='145.434' xlink:href='#g2-49'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 198.34 221.034)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-52'/> +<use x='121.25' y='145.434' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 -25.207 245.519)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-48'/> +<use x='121.25' y='145.434' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 31.988 239.696)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-49'/> +<use x='121.25' y='145.434' xlink:href='#g2-54'/> +</g> +<g transform='matrix(0 -1 1 0 89.182 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-50'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-49'/> +<use x='126.877' y='145.434' xlink:href='#g2-52'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 146.376 188.157)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-57'/> +<use x='121.25' y='145.434' xlink:href='#g2-56'/> +</g> +<g transform='matrix(0 -1 1 0 203.571 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-52'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-52'/> +<use x='126.877' y='145.434' xlink:href='#g2-57'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -19.976 187.155)'> +<use x='114.487' y='145.434' xlink:href='#g2-50'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-50'/> +<use x='121.25' y='145.434' xlink:href='#g2-48'/> +</g> +<g transform='matrix(0 -1 1 0 37.218 201.746)'> +<use x='114.487' y='145.434' xlink:href='#g2-49'/> +<use x='117.133' y='145.434' xlink:href='#g2-46'/> +<use x='118.603' y='145.434' xlink:href='#g2-55'/> +<use x='121.25' y='145.434' xlink:href='#g2-55'/> +</g> +<g transform='matrix(0 -1 1 0 94.413 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-56'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-48'/> +<use x='126.877' y='145.434' xlink:href='#g2-52'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 151.607 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-50'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-55'/> +<use x='126.877' y='145.434' xlink:href='#g2-56'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 208.801 187.155)'> +<use x='109.598' y='145.434' xlink:href='#g4-1'/> +<use x='113.103' y='145.434' xlink:href='#g4-1'/> +<use x='116.608' y='145.434' xlink:href='#g4-1'/> +<use x='120.114' y='145.434' xlink:href='#g2-56'/> +<use x='122.76' y='145.434' xlink:href='#g2-46'/> +<use x='124.23' y='145.434' xlink:href='#g2-54'/> +<use x='126.877' y='145.434' xlink:href='#g2-49'/> +<use x='129.523' y='145.434' xlink:href='#g2-120'/> +</g> +<g transform='matrix(0 -1 1 0 -86.074 311.062)'> +<use x='114.487' y='145.434' xlink:href='#g1-82'/> +<use x='120.457' y='145.434' xlink:href='#g1-101'/> +<use x='124.553' y='145.434' xlink:href='#g1-108'/> +<use x='126.753' y='145.434' xlink:href='#g1-97'/> +<use x='131.181' y='145.434' xlink:href='#g1-116'/> +<use x='134.509' y='145.434' xlink:href='#g1-105'/> +<use x='136.709' y='145.434' xlink:href='#g1-118'/> +<use x='140.957' y='145.434' xlink:href='#g1-101'/> +<use x='148.124' y='145.434' xlink:href='#g1-116'/> +<use x='151.452' y='145.434' xlink:href='#g1-105'/> +<use x='153.652' y='145.434' xlink:href='#g1-109'/> +<use x='160.972' y='145.434' xlink:href='#g1-101'/> +<use x='168.139' y='145.434' xlink:href='#g3-40'/> +<use x='171.432' y='145.434' xlink:href='#g3-108'/> +<use x='173.453' y='145.434' xlink:href='#g3-111'/> +<use x='177.452' y='145.434' xlink:href='#g3-119'/> +<use x='183' y='145.434' xlink:href='#g3-101'/> +<use x='186.764' y='145.434' xlink:href='#g3-114'/> +<use x='192.479' y='145.434' xlink:href='#g3-105'/> +<use x='194.499' y='145.434' xlink:href='#g3-115'/> +<use x='200.568' y='145.434' xlink:href='#g3-98'/> +<use x='205.176' y='145.434' xlink:href='#g3-101'/> +<use x='208.94' y='145.434' xlink:href='#g3-116'/> +<use x='211.998' y='145.434' xlink:href='#g3-116'/> +<use x='215.056' y='145.434' xlink:href='#g3-101'/> +<use x='218.819' y='145.434' xlink:href='#g3-114'/> +<use x='221.711' y='145.434' xlink:href='#g3-41'/> +</g> +<path d='M82.348 262.243H231.688V232.317H82.348Z' fill='#fff'/> +<path d='M82.348 262.243H231.688V232.317H82.348Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<path d='M85.535 242.77H88.523V234.801H85.535ZM91.516 242.77H94.504V236.793H91.516Z' fill='#933'/> +<path d='M85.535 242.77H88.523V234.801H85.535ZM91.516 242.77H94.504V236.793H91.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -40.354 110.298)'> +<use x='141.573' y='132.464' xlink:href='#g3-120'/> +<use x='145.475' y='132.464' xlink:href='#g3-109'/> +<use x='152.2' y='132.464' xlink:href='#g3-105'/> +<use x='154.221' y='132.464' xlink:href='#g3-58'/> +<use x='156.573' y='132.464' xlink:href='#g0-57'/> +<use x='160.278' y='132.464' xlink:href='#g0-48'/> +</g> +<path d='M130.344 242.77H133.336V234.801H130.344ZM136.324 242.77H139.313V236.793H136.324Z' fill='#bf8080'/> +<path d='M130.344 242.77H133.336V234.801H130.344ZM136.324 242.77H139.313V236.793H136.324Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -38.403 110.298)'> +<use x='181.727' y='132.464' xlink:href='#g3-109'/> +<use x='188.452' y='132.464' xlink:href='#g3-105'/> +<use x='190.472' y='132.464' xlink:href='#g3-58'/> +<use x='192.825' y='132.464' xlink:href='#g0-57'/> +<use x='196.53' y='132.464' xlink:href='#g0-51'/> +</g> +<path d='M165.844 242.77H168.832V234.801H165.844ZM171.82 242.77H174.813V236.793H171.82Z' fill='#8080bf'/> +<path d='M165.844 242.77H168.832V234.801H165.844ZM171.82 242.77H174.813V236.793H171.82Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.441 109.855)'> +<use x='215.44' y='132.464' xlink:href='#g3-116'/> +<use x='218.498' y='132.464' xlink:href='#g3-99'/> +<use x='222.262' y='132.464' xlink:href='#g3-58'/> +<use x='224.614' y='132.464' xlink:href='#g0-53'/> +<use x='228.319' y='132.464' xlink:href='#g0-48'/> +</g> +<path d='M197.77 242.77H200.758V234.801H197.77ZM203.75 242.77H206.738V236.793H203.75Z' fill='#ffb733'/> +<path d='M197.77 242.77H200.758V234.801H197.77ZM203.75 242.77H206.738V236.793H203.75Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -37.04 110.298)'> +<use x='246.965' y='132.464' xlink:href='#g3-106'/> +<use x='249.221' y='132.464' xlink:href='#g3-101'/> +<use x='252.984' y='132.464' xlink:href='#g3-58'/> +<use x='255.337' y='132.464' xlink:href='#g0-53'/> +<use x='259.041' y='132.464' xlink:href='#g0-51'/> +</g> +<path d='M85.535 255.742H88.523V247.77H85.535ZM91.516 255.742H94.504V249.762H91.516Z' fill='#80bf80'/> +<path d='M85.535 255.742H88.523V247.77H85.535ZM91.516 255.742H94.504V249.762H91.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -43.882 110.334)'> +<use x='141.573' y='145.434' xlink:href='#g3-104'/> +<use x='145.946' y='145.434' xlink:href='#g3-111'/> +<use x='150.18' y='145.434' xlink:href='#g3-97'/> +<use x='154.013' y='145.434' xlink:href='#g3-114'/> +<use x='156.905' y='145.434' xlink:href='#g3-100'/> +<use x='161.278' y='145.434' xlink:href='#g3-58'/> +<use x='163.63' y='145.434' xlink:href='#g0-53'/> +<use x='167.335' y='145.434' xlink:href='#g0-51'/> +</g> +<path d='M130.344 255.742H133.336V247.77H130.344ZM136.324 255.742H139.313V249.762H136.324Z' fill='#399'/> +<path d='M130.344 255.742H133.336V247.77H130.344ZM136.324 255.742H139.313V249.762H136.324Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/> +<g transform='matrix(1 0 0 1 -39.227 109.855)'> +<use x='181.727' y='145.434' xlink:href='#g3-115'/> +<use x='184.974' y='145.434' xlink:href='#g3-121'/> +<use x='188.876' y='145.434' xlink:href='#g3-115'/> +<use x='192.122' y='145.434' xlink:href='#g3-58'/> +<use x='194.474' y='145.434' xlink:href='#g0-50'/> +<use x='198.179' y='145.434' xlink:href='#g0-51'/> +</g> +</g> +</svg>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/doc/doxyfile b/lib/Utils.Memory/mimalloc/doc/doxyfile new file mode 100644 index 0000000..55cae8b --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/doxyfile @@ -0,0 +1,2659 @@ +# Doxyfile 1.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = mi-malloc + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 1.8/2.1 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = mimalloc-logo.svg + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = .. + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 2 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = YES + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = YES + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which efficively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 0 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = NO + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = mimalloc-doc.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, +# *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: +# http://clang.llvm.org/) for more accurate parsing at the cost of reduced +# performance. This can be particularly helpful with template rich C++ code for +# which doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to +# YES then doxygen will add the directory of each input to the include path. +# The default value is: YES. + +CLANG_ADD_INC_PATHS = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the directory containing a file called compile_commands.json. This +# file is the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the +# options used when the source files were built. This is equivalent to +# specifying the -p option to a clang tool, such as clang-check. These options +# will then be passed to the parser. Any options specified with CLANG_OPTIONS +# will be added as well. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = docs + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = mimalloc-doxygen.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 189 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 12 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 240 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: +# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 180 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using JavaScript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: +# https://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = \makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag UML_LOOK is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = NO + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate +# files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc and +# plantuml temporary files. +# The default value is: YES. + +DOT_CLEANUP = YES diff --git a/lib/Utils.Memory/mimalloc/doc/ds-logo.jpg b/lib/Utils.Memory/mimalloc/doc/ds-logo.jpg Binary files differnew file mode 100644 index 0000000..c9abb1a --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/ds-logo.jpg diff --git a/lib/Utils.Memory/mimalloc/doc/ds-logo.png b/lib/Utils.Memory/mimalloc/doc/ds-logo.png Binary files differnew file mode 100644 index 0000000..93b84e4 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/ds-logo.png diff --git a/lib/Utils.Memory/mimalloc/doc/mimalloc-doc.h b/lib/Utils.Memory/mimalloc/doc/mimalloc-doc.h new file mode 100644 index 0000000..3e75243 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-doc.h @@ -0,0 +1,1281 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#error "documentation file only!" + + +/*! \mainpage + +This is the API documentation of the +[mimalloc](https://github.com/microsoft/mimalloc) allocator +(pronounced "me-malloc") -- a +general purpose allocator with excellent [performance](bench.html) +characteristics. Initially +developed by Daan Leijen for the run-time systems of the +[Koka](https://github.com/koka-lang/koka) and [Lean](https://github.com/leanprover/lean) languages. + +It is a drop-in replacement for `malloc` and can be used in other programs +without code changes, for example, on Unix you can use it as: +``` +> LD_PRELOAD=/usr/bin/libmimalloc.so myprogram +``` + +Notable aspects of the design include: + +- __small and consistent__: the library is about 8k LOC using simple and + consistent data structures. This makes it very suitable + to integrate and adapt in other projects. For runtime systems it + provides hooks for a monotonic _heartbeat_ and deferred freeing (for + bounded worst-case times with reference counting). +- __free list sharding__: instead of one big free list (per size class) we have + many smaller lists per "mimalloc page" which reduces fragmentation and + increases locality -- + things that are allocated close in time get allocated close in memory. + (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system). +- __free list multi-sharding__: the big idea! Not only do we shard the free list + per mimalloc page, but for each page we have multiple free lists. In particular, there + is one list for thread-local `free` operations, and another one for concurrent `free` + operations. Free-ing from another thread can now be a single CAS without needing + sophisticated coordination between threads. Since there will be + thousands of separate free lists, contention is naturally distributed over the heap, + and the chance of contending on a single location will be low -- this is quite + similar to randomized algorithms like skip lists where adding + a random oracle removes the need for a more complex algorithm. +- __eager page reset__: when a "page" becomes empty (with increased chance + due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged") + reducing (real) memory pressure and fragmentation, especially in long running + programs. +- __secure__: _mimalloc_ can be build in secure mode, adding guard pages, + randomized allocation, encrypted free lists, etc. to protect against various + heap vulnerabilities. The performance penalty is only around 5% on average + over our benchmarks. +- __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions. + A heap can be destroyed at once instead of deallocating each object separately. +- __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation + times (_wcat_), bounded space overhead (~0.2% meta-data, with low internal fragmentation), + and has no internal points of contention using only atomic operations. +- __fast__: In our benchmarks (see [below](#performance)), + _mimalloc_ outperforms all other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), + and usually uses less memory (up to 25% more in the worst case). A nice property + is that it does consistently well over a wide range of benchmarks. + +You can read more on the design of _mimalloc_ in the +[technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action) +which also has detailed benchmark results. + + +Further information: + +- \ref build +- \ref using +- \ref environment +- \ref overrides +- \ref bench +- \ref malloc +- \ref extended +- \ref aligned +- \ref heap +- \ref typed +- \ref analysis +- \ref options +- \ref posix +- \ref cpp + +*/ + + +/// \defgroup malloc Basic Allocation +/// The basic allocation interface. +/// \{ + + +/// Free previously allocated memory. +/// The pointer `p` must have been allocated before (or be \a NULL). +/// @param p pointer to free, or \a NULL. +void mi_free(void* p); + +/// Allocate \a size bytes. +/// @param size number of bytes to allocate. +/// @returns pointer to the allocated memory or \a NULL if out of memory. +/// Returns a unique pointer if called with \a size 0. +void* mi_malloc(size_t size); + +/// Allocate zero-initialized `size` bytes. +/// @param size The size in bytes. +/// @returns Pointer to newly allocated zero initialized memory, +/// or \a NULL if out of memory. +void* mi_zalloc(size_t size); + +/// Allocate zero-initialized \a count elements of \a size bytes. +/// @param count number of elements. +/// @param size size of each element. +/// @returns pointer to the allocated memory +/// of \a size*\a count bytes, or \a NULL if either out of memory +/// or when `count*size` overflows. +/// +/// Returns a unique pointer if called with either \a size or \a count of 0. +/// @see mi_zalloc() +void* mi_calloc(size_t count, size_t size); + +/// Re-allocate memory to \a newsize bytes. +/// @param p pointer to previously allocated memory (or \a NULL). +/// @param newsize the new required size in bytes. +/// @returns pointer to the re-allocated memory +/// of \a newsize bytes, or \a NULL if out of memory. +/// If \a NULL is returned, the pointer \a p is not freed. +/// Otherwise the original pointer is either freed or returned +/// as the reallocated result (in case it fits in-place with the +/// new size). If the pointer \a p is \a NULL, it behaves as +/// \a mi_malloc(\a newsize). If \a newsize is larger than the +/// original \a size allocated for \a p, the bytes after \a size +/// are uninitialized. +void* mi_realloc(void* p, size_t newsize); + +/// Re-allocate memory to \a count elements of \a size bytes, with extra memory initialized to zero. +/// @param p Pointer to a previously allocated block (or \a NULL). +/// @param count The number of elements. +/// @param size The size of each element. +/// @returns A pointer to a re-allocated block of \a count * \a size bytes, or \a NULL +/// if out of memory or if \a count * \a size overflows. +/// +/// If there is no overflow, it behaves exactly like `mi_rezalloc(p,count*size)`. +/// @see mi_reallocn() +/// @see [recallocarray()](http://man.openbsd.org/reallocarray) (on BSD). +void* mi_recalloc(void* p, size_t count, size_t size); + +/// Try to re-allocate memory to \a newsize bytes _in place_. +/// @param p pointer to previously allocated memory (or \a NULL). +/// @param newsize the new required size in bytes. +/// @returns pointer to the re-allocated memory +/// of \a newsize bytes (always equal to \a p), +/// or \a NULL if either out of memory or if +/// the memory could not be expanded in place. +/// If \a NULL is returned, the pointer \a p is not freed. +/// Otherwise the original pointer is returned +/// as the reallocated result since it fits in-place with the +/// new size. If \a newsize is larger than the +/// original \a size allocated for \a p, the bytes after \a size +/// are uninitialized. +void* mi_expand(void* p, size_t newsize); + +/// Allocate \a count elements of \a size bytes. +/// @param count The number of elements. +/// @param size The size of each element. +/// @returns A pointer to a block of \a count * \a size bytes, or \a NULL +/// if out of memory or if \a count * \a size overflows. +/// +/// If there is no overflow, it behaves exactly like `mi_malloc(p,count*size)`. +/// @see mi_calloc() +/// @see mi_zallocn() +void* mi_mallocn(size_t count, size_t size); + +/// Re-allocate memory to \a count elements of \a size bytes. +/// @param p Pointer to a previously allocated block (or \a NULL). +/// @param count The number of elements. +/// @param size The size of each element. +/// @returns A pointer to a re-allocated block of \a count * \a size bytes, or \a NULL +/// if out of memory or if \a count * \a size overflows. +/// +/// If there is no overflow, it behaves exactly like `mi_realloc(p,count*size)`. +/// @see [reallocarray()](<http://man.openbsd.org/reallocarray>) (on BSD) +void* mi_reallocn(void* p, size_t count, size_t size); + +/// Re-allocate memory to \a newsize bytes, +/// @param p pointer to previously allocated memory (or \a NULL). +/// @param newsize the new required size in bytes. +/// @returns pointer to the re-allocated memory +/// of \a newsize bytes, or \a NULL if out of memory. +/// +/// In contrast to mi_realloc(), if \a NULL is returned, the original pointer +/// \a p is freed (if it was not \a NULL itself). +/// Otherwise the original pointer is either freed or returned +/// as the reallocated result (in case it fits in-place with the +/// new size). If the pointer \a p is \a NULL, it behaves as +/// \a mi_malloc(\a newsize). If \a newsize is larger than the +/// original \a size allocated for \a p, the bytes after \a size +/// are uninitialized. +/// +/// @see [reallocf](https://www.freebsd.org/cgi/man.cgi?query=reallocf) (on BSD) +void* mi_reallocf(void* p, size_t newsize); + + +/// Allocate and duplicate a string. +/// @param s string to duplicate (or \a NULL). +/// @returns a pointer to newly allocated memory initialized +/// to string \a s, or \a NULL if either out of memory or if +/// \a s is \a NULL. +/// +/// Replacement for the standard [strdup()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html) +/// such that mi_free() can be used on the returned result. +char* mi_strdup(const char* s); + +/// Allocate and duplicate a string up to \a n bytes. +/// @param s string to duplicate (or \a NULL). +/// @param n maximum number of bytes to copy (excluding the terminating zero). +/// @returns a pointer to newly allocated memory initialized +/// to string \a s up to the first \a n bytes (and always zero terminated), +/// or \a NULL if either out of memory or if \a s is \a NULL. +/// +/// Replacement for the standard [strndup()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html) +/// such that mi_free() can be used on the returned result. +char* mi_strndup(const char* s, size_t n); + +/// Resolve a file path name. +/// @param fname File name. +/// @param resolved_name Should be \a NULL (but can also point to a buffer +/// of at least \a PATH_MAX bytes). +/// @returns If successful a pointer to the resolved absolute file name, or +/// \a NULL on failure (with \a errno set to the error code). +/// +/// If \a resolved_name was \a NULL, the returned result should be freed with +/// mi_free(). +/// +/// Replacement for the standard [realpath()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html) +/// such that mi_free() can be used on the returned result (if \a resolved_name was \a NULL). +char* mi_realpath(const char* fname, char* resolved_name); + +/// \} + +// ------------------------------------------------------ +// Extended functionality +// ------------------------------------------------------ + +/// \defgroup extended Extended Functions +/// Extended functionality. +/// \{ + +/// Maximum size allowed for small allocations in +/// #mi_malloc_small and #mi_zalloc_small (usually `128*sizeof(void*)` (= 1KB on 64-bit systems)) +#define MI_SMALL_SIZE_MAX (128*sizeof(void*)) + +/// Allocate a small object. +/// @param size The size in bytes, can be at most #MI_SMALL_SIZE_MAX. +/// @returns a pointer to newly allocated memory of at least \a size +/// bytes, or \a NULL if out of memory. +/// This function is meant for use in run-time systems for best +/// performance and does not check if \a size was indeed small -- use +/// with care! +void* mi_malloc_small(size_t size); + +/// Allocate a zero initialized small object. +/// @param size The size in bytes, can be at most #MI_SMALL_SIZE_MAX. +/// @returns a pointer to newly allocated zero-initialized memory of at +/// least \a size bytes, or \a NULL if out of memory. +/// This function is meant for use in run-time systems for best +/// performance and does not check if \a size was indeed small -- use +/// with care! +void* mi_zalloc_small(size_t size); + +/// Return the available bytes in a memory block. +/// @param p Pointer to previously allocated memory (or \a NULL) +/// @returns Returns the available bytes in the memory block, or +/// 0 if \a p was \a NULL. +/// +/// The returned size can be +/// used to call \a mi_expand successfully. +/// The returned size is always at least equal to the +/// allocated size of \a p, and, in the current design, +/// should be less than 16.7% more. +/// +/// @see [_msize](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/msize?view=vs-2017) (Windows) +/// @see [malloc_usable_size](http://man7.org/linux/man-pages/man3/malloc_usable_size.3.html) (Linux) +/// @see mi_good_size() +size_t mi_usable_size(void* p); + +/// Return the used allocation size. +/// @param size The minimal required size in bytes. +/// @returns the size `n` that will be allocated, where `n >= size`. +/// +/// Generally, `mi_usable_size(mi_malloc(size)) == mi_good_size(size)`. +/// This can be used to reduce internal wasted space when +/// allocating buffers for example. +/// +/// @see mi_usable_size() +size_t mi_good_size(size_t size); + +/// Eagerly free memory. +/// @param force If \a true, aggressively return memory to the OS (can be expensive!) +/// +/// Regular code should not have to call this function. It can be beneficial +/// in very narrow circumstances; in particular, when a long running thread +/// allocates a lot of blocks that are freed by other threads it may improve +/// resource usage by calling this every once in a while. +void mi_collect(bool force); + +/// Deprecated +/// @param out Ignored, outputs to the registered output function or stderr by default. +/// +/// Most detailed when using a debug build. +void mi_stats_print(void* out); + +/// Print the main statistics. +/// @param out An output function or \a NULL for the default. +/// @param arg Optional argument passed to \a out (if not \a NULL) +/// +/// Most detailed when using a debug build. +void mi_stats_print_out(mi_output_fun* out, void* arg); + +/// Reset statistics. +void mi_stats_reset(void); + +/// Merge thread local statistics with the main statistics and reset. +void mi_stats_merge(void); + +/// Initialize mimalloc on a thread. +/// Should not be used as on most systems (pthreads, windows) this is done +/// automatically. +void mi_thread_init(void); + +/// Uninitialize mimalloc on a thread. +/// Should not be used as on most systems (pthreads, windows) this is done +/// automatically. Ensures that any memory that is not freed yet (but will +/// be freed by other threads in the future) is properly handled. +void mi_thread_done(void); + +/// Print out heap statistics for this thread. +/// @param out An output function or \a NULL for the default. +/// @param arg Optional argument passed to \a out (if not \a NULL) +/// +/// Most detailed when using a debug build. +void mi_thread_stats_print_out(mi_output_fun* out, void* arg); + +/// Type of deferred free functions. +/// @param force If \a true all outstanding items should be freed. +/// @param heartbeat A monotonically increasing count. +/// @param arg Argument that was passed at registration to hold extra state. +/// +/// @see mi_register_deferred_free +typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg); + +/// Register a deferred free function. +/// @param deferred_free Address of a deferred free-ing function or \a NULL to unregister. +/// @param arg Argument that will be passed on to the deferred free function. +/// +/// Some runtime systems use deferred free-ing, for example when using +/// reference counting to limit the worst case free time. +/// Such systems can register (re-entrant) deferred free function +/// to free more memory on demand. When the \a force parameter is +/// \a true all possible memory should be freed. +/// The per-thread \a heartbeat parameter is monotonically increasing +/// and guaranteed to be deterministic if the program allocates +/// deterministically. The \a deferred_free function is guaranteed +/// to be called deterministically after some number of allocations +/// (regardless of freeing or available free memory). +/// At most one \a deferred_free function can be active. +void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg); + +/// Type of output functions. +/// @param msg Message to output. +/// @param arg Argument that was passed at registration to hold extra state. +/// +/// @see mi_register_output() +typedef void (mi_output_fun)(const char* msg, void* arg); + +/// Register an output function. +/// @param out The output function, use `NULL` to output to stderr. +/// @param arg Argument that will be passed on to the output function. +/// +/// The `out` function is called to output any information from mimalloc, +/// like verbose or warning messages. +void mi_register_output(mi_output_fun* out, void* arg); + +/// Type of error callback functions. +/// @param err Error code (see mi_register_error() for a complete list). +/// @param arg Argument that was passed at registration to hold extra state. +/// +/// @see mi_register_error() +typedef void (mi_error_fun)(int err, void* arg); + +/// Register an error callback function. +/// @param errfun The error function that is called on an error (use \a NULL for default) +/// @param arg Extra argument that will be passed on to the error function. +/// +/// The \a errfun function is called on an error in mimalloc after emitting +/// an error message (through the output function). It as always legal to just +/// return from the \a errfun function in which case allocation functions generally +/// return \a NULL or ignore the condition. The default function only calls abort() +/// when compiled in secure mode with an \a EFAULT error. The possible error +/// codes are: +/// * \a EAGAIN: Double free was detected (only in debug and secure mode). +/// * \a EFAULT: Corrupted free list or meta-data was detected (only in debug and secure mode). +/// * \a ENOMEM: Not enough memory available to satisfy the request. +/// * \a EOVERFLOW: Too large a request, for example in mi_calloc(), the \a count and \a size parameters are too large. +/// * \a EINVAL: Trying to free or re-allocate an invalid pointer. +void mi_register_error(mi_error_fun* errfun, void* arg); + +/// Is a pointer part of our heap? +/// @param p The pointer to check. +/// @returns \a true if this is a pointer into our heap. +/// This function is relatively fast. +bool mi_is_in_heap_region(const void* p); + +/// Reserve OS memory for use by mimalloc. Reserved areas are used +/// before allocating from the OS again. By reserving a large area upfront, +/// allocation can be more efficient, and can be better managed on systems +/// without `mmap`/`VirtualAlloc` (like WASM for example). +/// @param size The size to reserve. +/// @param commit Commit the memory upfront. +/// @param allow_large Allow large OS pages (2MiB) to be used? +/// @return \a 0 if successful, and an error code otherwise (e.g. `ENOMEM`). +int mi_reserve_os_memory(size_t size, bool commit, bool allow_large); + +/// Manage a particular memory area for use by mimalloc. +/// This is just like `mi_reserve_os_memory` except that the area should already be +/// allocated in some manner and available for use my mimalloc. +/// @param start Start of the memory area +/// @param size The size of the memory area. +/// @param commit Is the area already committed? +/// @param is_large Does it consist of large OS pages? Set this to \a true as well for memory +/// that should not be decommitted or protected (like rdma etc.) +/// @param is_zero Does the area consists of zero's? +/// @param numa_node Possible associated numa node or `-1`. +/// @return \a true if successful, and \a false on error. +bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node); + +/// Reserve \a pages of huge OS pages (1GiB) evenly divided over \a numa_nodes nodes, +/// but stops after at most `timeout_msecs` seconds. +/// @param pages The number of 1GiB pages to reserve. +/// @param numa_nodes The number of nodes do evenly divide the pages over, or 0 for using the actual number of NUMA nodes. +/// @param timeout_msecs Maximum number of milli-seconds to try reserving, or 0 for no timeout. +/// @returns 0 if successfull, \a ENOMEM if running out of memory, or \a ETIMEDOUT if timed out. +/// +/// The reserved memory is used by mimalloc to satisfy allocations. +/// May quit before \a timeout_msecs are expired if it estimates it will take more than +/// 1.5 times \a timeout_msecs. The time limit is needed because on some operating systems +/// it can take a long time to reserve contiguous memory if the physical memory is +/// fragmented. +int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs); + +/// Reserve \a pages of huge OS pages (1GiB) at a specific \a numa_node, +/// but stops after at most `timeout_msecs` seconds. +/// @param pages The number of 1GiB pages to reserve. +/// @param numa_node The NUMA node where the memory is reserved (start at 0). +/// @param timeout_msecs Maximum number of milli-seconds to try reserving, or 0 for no timeout. +/// @returns 0 if successfull, \a ENOMEM if running out of memory, or \a ETIMEDOUT if timed out. +/// +/// The reserved memory is used by mimalloc to satisfy allocations. +/// May quit before \a timeout_msecs are expired if it estimates it will take more than +/// 1.5 times \a timeout_msecs. The time limit is needed because on some operating systems +/// it can take a long time to reserve contiguous memory if the physical memory is +/// fragmented. +int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs); + + +/// Is the C runtime \a malloc API redirected? +/// @returns \a true if all malloc API calls are redirected to mimalloc. +/// +/// Currenty only used on Windows. +bool mi_is_redirected(); + +/// Return process information (time and memory usage). +/// @param elapsed_msecs Optional. Elapsed wall-clock time of the process in milli-seconds. +/// @param user_msecs Optional. User time in milli-seconds (as the sum over all threads). +/// @param system_msecs Optional. System time in milli-seconds. +/// @param current_rss Optional. Current working set size (touched pages). +/// @param peak_rss Optional. Peak working set size (touched pages). +/// @param current_commit Optional. Current committed memory (backed by the page file). +/// @param peak_commit Optional. Peak committed memory (backed by the page file). +/// @param page_faults Optional. Count of hard page faults. +/// +/// The \a current_rss is precise on Windows and MacOSX; other systems estimate +/// this using \a current_commit. The \a commit is precise on Windows but estimated +/// on other systems as the amount of read/write accessible memory reserved by mimalloc. +void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults); + +/// \} + +// ------------------------------------------------------ +// Aligned allocation +// ------------------------------------------------------ + +/// \defgroup aligned Aligned Allocation +/// +/// Allocating aligned memory blocks. +/// +/// \{ + +/// The maximum supported alignment size (currently 1MiB). +#define MI_ALIGNMENT_MAX (1024*1024UL) + +/// Allocate \a size bytes aligned by \a alignment. +/// @param size number of bytes to allocate. +/// @param alignment the minimal alignment of the allocated memory. Must be less than #MI_ALIGNMENT_MAX. +/// @returns pointer to the allocated memory or \a NULL if out of memory. +/// The returned pointer is aligned by \a alignment, i.e. +/// `(uintptr_t)p % alignment == 0`. +/// +/// Returns a unique pointer if called with \a size 0. +/// @see [_aligned_malloc](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc?view=vs-2017) (on Windows) +/// @see [aligned_alloc](http://man.openbsd.org/reallocarray) (on BSD, with switched arguments!) +/// @see [posix_memalign](https://linux.die.net/man/3/posix_memalign) (on Posix, with switched arguments!) +/// @see [memalign](https://linux.die.net/man/3/posix_memalign) (on Linux, with switched arguments!) +void* mi_malloc_aligned(size_t size, size_t alignment); +void* mi_zalloc_aligned(size_t size, size_t alignment); +void* mi_calloc_aligned(size_t count, size_t size, size_t alignment); +void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment); + +/// Allocate \a size bytes aligned by \a alignment at a specified \a offset. +/// @param size number of bytes to allocate. +/// @param alignment the minimal alignment of the allocated memory at \a offset. +/// @param offset the offset that should be aligned. +/// @returns pointer to the allocated memory or \a NULL if out of memory. +/// The returned pointer is aligned by \a alignment at \a offset, i.e. +/// `((uintptr_t)p + offset) % alignment == 0`. +/// +/// Returns a unique pointer if called with \a size 0. +/// @see [_aligned_offset_malloc](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-offset-malloc?view=vs-2017) (on Windows) +void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset); +void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset); +void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset); +void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset); + +/// \} + +/// \defgroup heap Heap Allocation +/// +/// First-class heaps that can be destroyed in one go. +/// +/// \{ + +/// Type of first-class heaps. +/// A heap can only be used for allocation in +/// the thread that created this heap! Any allocated +/// blocks can be freed or reallocated by any other thread though. +struct mi_heap_s; + +/// Type of first-class heaps. +/// A heap can only be used for (re)allocation in +/// the thread that created this heap! Any allocated +/// blocks can be freed by any other thread though. +typedef struct mi_heap_s mi_heap_t; + +/// Create a new heap that can be used for allocation. +mi_heap_t* mi_heap_new(); + +/// Delete a previously allocated heap. +/// This will release resources and migrate any +/// still allocated blocks in this heap (efficienty) +/// to the default heap. +/// +/// If \a heap is the default heap, the default +/// heap is set to the backing heap. +void mi_heap_delete(mi_heap_t* heap); + +/// Destroy a heap, freeing all its still allocated blocks. +/// Use with care as this will free all blocks still +/// allocated in the heap. However, this can be a very +/// efficient way to free all heap memory in one go. +/// +/// If \a heap is the default heap, the default +/// heap is set to the backing heap. +void mi_heap_destroy(mi_heap_t* heap); + +/// Set the default heap to use for mi_malloc() et al. +/// @param heap The new default heap. +/// @returns The previous default heap. +mi_heap_t* mi_heap_set_default(mi_heap_t* heap); + +/// Get the default heap that is used for mi_malloc() et al. +/// @returns The current default heap. +mi_heap_t* mi_heap_get_default(); + +/// Get the backing heap. +/// The _backing_ heap is the initial default heap for +/// a thread and always available for allocations. +/// It cannot be destroyed or deleted +/// except by exiting the thread. +mi_heap_t* mi_heap_get_backing(); + +/// Release outstanding resources in a specific heap. +void mi_heap_collect(mi_heap_t* heap, bool force); + +/// Allocate in a specific heap. +/// @see mi_malloc() +void* mi_heap_malloc(mi_heap_t* heap, size_t size); + +/// Allocate a small object in a specific heap. +/// \a size must be smaller or equal to MI_SMALL_SIZE_MAX(). +/// @see mi_malloc() +void* mi_heap_malloc_small(mi_heap_t* heap, size_t size); + +/// Allocate zero-initialized in a specific heap. +/// @see mi_zalloc() +void* mi_heap_zalloc(mi_heap_t* heap, size_t size); + +/// Allocate \a count zero-initialized elements in a specific heap. +/// @see mi_calloc() +void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size); + +/// Allocate \a count elements in a specific heap. +/// @see mi_mallocn() +void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size); + +/// Duplicate a string in a specific heap. +/// @see mi_strdup() +char* mi_heap_strdup(mi_heap_t* heap, const char* s); + +/// Duplicate a string of at most length \a n in a specific heap. +/// @see mi_strndup() +char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n); + +/// Resolve a file path name using a specific \a heap to allocate the result. +/// @see mi_realpath() +char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name); + +void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize); +void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size); +void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize); + +void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment); +void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset); +void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment); +void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset); +void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment); +void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset); +void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment); +void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset); + +/// \} + + +/// \defgroup zeroinit Zero initialized re-allocation +/// +/// The zero-initialized re-allocations are only valid on memory that was +/// originally allocated with zero initialization too. +/// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. +/// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992> +/// +/// \{ + +void* mi_rezalloc(void* p, size_t newsize); +void* mi_recalloc(void* p, size_t newcount, size_t size) ; + +void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment); +void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset); +void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment); +void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset); + +void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize); +void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size); + +void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment); +void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset); +void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment); +void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset); + +/// \} + +/// \defgroup typed Typed Macros +/// +/// Typed allocation macros. For example: +/// ``` +/// int* p = mi_malloc_tp(int) +/// ``` +/// +/// \{ + +/// Allocate a block of type \a tp. +/// @param tp The type of the block to allocate. +/// @returns A pointer to an object of type \a tp, or +/// \a NULL if out of memory. +/// +/// **Example:** +/// ``` +/// int* p = mi_malloc_tp(int) +/// ``` +/// +/// @see mi_malloc() +#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) + +/// Allocate a zero-initialized block of type \a tp. +#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) + +/// Allocate \a count zero-initialized blocks of type \a tp. +#define mi_calloc_tp(tp,count) ((tp*)mi_calloc(count,sizeof(tp))) + +/// Allocate \a count blocks of type \a tp. +#define mi_mallocn_tp(tp,count) ((tp*)mi_mallocn(count,sizeof(tp))) + +/// Re-allocate to \a count blocks of type \a tp. +#define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp))) + +/// Allocate a block of type \a tp in a heap \a hp. +#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) + +/// Allocate a zero-initialized block of type \a tp in a heap \a hp. +#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) + +/// Allocate \a count zero-initialized blocks of type \a tp in a heap \a hp. +#define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp))) + +/// Allocate \a count blocks of type \a tp in a heap \a hp. +#define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp))) + +/// Re-allocate to \a count blocks of type \a tp in a heap \a hp. +#define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp))) + +/// Re-allocate to \a count zero initialized blocks of type \a tp in a heap \a hp. +#define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp))) + +/// \} + +/// \defgroup analysis Heap Introspection +/// +/// Inspect the heap at runtime. +/// +/// \{ + +/// Does a heap contain a pointer to a previously allocated block? +/// @param heap The heap. +/// @param p Pointer to a previously allocated block (in any heap)-- cannot be some +/// random pointer! +/// @returns \a true if the block pointed to by \a p is in the \a heap. +/// @see mi_heap_check_owned() +bool mi_heap_contains_block(mi_heap_t* heap, const void* p); + +/// Check safely if any pointer is part of a heap. +/// @param heap The heap. +/// @param p Any pointer -- not required to be previously allocated by us. +/// @returns \a true if \a p points to a block in \a heap. +/// +/// Note: expensive function, linear in the pages in the heap. +/// @see mi_heap_contains_block() +/// @see mi_heap_get_default() +bool mi_heap_check_owned(mi_heap_t* heap, const void* p); + +/// Check safely if any pointer is part of the default heap of this thread. +/// @param p Any pointer -- not required to be previously allocated by us. +/// @returns \a true if \a p points to a block in default heap of this thread. +/// +/// Note: expensive function, linear in the pages in the heap. +/// @see mi_heap_contains_block() +/// @see mi_heap_get_default() +bool mi_check_owned(const void* p); + +/// An area of heap space contains blocks of a single size. +/// The bytes in freed blocks are `committed - used`. +typedef struct mi_heap_area_s { + void* blocks; ///< start of the area containing heap blocks + size_t reserved; ///< bytes reserved for this area + size_t committed; ///< current committed bytes of this area + size_t used; ///< bytes in use by allocated blocks + size_t block_size; ///< size in bytes of one block +} mi_heap_area_t; + +/// Visitor function passed to mi_heap_visit_blocks() +/// @returns \a true if ok, \a false to stop visiting (i.e. break) +/// +/// This function is always first called for every \a area +/// with \a block as a \a NULL pointer. If \a visit_all_blocks +/// was \a true, the function is then called for every allocated +/// block in that area. +typedef bool (mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); + +/// Visit all areas and blocks in a heap. +/// @param heap The heap to visit. +/// @param visit_all_blocks If \a true visits all allocated blocks, otherwise +/// \a visitor is only called for every heap area. +/// @param visitor This function is called for every area in the heap +/// (with \a block as \a NULL). If \a visit_all_blocks is +/// \a true, \a visitor is also called for every allocated +/// block in every area (with `block!=NULL`). +/// return \a false from this function to stop visiting early. +/// @param arg Extra argument passed to \a visitor. +/// @returns \a true if all areas and blocks were visited. +bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); + +/// \} + +/// \defgroup options Runtime Options +/// +/// Set runtime behavior. +/// +/// \{ + +/// Runtime options. +typedef enum mi_option_e { + // stable options + mi_option_show_errors, ///< Print error messages to `stderr`. + mi_option_show_stats, ///< Print statistics to `stderr` when the program is done. + mi_option_verbose, ///< Print verbose messages to `stderr`. + + // the following options are experimental + mi_option_eager_commit, ///< Eagerly commit segments (4MiB) (enabled by default). + mi_option_large_os_pages, ///< Use large OS pages (2MiB in size) if possible + mi_option_reserve_huge_os_pages, ///< The number of huge OS pages (1GiB in size) to reserve at the start of the program. + mi_option_reserve_huge_os_pages_at, ///< Reserve huge OS pages at node N. + mi_option_reserve_os_memory, ///< Reserve specified amount of OS memory at startup, e.g. "1g" or "512m". + mi_option_segment_cache, ///< The number of segments per thread to keep cached (0). + mi_option_page_reset, ///< Reset page memory after \a mi_option_reset_delay milliseconds when it becomes free. + mi_option_abandoned_page_reset, //< Reset free page memory when a thread terminates. + mi_option_use_numa_nodes, ///< Pretend there are at most N NUMA nodes; Use 0 to use the actual detected NUMA nodes at runtime. + mi_option_eager_commit_delay, ///< the first N segments per thread are not eagerly committed (=1). + mi_option_os_tag, ///< OS tag to assign to mimalloc'd memory + mi_option_limit_os_alloc, ///< If set to 1, do not use OS memory for allocation (but only pre-reserved arenas) + + // v1.x specific options + mi_option_eager_region_commit, ///< Eagerly commit large (256MiB) memory regions (enabled by default, except on Windows) + mi_option_segment_reset, ///< Experimental + mi_option_reset_delay, ///< Delay in milli-seconds before resetting a page (100ms by default) + mi_option_purge_decommits, ///< Experimental + + // v2.x specific options + mi_option_allow_purge, ///< Enable decommitting memory (=on) + mi_option_purge_delay, ///< Decommit page memory after N milli-seconds delay (25ms). + mi_option_segment_purge_delay, ///< Decommit large segment memory after N milli-seconds delay (500ms). + + _mi_option_last +} mi_option_t; + + +bool mi_option_is_enabled(mi_option_t option); +void mi_option_enable(mi_option_t option); +void mi_option_disable(mi_option_t option); +void mi_option_set_enabled(mi_option_t option, bool enable); +void mi_option_set_enabled_default(mi_option_t option, bool enable); + +long mi_option_get(mi_option_t option); +void mi_option_set(mi_option_t option, long value); +void mi_option_set_default(mi_option_t option, long value); + + +/// \} + +/// \defgroup posix Posix +/// +/// `mi_` prefixed implementations of various Posix, Unix, and C++ allocation functions. +/// Defined for convenience as all redirect to the regular mimalloc API. +/// +/// \{ + +void* mi_recalloc(void* p, size_t count, size_t size); +size_t mi_malloc_size(const void* p); +size_t mi_malloc_usable_size(const void *p); + +/// Just as `free` but also checks if the pointer `p` belongs to our heap. +void mi_cfree(void* p); + +int mi_posix_memalign(void** p, size_t alignment, size_t size); +int mi__posix_memalign(void** p, size_t alignment, size_t size); +void* mi_memalign(size_t alignment, size_t size); +void* mi_valloc(size_t size); + +void* mi_pvalloc(size_t size); +void* mi_aligned_alloc(size_t alignment, size_t size); + +/// Correspond s to [reallocarray](https://www.freebsd.org/cgi/man.cgi?query=reallocarray&sektion=3&manpath=freebsd-release-ports) +/// in FreeBSD. +void* mi_reallocarray(void* p, size_t count, size_t size); + +/// Corresponds to [reallocarr](https://man.netbsd.org/reallocarr.3) in NetBSD. +int mi_reallocarr(void* p, size_t count, size_t size); + +void mi_free_size(void* p, size_t size); +void mi_free_size_aligned(void* p, size_t size, size_t alignment); +void mi_free_aligned(void* p, size_t alignment); + +/// \} + +/// \defgroup cpp C++ wrappers +/// +/// `mi_` prefixed implementations of various allocation functions +/// that use C++ semantics on out-of-memory, generally calling +/// `std::get_new_handler` and raising a `std::bad_alloc` exception on failure. +/// +/// Note: use the `mimalloc-new-delete.h` header to override the \a new +/// and \a delete operators globally. The wrappers here are mostly +/// for convience for library writers that need to interface with +/// mimalloc from C++. +/// +/// \{ + +/// like mi_malloc(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure. +void* mi_new(std::size_t n) noexcept(false); + +/// like mi_mallocn(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure. +void* mi_new_n(size_t count, size_t size) noexcept(false); + +/// like mi_malloc_aligned(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure. +void* mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false); + +/// like `mi_malloc`, but when out of memory, use `std::get_new_handler` but return \a NULL on failure. +void* mi_new_nothrow(size_t n); + +/// like `mi_malloc_aligned`, but when out of memory, use `std::get_new_handler` but return \a NULL on failure. +void* mi_new_aligned_nothrow(size_t n, size_t alignment); + +/// like mi_realloc(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure. +void* mi_new_realloc(void* p, size_t newsize); + +/// like mi_reallocn(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure. +void* mi_new_reallocn(void* p, size_t newcount, size_t size); + +/// \a std::allocator implementation for mimalloc for use in STL containers. +/// For example: +/// ``` +/// std::vector<int, mi_stl_allocator<int> > vec; +/// vec.push_back(1); +/// vec.pop_back(); +/// ``` +template<class T> struct mi_stl_allocator { } + +/// \} + +/*! \page build Building + +Checkout the sources from GitHub: +``` +git clone https://github.com/microsoft/mimalloc +``` + +## Windows + +Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build (or `ide/vs2017/mimalloc.sln`). +The `mimalloc` project builds a static library (in `out/msvc-x64`), while the +`mimalloc-override` project builds a DLL for overriding malloc +in the entire program. + +## macOS, Linux, BSD, etc. + +We use [`cmake`](https://cmake.org)<sup>1</sup> as the build system: + +``` +> mkdir -p out/release +> cd out/release +> cmake ../.. +> make +``` +This builds the library as a shared (dynamic) +library (`.so` or `.dylib`), a static library (`.a`), and +as a single object file (`.o`). + +`> sudo make install` (install the library and header files in `/usr/local/lib` and `/usr/local/include`) + +You can build the debug version which does many internal checks and +maintains detailed statistics as: + +``` +> mkdir -p out/debug +> cd out/debug +> cmake -DCMAKE_BUILD_TYPE=Debug ../.. +> make +``` +This will name the shared library as `libmimalloc-debug.so`. + +Finally, you can build a _secure_ version that uses guard pages, encrypted +free lists, etc, as: +``` +> mkdir -p out/secure +> cd out/secure +> cmake -DMI_SECURE=ON ../.. +> make +``` +This will name the shared library as `libmimalloc-secure.so`. +Use `ccmake`<sup>2</sup> instead of `cmake` +to see and customize all the available build options. + +Notes: +1. Install CMake: `sudo apt-get install cmake` +2. Install CCMake: `sudo apt-get install cmake-curses-gui` + +*/ + +/*! \page using Using the library + +### Build + +The preferred usage is including `<mimalloc.h>`, linking with +the shared- or static library, and using the `mi_malloc` API exclusively for allocation. For example, +``` +gcc -o myprogram -lmimalloc myfile.c +``` + +mimalloc uses only safe OS calls (`mmap` and `VirtualAlloc`) and can co-exist +with other allocators linked to the same program. +If you use `cmake`, you can simply use: +``` +find_package(mimalloc 1.0 REQUIRED) +``` +in your `CMakeLists.txt` to find a locally installed mimalloc. Then use either: +``` +target_link_libraries(myapp PUBLIC mimalloc) +``` +to link with the shared (dynamic) library, or: +``` +target_link_libraries(myapp PUBLIC mimalloc-static) +``` +to link with the static library. See `test\CMakeLists.txt` for an example. + +### C++ +For best performance in C++ programs, it is also recommended to override the +global `new` and `delete` operators. For convience, mimalloc provides +[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) which does this for you -- just include it in a single(!) source file in your project. + +In C++, mimalloc also provides the `mi_stl_allocator` struct which implements the `std::allocator` +interface. For example: +``` +std::vector<some_struct, mi_stl_allocator<some_struct>> vec; +vec.push_back(some_struct()); +``` + +### Statistics + +You can pass environment variables to print verbose messages (`MIMALLOC_VERBOSE=1`) +and statistics (`MIMALLOC_SHOW_STATS=1`) (in the debug version): +``` +> env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363 + +175451865205073170563711388363 = 374456281610909315237213 * 468551 + +heap stats: peak total freed unit +normal 2: 16.4 kb 17.5 mb 17.5 mb 16 b ok +normal 3: 16.3 kb 15.2 mb 15.2 mb 24 b ok +normal 4: 64 b 4.6 kb 4.6 kb 32 b ok +normal 5: 80 b 118.4 kb 118.4 kb 40 b ok +normal 6: 48 b 48 b 48 b 48 b ok +normal 17: 960 b 960 b 960 b 320 b ok + +heap stats: peak total freed unit + normal: 33.9 kb 32.8 mb 32.8 mb 1 b ok + huge: 0 b 0 b 0 b 1 b ok + total: 33.9 kb 32.8 mb 32.8 mb 1 b ok +malloc requested: 32.8 mb + + committed: 58.2 kb 58.2 kb 58.2 kb 1 b ok + reserved: 2.0 mb 2.0 mb 2.0 mb 1 b ok + reset: 0 b 0 b 0 b 1 b ok + segments: 1 1 1 +-abandoned: 0 + pages: 6 6 6 +-abandoned: 0 + mmaps: 3 + mmap fast: 0 + mmap slow: 1 + threads: 0 + elapsed: 2.022s + process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb +``` + +The above model of using the `mi_` prefixed API is not always possible +though in existing programs that already use the standard malloc interface, +and another option is to override the standard malloc interface +completely and redirect all calls to the _mimalloc_ library instead. + +See \ref overrides for more info. + +*/ + +/*! \page environment Environment Options + +You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)), +or via environment variables. + +- `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates. +- `MIMALLOC_VERBOSE=1`: show verbose messages. +- `MIMALLOC_SHOW_ERRORS=1`: show error and warning messages. +- `MIMALLOC_PAGE_RESET=0`: by default, mimalloc will reset (or purge) OS pages when not in use to signal to the OS + that the underlying physical memory can be reused. This can reduce memory fragmentation in long running (server) + programs. By setting it to `0` no such page resets will be done which can improve performance for programs that are not long + running. As an alternative, the `MIMALLOC_DECOMMIT_DELAY=`<msecs> can be set higher (100ms by default) to make the page + reset occur less frequently instead of turning it off completely. +- `MIMALLOC_LARGE_OS_PAGES=1`: use large OS pages (2MiB) when available; for some workloads this can significantly + improve performance. Use `MIMALLOC_VERBOSE` to check if the large OS pages are enabled -- usually one needs + to explicitly allow large OS pages (as on [Windows][windows-huge] and [Linux][linux-huge]). However, sometimes + the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that + can have fragmented memory (for that reason, we generally recommend to use `MIMALLOC_RESERVE_HUGE_OS_PAGES` instead when possible). +- `MIMALLOC_RESERVE_HUGE_OS_PAGES=N`: where N is the number of 1GiB _huge_ OS pages. This reserves the huge pages at + startup and sometimes this can give a large (latency) performance improvement on big workloads. + Usually it is better to not use + `MIMALLOC_LARGE_OS_PAGES` in combination with this setting. Just like large OS pages, use with care as reserving + contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at + startup only once). + Note that we usually need to explicitly enable huge OS pages (as on [Windows][windows-huge] and [Linux][linux-huge])). With huge OS pages, it may be beneficial to set the setting + `MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB) + of a thread to not allocate in the huge OS pages; this prevents threads that are short lived + and allocate just a little to take up space in the huge OS page area (which cannot be reset). +- `MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N`: where N is the numa node. This reserves the huge pages at a specific numa node. + (`N` is -1 by default to reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected)) + +Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write +for all pages in the original process including the huge OS pages. When any memory is now written in that area, the +OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in big increments. + +[linux-huge]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5 +[windows-huge]: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017 + +*/ + +/*! \page overrides Overriding Malloc + +Overriding the standard `malloc` can be done either _dynamically_ or _statically_. + +## Dynamic override + +This is the recommended way to override the standard malloc interface. + + +### Linux, BSD + +On these systems we preload the mimalloc shared +library so all calls to the standard `malloc` interface are +resolved to the _mimalloc_ library. + +- `env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram` + +You can set extra environment variables to check that mimalloc is running, +like: +``` +env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram +``` +or run with the debug version to get detailed statistics: +``` +env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram +``` + +### MacOS + +On macOS we can also preload the mimalloc shared +library so all calls to the standard `malloc` interface are +resolved to the _mimalloc_ library. + +- `env DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram` + +Note that certain security restrictions may apply when doing this from +the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash). + +(Note: macOS support for dynamic overriding is recent, please report any issues.) + + +### Windows + +Overriding on Windows is robust and has the +particular advantage to be able to redirect all malloc/free calls that go through +the (dynamic) C runtime allocator, including those from other DLL's or libraries. + +The overriding on Windows requires that you link your program explicitly with +the mimalloc DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch). +Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be available +in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency). +The redirection DLL ensures that all calls to the C runtime malloc API get redirected to +mimalloc (in `mimalloc-override.dll`). + +To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some +call to the mimalloc API in the `main` function, like `mi_version()` +(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project +for an example on how to use this. For best performance on Windows with C++, it +is also recommended to also override the `new`/`delete` operations (by including +[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) a single(!) source file in your project). + +The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic +overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc was successfully redirected. + +(Note: in principle, it is possible to even patch existing executables without any recompilation +if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `mimalloc-override.dll` +into the import table (and put `mimalloc-redirect.dll` in the same folder) +Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388)). + + +## Static override + +On Unix systems, you can also statically link with _mimalloc_ to override the standard +malloc interface. The recommended way is to link the final program with the +_mimalloc_ single object file (`mimalloc-override.o`). We use +an object file instead of a library file as linkers give preference to +that over archives to resolve symbols. To ensure that the standard +malloc interface resolves to the _mimalloc_ library, link it as the first +object file. For example: + +``` +gcc -o myprogram mimalloc-override.o myfile1.c ... +``` + +## List of Overrides: + +The specific functions that get redirected to the _mimalloc_ library are: + +``` +// C +void* malloc(size_t size); +void* calloc(size_t size, size_t n); +void* realloc(void* p, size_t newsize); +void free(void* p); + +void* aligned_alloc(size_t alignment, size_t size); +char* strdup(const char* s); +char* strndup(const char* s, size_t n); +char* realpath(const char* fname, char* resolved_name); + + +// C++ +void operator delete(void* p); +void operator delete[](void* p); + +void* operator new(std::size_t n) noexcept(false); +void* operator new[](std::size_t n) noexcept(false); +void* operator new( std::size_t n, std::align_val_t align) noexcept(false); +void* operator new[]( std::size_t n, std::align_val_t align) noexcept(false); + +void* operator new ( std::size_t count, const std::nothrow_t& tag); +void* operator new[]( std::size_t count, const std::nothrow_t& tag); +void* operator new ( std::size_t count, std::align_val_t al, const std::nothrow_t&); +void* operator new[]( std::size_t count, std::align_val_t al, const std::nothrow_t&); + +// Posix +int posix_memalign(void** p, size_t alignment, size_t size); + +// Linux +void* memalign(size_t alignment, size_t size); +void* valloc(size_t size); +void* pvalloc(size_t size); +size_t malloc_usable_size(void *p); +void* reallocf(void* p, size_t newsize); + +// macOS +void vfree(void* p); +size_t malloc_size(const void* p); +size_t malloc_good_size(size_t size); + +// BSD +void* reallocarray( void* p, size_t count, size_t size ); +void* reallocf(void* p, size_t newsize); +void cfree(void* p); + +// NetBSD +int reallocarr(void* p, size_t count, size_t size); + +// Windows +void* _expand(void* p, size_t newsize); +size_t _msize(void* p); + +void* _malloc_dbg(size_t size, int block_type, const char* fname, int line); +void* _realloc_dbg(void* p, size_t newsize, int block_type, const char* fname, int line); +void* _calloc_dbg(size_t count, size_t size, int block_type, const char* fname, int line); +void* _expand_dbg(void* p, size_t size, int block_type, const char* fname, int line); +size_t _msize_dbg(void* p, int block_type); +void _free_dbg(void* p, int block_type); +``` + +*/ + +/*! \page bench Performance + +We tested _mimalloc_ against many other top allocators over a wide +range of benchmarks, ranging from various real world programs to +synthetic benchmarks that see how the allocator behaves under more +extreme circumstances. + +In our benchmarks, _mimalloc_ always outperforms all other leading +allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc) (Jan 2021), +and usually uses less memory (up to 25% more in the worst case). +A nice property is that it does *consistently* well over the wide +range of benchmarks. + +See the [Performance](https://github.com/microsoft/mimalloc#Performance) +section in the _mimalloc_ repository for benchmark results, +or the the technical report for detailed benchmark results. + +*/ diff --git a/lib/Utils.Memory/mimalloc/doc/mimalloc-doxygen.css b/lib/Utils.Memory/mimalloc/doc/mimalloc-doxygen.css new file mode 100644 index 0000000..b24f564 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-doxygen.css @@ -0,0 +1,49 @@ +#projectlogo img { + padding: 1ex; +} +tt, code, kbd, samp, div.memproto, div.fragment, div.line, table.memname { + font-family: Consolas, Monaco, Inconsolata, "Courier New", monospace; +} +.image img, .textblock img { + max-width: 99%; + max-height: 350px; +} +table.memname, .memname{ + font-weight: bold; +} +code { + background-color: #EEE; + padding: 0ex 0.25ex; +} +body { + margin: 1ex 1ex 0ex 1ex; + border: 1px solid black; +} +.contents table, .contents div, .contents p, .contents dl { + font-size: 16px; + line-height: 1.44; +} +body #nav-tree .label { + font-size: 14px; +} +a{ + text-decoration: underline; +} +#side-nav { + margin-left: 1ex; + border-left: 1px solid black; +} +#nav-tree { + padding-left: 1ex; +} +#nav-path { + display: none; +} +div.fragment { + background-color: #EEE; + padding: 0.25ex 0.5ex; + border-color: black; +} +#nav-sync img { + display: none; +} diff --git a/lib/Utils.Memory/mimalloc/doc/mimalloc-logo-100.png b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo-100.png Binary files differnew file mode 100644 index 0000000..96f0825 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo-100.png diff --git a/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.png b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.png Binary files differnew file mode 100644 index 0000000..e0a5a8c --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.png diff --git a/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.svg b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.svg new file mode 100644 index 0000000..672c7e4 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.svg @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="20mm" + height="20mm" + viewBox="0 0 10 10" + version="1.1" + id="svg8" + sodipodi:docname="mimalloc-logo.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <defs + id="defs2"> + <linearGradient + id="linearGradient6471" + osb:paint="solid"> + <stop + style="stop-color:#008da3;stop-opacity:1;" + offset="0" + id="stop6469" /> + </linearGradient> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="23.706667" + inkscape:cx="24.864771" + inkscape:cy="35.79485" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="3840" + inkscape:window-height="2050" + inkscape:window-x="-12" + inkscape:window-y="-12" + inkscape:window-maximized="1" + inkscape:snap-object-midpoints="false" + inkscape:snap-bbox="false" + inkscape:snap-bbox-midpoints="false" + inkscape:bbox-nodes="false" + inkscape:bbox-paths="false" + inkscape:snap-bbox-edge-midpoints="false" + showguides="false" + showborder="false"> + <inkscape:grid + type="xygrid" + id="grid815" + units="mm" + spacingx="0.99999997" + spacingy="0.99999997" /> + </sodipodi:namedview> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-287)"> + <circle + id="path840" + cx="5" + cy="292" + style="fill:#0d8ca4;fill-opacity:0.64444448;fill-rule:nonzero;stroke:#000000;stroke-width:0.56603777;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + r="4.7169809" /> + <ellipse + id="path4522" + style="fill:none;stroke:#000000;stroke-width:0.6;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + cx="5.171" + cy="292" + r="4.8711185" /> + <g + aria-label="malloc" + transform="matrix(0.9031136,0,0,0.80782132,0.58122269,37.023319)" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28599727" + id="text6501"> + <path + inkscape:connector-curvature="0" + d="m 1.7799307,318.87079 c 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.70159 c 0.013406,-0.0223 0.031281,-0.0469 0.05139,-0.0693 0.017875,-0.0223 0.049156,-0.0447 0.089374,-0.0693 0.040218,-0.0223 0.082671,-0.0358 0.1273581,-0.0358 0.040218,0 0.078202,0.0179 0.1117177,0.0536 0.031281,0.0358 0.049156,0.0827 0.049156,0.143 v 0.67924 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.67924 -0.0223 c 0.0067,-0.0112 0.01564,-0.0223 0.024578,-0.0358 0.00894,-0.0134 0.022344,-0.0268 0.040218,-0.0447 0.017875,-0.0179 0.03575,-0.0335 0.053624,-0.0469 0.017875,-0.0134 0.042453,-0.0246 0.069265,-0.0335 0.026812,-0.009 0.053625,-0.0134 0.080437,-0.0134 0.040218,0 0.078202,0.0179 0.1117177,0.0536 0.031281,0.0358 0.049156,0.0827 0.049156,0.143 v 0.67924 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.67924 c 0,-0.11396 -0.037984,-0.21003 -0.1094833,-0.29047 -0.073734,-0.0804 -0.1631078,-0.12066 -0.2658881,-0.12066 -0.073734,0 -0.1407643,0.0156 -0.1988575,0.0425 -0.058093,0.0268 -0.1094833,0.0626 -0.1541704,0.10725 -0.075968,-0.0983 -0.1720452,-0.14971 -0.290466,-0.14971 -0.1027802,0 -0.1943887,0.029 -0.2748255,0.0849 -0.00894,-0.0179 -0.022343,-0.0335 -0.040218,-0.0469 -0.017875,-0.0134 -0.037984,-0.0201 -0.060328,-0.0201 -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 0.96524 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727" + id="path6515" /> + <path + inkscape:connector-curvature="0" + d="m 4.2824069,317.69105 c -0.01564,0 -0.029047,0.004 -0.042453,0.009 -0.013406,0.007 -0.026812,0.0156 -0.03575,0.0246 -0.00894,0.0112 -0.017875,0.0223 -0.022344,0.0335 -0.078202,-0.0559 -0.1631079,-0.0849 -0.2569507,-0.0849 -0.145233,0 -0.2658881,0.0626 -0.359731,0.18322 -0.093843,0.12066 -0.1407642,0.26366 -0.1407642,0.42453 0,0.16311 0.046921,0.30611 0.1407642,0.42676 0.093843,0.12066 0.214498,0.18098 0.359731,0.18098 0.093843,0 0.1787483,-0.0268 0.2569507,-0.0849 0.00894,0.0201 0.022344,0.0358 0.040218,0.0491 0.017875,0.0134 0.037984,0.0179 0.060328,0.0179 0.029047,0 0.053625,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.96524 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z m -0.107249,0.77979 c -0.017875,0.0424 -0.040218,0.0782 -0.067031,0.10948 -0.026812,0.0313 -0.055859,0.0559 -0.08714,0.0715 -0.031281,0.0156 -0.064796,0.0224 -0.096077,0.0224 -0.073734,0 -0.1407643,-0.0358 -0.1988575,-0.10949 -0.058093,-0.0737 -0.08714,-0.16757 -0.08714,-0.28376 0,-0.11395 0.029047,-0.2078 0.08714,-0.28153 0.058093,-0.0737 0.1251238,-0.11172 0.1988575,-0.11172 0.049156,0 0.098312,0.0179 0.1429986,0.0536 0.044687,0.0358 0.080437,0.0871 0.107249,0.1497 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727" + id="path6517" /> + <path + inkscape:connector-curvature="0" + d="m 4.7471525,317.2263 c -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 1.21549 c 0,0.10502 0.0067,0.18545 0.022343,0.24131 0.00447,0.0268 0.017875,0.0469 0.037984,0.0603 0.017875,0.0134 0.040218,0.0201 0.064796,0.0201 0.00894,0 0.017875,0 0.026812,-0.002 0.00447,-0.002 0.011172,-0.004 0.017875,-0.009 0.0067,-0.002 0.013406,-0.004 0.017875,-0.009 0.00447,-0.004 0.011172,-0.009 0.01564,-0.0134 0.00447,-0.004 0.0067,-0.0112 0.011172,-0.0156 0.00447,-0.004 0.0067,-0.0112 0.00894,-0.0179 0.00223,-0.007 0.00447,-0.0134 0.0067,-0.0201 0,-0.007 0.00223,-0.0134 0.00223,-0.0201 v -0.007 c 0,-0.002 -0.00223,-0.004 -0.00223,-0.007 0,-0.002 0,-0.004 0,-0.009 -0.011172,-0.0447 -0.01564,-0.10725 -0.01564,-0.19216 v -1.21549 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727" + id="path6519" /> + <path + inkscape:connector-curvature="0" + d="m 5.2655226,317.2263 c -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 1.21549 c 0,0.10502 0.0067,0.18545 0.022344,0.24131 0.00447,0.0268 0.017875,0.0469 0.037984,0.0603 0.017875,0.0134 0.040218,0.0201 0.064796,0.0201 0.00894,0 0.017875,0 0.026812,-0.002 0.00447,-0.002 0.011172,-0.004 0.017875,-0.009 0.0067,-0.002 0.013406,-0.004 0.017875,-0.009 0.00447,-0.004 0.011172,-0.009 0.01564,-0.0134 0.00447,-0.004 0.0067,-0.0112 0.011172,-0.0156 0.00447,-0.004 0.0067,-0.0112 0.00894,-0.0179 0.00223,-0.007 0.00447,-0.0134 0.0067,-0.0201 0,-0.007 0.00223,-0.0134 0.00223,-0.0201 v -0.007 c 0,-0.002 -0.00223,-0.004 -0.00223,-0.007 0,-0.002 0,-0.004 0,-0.009 -0.011172,-0.0447 -0.01564,-0.10725 -0.01564,-0.19216 v -1.21549 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727" + id="path6521" /> + <path + inkscape:connector-curvature="0" + d="m 6.6061344,318.28092 c 0,-0.16087 -0.049156,-0.30387 -0.1429986,-0.42453 -0.093843,-0.12065 -0.2144979,-0.18322 -0.3574966,-0.18322 -0.145233,0 -0.2658881,0.0626 -0.3597309,0.18322 -0.093843,0.12066 -0.1407643,0.26366 -0.1407643,0.42453 0,0.16311 0.046921,0.30611 0.1407643,0.42676 0.093843,0.12066 0.2144979,0.18098 0.3597309,0.18098 0.1429987,0 0.2636538,-0.0603 0.3574966,-0.18098 0.093843,-0.12065 0.1429986,-0.26365 0.1429986,-0.42676 z m -0.2144979,0 c 0,0.11619 -0.031281,0.21003 -0.089374,0.28376 -0.058093,0.0737 -0.1251238,0.10949 -0.1966231,0.10949 -0.073734,0 -0.1407643,-0.0358 -0.1988575,-0.10949 -0.058093,-0.0737 -0.08714,-0.16757 -0.08714,-0.28376 0,-0.11395 0.029047,-0.2078 0.08714,-0.28153 0.058093,-0.0737 0.1251238,-0.11172 0.1988575,-0.11172 0.071499,0 0.1385299,0.038 0.1966231,0.11172 0.058093,0.0737 0.089374,0.16758 0.089374,0.28153 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727" + id="path6523" /> + <path + inkscape:connector-curvature="0" + d="m 7.6406407,318.47754 c -0.00894,-0.004 -0.01564,-0.007 -0.024578,-0.009 -0.00894,-0.002 -0.017875,-0.004 -0.026812,-0.004 -0.044687,0 -0.075968,0.0201 -0.093843,0.0559 -0.026812,0.0514 -0.060328,0.0894 -0.098312,0.11618 -0.040218,0.0268 -0.080437,0.038 -0.1206551,0.038 -0.071499,0 -0.1340612,-0.0358 -0.1921544,-0.10949 -0.058093,-0.0737 -0.084905,-0.16757 -0.084905,-0.28376 0,-0.11395 0.026812,-0.2078 0.084905,-0.28153 0.058093,-0.0737 0.1206551,-0.11172 0.1921544,-0.11172 0.080437,0 0.1474674,0.0447 0.2055606,0.1296 0.020109,0.0335 0.049156,0.0491 0.089374,0.0491 0.022343,0 0.040218,-0.004 0.058093,-0.0179 0.0067,-0.004 0.013406,-0.009 0.020109,-0.0156 0.0067,-0.007 0.011172,-0.0134 0.01564,-0.0224 0.00447,-0.009 0.0067,-0.0156 0.00894,-0.0246 0.00223,-0.009 0.00447,-0.0179 0.00447,-0.0268 0,-0.004 -0.00223,-0.0112 -0.00223,-0.0156 0,-0.004 -0.00223,-0.009 -0.00223,-0.0134 -0.00223,-0.004 -0.00447,-0.0112 -0.0067,-0.0156 -0.00223,-0.004 -0.00447,-0.009 -0.0067,-0.0134 -0.031281,-0.0447 -0.064796,-0.0827 -0.1027803,-0.11619 -0.037984,-0.0335 -0.080437,-0.0603 -0.1295925,-0.0804 -0.049156,-0.0201 -0.1005459,-0.0313 -0.1519361,-0.0313 -0.1429986,0 -0.2614194,0.0626 -0.3530279,0.18322 -0.093843,0.12066 -0.1385299,0.26366 -0.1385299,0.42453 0,0.16311 0.044687,0.30611 0.1385299,0.42676 0.091608,0.12066 0.2100293,0.18098 0.3530279,0.18098 0.084905,0 0.1631078,-0.0246 0.2346072,-0.0737 0.071499,-0.0492 0.1273581,-0.11172 0.1720452,-0.19215 0.0067,-0.0134 0.011172,-0.0313 0.013406,-0.0514 0,-0.0425 -0.020109,-0.0737 -0.055859,-0.0939 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727" + id="path6525" /> + </g> + <g + aria-label="m" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3694315px;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578" + id="text848"> + <path + d="m 2.3718985,293.17081 c 0.080862,0 0.1492836,-0.0249 0.211485,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.95313 c 0.037321,-0.0622 0.087082,-0.13062 0.1430634,-0.19282 0.049761,-0.0622 0.1368433,-0.1244 0.2488059,-0.19283 0.1119627,-0.0622 0.2301455,-0.0995 0.3545485,-0.0995 0.1119626,0 0.2177051,0.0498 0.3110074,0.14929 0.087082,0.0995 0.1368432,0.23014 0.1368432,0.39808 v 1.89093 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.89093 -0.0622 c 0.018661,-0.0311 0.043541,-0.0622 0.068422,-0.0995 0.024881,-0.0373 0.062201,-0.0746 0.1119626,-0.1244 0.049761,-0.0498 0.099522,-0.0933 0.1492836,-0.13063 0.049761,-0.0373 0.1181828,-0.0684 0.1928246,-0.0933 0.074642,-0.0249 0.1492835,-0.0373 0.2239253,-0.0373 0.1119626,0 0.2177052,0.0498 0.3110074,0.14929 0.087082,0.0995 0.1368432,0.23014 0.1368432,0.39808 v 1.89093 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.89093 c 0,-0.31722 -0.1057425,-0.58469 -0.3047872,-0.80861 -0.2052649,-0.22393 -0.4540708,-0.33589 -0.7401976,-0.33589 -0.2052649,0 -0.3918693,0.0435 -0.5535932,0.11818 -0.1617238,0.0746 -0.3047872,0.17416 -0.4291902,0.29857 -0.211485,-0.27369 -0.4789514,-0.41675 -0.8086192,-0.41675 -0.2861268,0 -0.5411529,0.0809 -0.7650782,0.23636 -0.024881,-0.0498 -0.062202,-0.0933 -0.1119627,-0.13062 -0.049761,-0.0373 -0.1057425,-0.056 -0.167944,-0.056 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.087082,0.13062 -0.087082,0.21149 v 2.6871 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.1244029,0.0871 0.211485,0.0871 z" + style="stroke-width:0.15923578" + id="path834" /> + </g> + <g + id="g28" + transform="translate(-0.23995531,0.02790178)"> + <g + id="g835"> + <g + transform="matrix(1.0000001,0,0,0.98554676,-7.6075554e-7,4.2369817)" + id="g25"> + <path + d="m 7.426334,293.15097 c 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21149 v -2.6871 c 0,-0.0809 -0.031101,-0.14928 -0.087082,-0.21149 -0.062201,-0.056 -0.1306232,-0.0871 -0.2114851,-0.0871 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.087082,0.13063 -0.087082,0.21149 v 2.6871 c 0,0.0871 0.024881,0.15551 0.087082,0.21149 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578" + id="path896" + inkscape:connector-curvature="0" /> + </g> + <path + d="m 7.4249389,289.61754 c 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.086228,-0.1244 0.087082,-0.21149 l 0.0014,-0.14231 c 7.93e-4,-0.0809 -0.031101,-0.14929 -0.087082,-0.21149 -0.062201,-0.056 -0.1306232,-0.0871 -0.2114851,-0.0871 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.086289,0.13062 -0.087082,0.21149 l -0.0014,0.14231 c -8.538e-4,0.0871 0.024881,0.15551 0.087082,0.21149 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578" + id="path898" + inkscape:connector-curvature="0" + sodipodi:nodetypes="scsscscsscs" /> + </g> + </g> + </g> +</svg> diff --git a/lib/Utils.Memory/mimalloc/doc/spades-logo.png b/lib/Utils.Memory/mimalloc/doc/spades-logo.png Binary files differnew file mode 100644 index 0000000..d8c73fe --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/spades-logo.png diff --git a/lib/Utils.Memory/mimalloc/doc/unreal-logo.svg b/lib/Utils.Memory/mimalloc/doc/unreal-logo.svg new file mode 100644 index 0000000..5d5192a --- /dev/null +++ b/lib/Utils.Memory/mimalloc/doc/unreal-logo.svg @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + height="706.71118" + width="746.71118" + viewBox="-150.3282 -273.04775 810.70706 1447.2442" + version="1.1" + id="svg34" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs24"> + <clipPath + id="a" + clipPathUnits="userSpaceOnUse"> + <path + d="M 0,1024 H 1024 V 0 H 0 Z" + id="path21" /> + </clipPath> + </defs> + <rect + style="fill:#b2b2b2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.04786;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect121" + width="1300.7299" + height="1264.0651" + x="-391.91745" + y="-186.69598" + rx="154.79872" + ry="154.79872" /> + <path + d="m 693.86447,863.90527 v -94.746 h -35.855 v 122.747 h 120.26 v -28 z" + id="path26" /> + <g + clip-path="url(#a)" + transform="matrix(1.33333,0,0,-1.33333,-408.39652,1133.2393)" + id="g32"> + <path + d="m 498.837,117.958 h 20.085 c 0.498,-5.295 -1.063,-7.971 -5.392,-8.386 -4.293,-0.411 -8.612,-0.76 -12.92,-0.77 -17.903,-0.044 -19.822,2.052 -18.737,19.932 0.02,0.333 0.03,0.666 0.063,0.997 0.67,6.667 3.126,9.189 9.81,9.499 5.15,0.238 10.316,0.089 15.476,0.132 5.373,0.044 10.5,-0.337 11.806,-6.626 h 13.198 c 1.86,10.558 -1.6,16.306 -11.74,16.9 -13.059,0.767 -26.228,0.648 -39.293,-0.086 -8.782,-0.493 -13.292,-5.67 -13.804,-14.27 -0.444,-7.454 -0.42,-14.975 -0.007,-22.434 0.441,-7.953 4.16,-11.928 11.938,-13.918 2.87,-0.734 5.785,-1.29 8.68,-1.928 h 26 c 2.091,0.444 4.177,0.913 6.274,1.328 5.615,1.11 11.135,2.918 12.264,9.28 1.114,6.278 1.061,12.763 1.546,19.515 h -35.247 z m -103.4,63.438 v 91.393 h -26.424 v -69.795 l -54.236,70.22 H 273.38 V 181.28 h 26.308 v 68.354 l 1.226,0.31 53.645,-68.547 z m 47.577,45.635 v 26.323 c 12.208,0 24.12,0.002 36.033,-0.003 1.662,0 3.323,-0.048 4.985,-0.059 14.801,-0.1 16.353,-4.42 14.866,-18.979 -0.484,-4.738 -4.073,-7.103 -8.306,-7.175 -15.731,-0.268 -31.469,-0.107 -47.578,-0.107 m 56.443,-33.406 c 0.357,-4.063 0.548,-8.14 0.82,-12.3 h 26.391 c 0,5.758 0.219,11.061 -0.045,16.34 -0.581,11.61 -2.289,16.735 -13.599,18.696 -0.592,0.103 -1.114,0.614 -2.506,1.42 11.369,2.53 15.442,10.208 15.981,20.201 0.267,4.96 0.176,10.017 -0.484,14.932 -1.604,11.95 -5.993,16.673 -17.761,18.885 a 101.743,101.743 0 0 1 -17.843,1.741 c -22.818,0.197 -45.638,0.09 -68.458,0.066 -1.78,-0.002 -3.559,-0.22 -5.646,-0.36 v -91.884 h 26.535 v 25.35 c 6.04,0 11.509,0.111 16.972,-0.025 9.644,-0.24 19.344,-0.086 28.908,-1.129 7.832,-0.854 10.041,-4.046 10.735,-11.933 m 73.129,24.754 h 68.786 v 18.565 h -68.899 v 16.585 h 72.852 v 19.517 h -99.79 v -91.744 h 101.018 v 20.193 h -73.967 z m -319.109,52.037 c 0.004,0.918 -0.563,1.84 -0.847,2.708 h -26.34 c 0,-16.299 0.052,-32.104 -0.036,-47.909 -0.025,-4.314 -0.31,-8.644 -0.772,-12.935 -0.665,-6.161 -4.552,-10.04 -10.412,-10.334 -12.098,-0.61 -24.283,-1.056 -36.347,-0.266 -9.717,0.635 -12.873,4.996 -12.984,14.895 -0.19,16.997 -0.103,33.998 -0.188,50.997 -0.009,1.895 -0.385,3.789 -0.59,5.67 h -26.32 c 0,-22.846 -0.788,-45.02 0.27,-67.106 0.734,-15.35 7.1,-21.4 22.59,-23.992 22.481,-3.765 45.194,-3.61 67.677,-0.266 17.168,2.553 22.995,8.927 23.753,26.069 0.92,20.79 0.464,41.644 0.546,62.47 m 447.926,-53.371 19.515,38.362 19.723,-38.362 z m 2.8,56.306 -49.975,-92.133 h 28.863 l 8.345,15.905 h 59.333 l 8.375,-15.847 h 29.165 l -50.248,92.075 z m -264.917,-161.351 -1.233,-0.292 a 532757.74,532757.74 0 0 1 -30.02,38.7 h -23.4 v -51.93 h 14.433 v 37.887 l 1.47,0.522 30.288,-38.488 h 23.367 v 51.89 h -14.904 z m 187.996,-0.026 -1.193,-0.31 c -9.93,12.813 -19.858,25.627 -29.476,38.039 H 573.309 V 98.583 h 14.777 v 39.2 l 30.889,-39.43 h 23.009 v 51.189 h -14.702 z m -295.244,7.284 h 39.176 v 10.717 H 332.04 v 9.647 h 41.322 V 150.45 H 317.11 V 98.519 h 57.303 v 11.039 h -42.375 z m 338.914,0.018 h 38.455 v 10.44 H 671.1 v 9.635 h 40.57 v 10.3 H 655.83 V 98.556 h 56.742 v 10.952 h -41.62 z M 545.666,98.416 h 14.301 v 51.189 H 545.666 Z M 312.554,585.913 c 0,0 -10.463,51.999 44.874,114.973 55.342,62.972 96.863,85.871 141.707,97.799 l -0.078,-0.046 0.17,0.046 c 0,0 -35.227,-20.517 -35.227,-51.522 0,-9 1.435,-15.184 3.423,-19.315 2.638,-5.488 6.816,-7.354 10.567,-7.372 3.16,-0.018 5.01,1.281 9.01,2.834 V 555.386 c 0,0 0.433,-2.707 2.863,-5.915 3.5,-4.613 9,-10.243 19.335,-10.3 17.629,0.113 39.802,20.026 39.802,20.026 v 135.964 c 0,13.832 -9.9,30.53 -20.39,36.259 0,0 1.43,0.09 3.744,0.089 6.926,0.002 21.784,-0.79 30.063,-7.115 2.3,2.665 39.418,44.665 105.466,57.589 l -0.032,-0.037 0.18,0.037 c 0,0 -36.531,-43.016 -47.981,-64.348 -2.035,-0.121 -2.332,-40.471 -1.993,-80.79 0.329,-38.92 1.253,-77.818 1.789,-80.509 0,0 3.898,-5.794 13.824,-5.844 11.196,-0.057 30.063,7.195 59.643,38.288 l -10e-4,-10e-4 v 10e-4 c 0,0 -0.78,-1.771 -2.35,-4.908 -8.476,-16.938 -39.974,-73.721 -95.924,-106.725 l -0.003,0.003 -0.005,-0.003 -36.29,30.693 -0.927,0.774 -39.58,-41.967 -0.06,0.006 -0.005,-0.006 c 0,0 -90.232,7.633 -127.92,62.015 l 0.179,-0.065 -0.047,0.065 c 0,0 5.707,-2.221 12.148,-2.342 7.547,-0.138 15.472,2.619 15.472,15.229 v 127.85 c 0,6.529 -4.495,13.853 -14.362,13.825 -8.874,-0.023 -21.614,-5.994 -39.01,-23.843 -36.734,-37.685 -51.99,-73.468 -51.99,-73.468 l -0.025,0.136 -0.06,-0.136 M 513,369.156 c 70.386,0 136.56,27.41 186.33,77.18 49.77,49.771 77.18,115.944 77.18,186.33 0,70.386 -27.41,136.559 -77.18,186.33 -49.77,49.77 -115.944,77.18 -186.33,77.18 -70.386,0 -136.56,-27.41 -186.33,-77.18 -49.77,-49.771 -77.18,-115.944 -77.18,-186.33 0,-70.386 27.41,-136.559 77.18,-186.33 49.77,-49.77 115.944,-77.18 186.33,-77.18" + id="path28" /> + <path + d="m 513,908.307 c 152.232,0 275.641,-123.409 275.641,-275.64 0,-152.233 -123.409,-275.642 -275.641,-275.642 -152.232,0 -275.641,123.41 -275.641,275.641 0,152.232 123.409,275.641 275.641,275.641 m 0,-559.119 c 75.72,0 146.907,29.487 200.449,83.03 53.542,53.541 83.028,124.728 83.028,200.448 0,75.72 -29.486,146.907 -83.028,200.45 -53.542,53.54 -124.729,83.026 -200.449,83.026 -75.72,0 -146.907,-29.486 -200.449,-83.028 -53.542,-53.542 -83.028,-124.73 -83.028,-200.449 0,-75.72 29.486,-146.907 83.028,-200.449 C 366.093,378.674 437.28,349.188 513,349.188" + id="path30" /> + </g> +</svg> diff --git a/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj new file mode 100644 index 0000000..04c16a9 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7868F-750E-4C21-A04D-22707CC66879}</ProjectGuid> + <RootNamespace>mimalloc-override-test</RootNamespace> + <ProjectName>mimalloc-override-test</ProjectName> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <ExceptionHandling>false</ExceptionHandling> + <CompileAs>Default</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent /> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <ExceptionHandling>Sync</ExceptionHandling> + <CompileAs>Default</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent /> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="mimalloc-override.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea7}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\test\main-override.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override.vcxproj new file mode 100644 index 0000000..3d5c1f7 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override.vcxproj @@ -0,0 +1,259 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{ABB5EAE7-B3E6-432E-B636-333449892EA7}</ProjectGuid> + <RootNamespace>mimalloc-override</RootNamespace> + <ProjectName>mimalloc-override</ProjectName> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <SupportJustMyCode>false</SupportJustMyCode> + <CompileAs>Default</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries> + </IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect32.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy mimalloc-redirect32.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <SupportJustMyCode>false</SupportJustMyCode> + <CompileAs>Default</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries> + </IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>copy mimalloc-redirect.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <CompileAs>Default</CompileAs> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect32.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy mimalloc-redirect32.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <CompileAs>Default</CompileAs> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>copy mimalloc-redirect.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" /> + <ClInclude Include="..\..\include\mimalloc-new-delete.h" /> + <ClInclude Include="..\..\include\mimalloc-override.h" /> + <ClInclude Include="..\..\include\mimalloc\atomic.h" /> + <ClInclude Include="..\..\include\mimalloc\internal.h" /> + <ClInclude Include="..\..\include\mimalloc\prim.h" /> + <ClInclude Include="..\..\include\mimalloc\track.h" /> + <ClInclude Include="..\..\include\mimalloc\types.h" /> + <ClInclude Include="..\..\src\bitmap.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\alloc-aligned.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-override.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-posix.c" /> + <ClCompile Include="..\..\src\alloc.c" /> + <ClCompile Include="..\..\src\arena.c" /> + <ClCompile Include="..\..\src\bitmap.c" /> + <ClCompile Include="..\..\src\heap.c" /> + <ClCompile Include="..\..\src\init.c" /> + <ClCompile Include="..\..\src\prim\prim.c" /> + <ClCompile Include="..\..\src\options.c" /> + <ClCompile Include="..\..\src\os.c" /> + <ClCompile Include="..\..\src\page-queue.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\page.c" /> + <ClCompile Include="..\..\src\random.c" /> + <ClCompile Include="..\..\src\segment-map.c" /> + <ClCompile Include="..\..\src\segment.c" /> + <ClCompile Include="..\..\src\stats.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj new file mode 100644 index 0000000..061b860 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7958F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloc-test-stress</RootNamespace> + <ProjectName>mimalloc-test-stress</ProjectName> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\test-stress.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test.vcxproj new file mode 100644 index 0000000..04bd653 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7858F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloctest</RootNamespace> + <ProjectName>mimalloc-test</ProjectName> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <LanguageStandard>stdcpp14</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\test\main-override-static.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.sln b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.sln new file mode 100644 index 0000000..515c03f --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.sln @@ -0,0 +1,71 @@ +
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.102
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test", "mimalloc-test.vcxproj", "{FEF7858F-750E-4C21-A04D-22707CC66878}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimalloc-override.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
+ {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32
+ {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32
+ {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
+ {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4297F93D-486A-4243-995F-7D32F59AE82A}
+ EndGlobalSection
+EndGlobal
diff --git a/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.vcxproj new file mode 100644 index 0000000..46eb05d --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.vcxproj @@ -0,0 +1,259 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{ABB5EAE7-B3E6-432E-B636-333449892EA6}</ProjectGuid> + <RootNamespace>mimalloc</RootNamespace> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Label="LLVM" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <UseLlvmLib>false</UseLlvmLib> + </PropertyGroup> + <PropertyGroup Label="LLVM" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <UseLlvmLib>false</UseLlvmLib> + </PropertyGroup> + <PropertyGroup Label="LLVM" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <UseLlvmLib>false</UseLlvmLib> + </PropertyGroup> + <PropertyGroup Label="LLVM" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <UseLlvmLib>false</UseLlvmLib> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <CompileAs>CompileAsC</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <CompileAs>CompileAsCpp</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + <LanguageStandard>stdcpp14</LanguageStandard> + </ClCompile> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + <Link> + <EntryPointSymbol> + </EntryPointSymbol> + </Link> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <CompileAs>CompileAsC</CompileAs> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <CompileAs>CompileAsC</CompileAs> + <IntrinsicFunctions>true</IntrinsicFunctions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <EntryPointSymbol> + </EntryPointSymbol> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\src\alloc-aligned.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-override.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-posix.c" /> + <ClCompile Include="..\..\src\alloc.c" /> + <ClCompile Include="..\..\src\arena.c" /> + <ClCompile Include="..\..\src\bitmap.c" /> + <ClCompile Include="..\..\src\heap.c" /> + <ClCompile Include="..\..\src\init.c" /> + <ClCompile Include="..\..\src\prim\prim.c" /> + <ClCompile Include="..\..\src\options.c" /> + <ClCompile Include="..\..\src\page-queue.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\page.c" /> + <ClCompile Include="..\..\src\random.c" /> + <ClCompile Include="..\..\src\segment-map.c" /> + <ClCompile Include="..\..\src\segment.c" /> + <ClCompile Include="..\..\src\os.c" /> + <ClCompile Include="..\..\src\stats.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" /> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc-override.h" /> + <ClInclude Include="..\..\include\mimalloc-new-delete.h" /> + <ClInclude Include="..\..\include\mimalloc\atomic.h" /> + <ClInclude Include="..\..\include\mimalloc\internal.h" /> + <ClInclude Include="..\..\include\mimalloc\prim.h" /> + <ClInclude Include="..\..\include\mimalloc\track.h" /> + <ClInclude Include="..\..\include\mimalloc\types.h" /> + <ClInclude Include="..\..\src\bitmap.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj new file mode 100644 index 0000000..7a9202f --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7868F-750E-4C21-A04D-22707CC66879}</ProjectGuid> + <RootNamespace>mimalloc-override-test</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-override-test</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <ExceptionHandling>Sync</ExceptionHandling> + <CompileAs>Default</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent /> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <ExceptionHandling>Sync</ExceptionHandling> + <CompileAs>Default</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent /> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\main-override.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc-override.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea7}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override.vcxproj new file mode 100644 index 0000000..1c5c61b --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override.vcxproj @@ -0,0 +1,259 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{ABB5EAE7-B3E6-432E-B636-333449892EA7}</ProjectGuid> + <RootNamespace>mimalloc-override</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-override</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <SupportJustMyCode>false</SupportJustMyCode> + <CompileAs>Default</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries> + </IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect32.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy mimalloc-redirect32.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_DEBUG=3;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <SupportJustMyCode>false</SupportJustMyCode> + <CompileAs>Default</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries> + </IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>copy mimalloc-redirect.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <CompileAs>Default</CompileAs> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect32.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy mimalloc-redirect32.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <CompileAs>Default</CompileAs> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>copy mimalloc-redirect.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" /> + <ClInclude Include="..\..\include\mimalloc-new-delete.h" /> + <ClInclude Include="..\..\include\mimalloc-override.h" /> + <ClInclude Include="..\..\include\mimalloc\atomic.h" /> + <ClInclude Include="..\..\include\mimalloc\internal.h" /> + <ClInclude Include="..\..\include\mimalloc\prim.h" /> + <ClInclude Include="..\..\include\mimalloc\track.h" /> + <ClInclude Include="..\..\include\mimalloc\types.h" /> + <ClInclude Include="..\..\src\bitmap.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\alloc-aligned.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-override.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-posix.c" /> + <ClCompile Include="..\..\src\alloc.c" /> + <ClCompile Include="..\..\src\arena.c" /> + <ClCompile Include="..\..\src\bitmap.c" /> + <ClCompile Include="..\..\src\heap.c" /> + <ClCompile Include="..\..\src\init.c" /> + <ClCompile Include="..\..\src\prim\prim.c" /> + <ClCompile Include="..\..\src\options.c" /> + <ClCompile Include="..\..\src\os.c" /> + <ClCompile Include="..\..\src\page-queue.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\page.c" /> + <ClCompile Include="..\..\src\random.c" /> + <ClCompile Include="..\..\src\segment-map.c" /> + <ClCompile Include="..\..\src\segment.c" /> + <ClCompile Include="..\..\src\stats.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj new file mode 100644 index 0000000..812a9cb --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj @@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FFF7958F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloc-test-api</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-test-api</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\test-api.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj new file mode 100644 index 0000000..ef7ab35 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7958F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloc-test-stress</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-test-stress</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\test-stress.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test.vcxproj new file mode 100644 index 0000000..13af6ab --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7858F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloctest</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-test</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\test\main-override-static.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.sln b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.sln new file mode 100644 index 0000000..6ff01d3 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test", "mimalloc-test.vcxproj", "{FEF7858F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimalloc-override.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-api", "mimalloc-test-api.vcxproj", "{FFF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4297F93D-486A-4243-995F-7D32F59AE82A} + EndGlobalSection +EndGlobal diff --git a/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.vcxproj new file mode 100644 index 0000000..0e2eb31 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.vcxproj @@ -0,0 +1,257 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{ABB5EAE7-B3E6-432E-B636-333449892EA6}</ProjectGuid> + <RootNamespace>mimalloc</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <CompileAs>CompileAsCpp</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + <LanguageStandard>Default</LanguageStandard> + </ClCompile> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>Default</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <CompileAs>CompileAsCpp</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + <LanguageStandard>Default</LanguageStandard> + </ClCompile> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + <Link> + <EntryPointSymbol> + </EntryPointSymbol> + </Link> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <CompileAs>CompileAsCpp</CompileAs> + <IntrinsicFunctions>true</IntrinsicFunctions> + <LanguageStandard>Default</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <CompileAs>CompileAsCpp</CompileAs> + <IntrinsicFunctions>true</IntrinsicFunctions> + <LanguageStandard>Default</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <EntryPointSymbol> + </EntryPointSymbol> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\src\alloc-aligned.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-override.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-posix.c" /> + <ClCompile Include="..\..\src\alloc.c" /> + <ClCompile Include="..\..\src\arena.c" /> + <ClCompile Include="..\..\src\bitmap.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\heap.c" /> + <ClCompile Include="..\..\src\init.c" /> + <ClCompile Include="..\..\src\prim\prim.c" /> + <ClCompile Include="..\..\src\prim\windows\prim.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\options.c" /> + <ClCompile Include="..\..\src\page-queue.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\page.c" /> + <ClCompile Include="..\..\src\random.c" /> + <ClCompile Include="..\..\src\segment-map.c" /> + <ClCompile Include="..\..\src\segment.c" /> + <ClCompile Include="..\..\src\os.c" /> + <ClCompile Include="..\..\src\stats.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" /> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc-override.h" /> + <ClInclude Include="..\..\include\mimalloc-new-delete.h" /> + <ClInclude Include="..\..\include\mimalloc\atomic.h" /> + <ClInclude Include="..\..\include\mimalloc\internal.h" /> + <ClInclude Include="..\..\include\mimalloc\prim.h" /> + <ClInclude Include="..\..\include\mimalloc\track.h" /> + <ClInclude Include="..\..\include\mimalloc\types.h" /> + <ClInclude Include="..\..\src\bitmap.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj new file mode 100644 index 0000000..a3c56f7 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7868F-750E-4C21-A04D-22707CC66879}</ProjectGuid> + <RootNamespace>mimalloc-override-test</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-override-test</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <ExceptionHandling>Sync</ExceptionHandling> + <CompileAs>Default</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent /> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <ExceptionHandling>Sync</ExceptionHandling> + <CompileAs>Default</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent /> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\main-override.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc-override.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea7}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override.vcxproj new file mode 100644 index 0000000..e2c7f71 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override.vcxproj @@ -0,0 +1,270 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{ABB5EAE7-B3E6-432E-B636-333449892EA7}</ProjectGuid> + <RootNamespace>mimalloc-override</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-override</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.dll</TargetExt> + <TargetName>mimalloc-override</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <SupportJustMyCode>false</SupportJustMyCode> + <CompileAs>Default</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries> + </IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect32.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy mimalloc-redirect32.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_DEBUG=4;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <SupportJustMyCode>false</SupportJustMyCode> + <CompileAs>Default</CompileAs> + </ClCompile> + <Link> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries> + </IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>copy mimalloc-redirect.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <CompileAs>Default</CompileAs> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect32.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>Copy mimalloc-redirect32.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <CompileAs>Default</CompileAs> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies)</AdditionalDependencies> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + </Link> + <PostBuildEvent> + <Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect.dll" "$(OutputPath)"</Command> + </PostBuildEvent> + <PostBuildEvent> + <Message>copy mimalloc-redirect.dll to the output directory</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" /> + <ClInclude Include="..\..\include\mimalloc-etw-gen.h" /> + <ClInclude Include="..\..\include\mimalloc-etw.h" /> + <ClInclude Include="..\..\include\mimalloc-new-delete.h" /> + <ClInclude Include="..\..\include\mimalloc-override.h" /> + <ClInclude Include="..\..\include\mimalloc\atomic.h" /> + <ClInclude Include="..\..\include\mimalloc\internal.h" /> + <ClInclude Include="..\..\include\mimalloc\prim.h" /> + <ClInclude Include="..\..\include\mimalloc\track.h" /> + <ClInclude Include="..\..\include\mimalloc\types.h" /> + <ClInclude Include="..\..\src\bitmap.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\alloc-aligned.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-override.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-posix.c" /> + <ClCompile Include="..\..\src\alloc.c" /> + <ClCompile Include="..\..\src\arena.c" /> + <ClCompile Include="..\..\src\bitmap.c" /> + <ClCompile Include="..\..\src\heap.c" /> + <ClCompile Include="..\..\src\init.c" /> + <ClCompile Include="..\..\src\prim\prim.c" /> + <ClCompile Include="..\..\src\prim\windows\prim.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\options.c" /> + <ClCompile Include="..\..\src\os.c" /> + <ClCompile Include="..\..\src\page-queue.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\page.c" /> + <ClCompile Include="..\..\src\random.c" /> + <ClCompile Include="..\..\src\segment-map.c" /> + <ClCompile Include="..\..\src\segment.c" /> + <ClCompile Include="..\..\src\stats.c" /> + </ItemGroup> + <ItemGroup> + <None Include="..\..\include\mimalloc-etw-gen.man" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj new file mode 100644 index 0000000..d9b9cae --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FFF7958F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloc-test-api</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-test-api</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\test-api-fill.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\test\test-api.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj new file mode 100644 index 0000000..14bd3e6 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7958F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloc-test-stress</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-test-stress</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\test-stress.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="mimalloc-override.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea7}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test.vcxproj new file mode 100644 index 0000000..506dd7d --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{FEF7858F-750E-4C21-A04D-22707CC66878}</ProjectGuid> + <RootNamespace>mimalloctest</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc-test</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <ConformanceMode>true</ConformanceMode> + <AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <LanguageStandard>stdcpp17</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="mimalloc.vcxproj"> + <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\test\main-override-static.c" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.sln b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.sln new file mode 100644 index 0000000..6ff01d3 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test", "mimalloc-test.vcxproj", "{FEF7858F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimalloc-override.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-api", "mimalloc-test-api.vcxproj", "{FFF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4297F93D-486A-4243-995F-7D32F59AE82A} + EndGlobalSection +EndGlobal diff --git a/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.vcxproj b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.vcxproj new file mode 100644 index 0000000..c298550 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.vcxproj @@ -0,0 +1,257 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{ABB5EAE7-B3E6-432E-B636-333449892EA6}</ProjectGuid> + <RootNamespace>mimalloc</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + <ProjectName>mimalloc</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> + <TargetExt>.lib</TargetExt> + <TargetName>mimalloc-static</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>Default</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <CompileAs>CompileAsCpp</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <ConformanceMode>Default</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>MI_DEBUG=4;MI_SECURE=0;%(PreprocessorDefinitions);</PreprocessorDefinitions> + <CompileAs>CompileAsCpp</CompileAs> + <SupportJustMyCode>false</SupportJustMyCode> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + <Link> + <EntryPointSymbol> + </EntryPointSymbol> + </Link> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <ConformanceMode>Default</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <CompileAs>CompileAsCpp</CompileAs> + <IntrinsicFunctions>true</IntrinsicFunctions> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <ConformanceMode>Default</ConformanceMode> + <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions> + <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <WholeProgramOptimization>false</WholeProgramOptimization> + <BufferSecurityCheck>false</BufferSecurityCheck> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <CompileAs>CompileAsCpp</CompileAs> + <IntrinsicFunctions>true</IntrinsicFunctions> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <EntryPointSymbol> + </EntryPointSymbol> + </Link> + <PostBuildEvent> + <Command> + </Command> + </PostBuildEvent> + <Lib> + <AdditionalLibraryDirectories> + </AdditionalLibraryDirectories> + <AdditionalDependencies> + </AdditionalDependencies> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\src\alloc-aligned.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-override.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\alloc-posix.c" /> + <ClCompile Include="..\..\src\alloc.c" /> + <ClCompile Include="..\..\src\arena.c" /> + <ClCompile Include="..\..\src\bitmap.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\heap.c" /> + <ClCompile Include="..\..\src\init.c" /> + <ClCompile Include="..\..\src\prim\prim.c" /> + <ClCompile Include="..\..\src\prim\windows\prim.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\options.c" /> + <ClCompile Include="..\..\src\page-queue.c"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\src\page.c" /> + <ClCompile Include="..\..\src\random.c" /> + <ClCompile Include="..\..\src\segment-map.c" /> + <ClCompile Include="..\..\src\segment.c" /> + <ClCompile Include="..\..\src\os.c" /> + <ClCompile Include="..\..\src\stats.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" /> + <ClInclude Include="$(ProjectDir)..\..\include\mimalloc-override.h" /> + <ClInclude Include="..\..\include\mimalloc-new-delete.h" /> + <ClInclude Include="..\..\include\mimalloc\atomic.h" /> + <ClInclude Include="..\..\include\mimalloc\internal.h" /> + <ClInclude Include="..\..\include\mimalloc\prim.h" /> + <ClInclude Include="..\..\include\mimalloc\track.h" /> + <ClInclude Include="..\..\include\mimalloc\types.h" /> + <ClInclude Include="..\..\src\bitmap.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc-new-delete.h b/lib/Utils.Memory/mimalloc/include/mimalloc-new-delete.h new file mode 100644 index 0000000..c16f4a6 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc-new-delete.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_NEW_DELETE_H +#define MIMALLOC_NEW_DELETE_H + +// ---------------------------------------------------------------------------- +// This header provides convenient overrides for the new and +// delete operations in C++. +// +// This header should be included in only one source file! +// +// On Windows, or when linking dynamically with mimalloc, these +// can be more performant than the standard new-delete operations. +// See <https://en.cppreference.com/w/cpp/memory/new/operator_new> +// --------------------------------------------------------------------------- +#if defined(__cplusplus) + #include <new> + #include <mimalloc.h> + + #if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_) + // stay consistent with VCRT definitions + #define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n) + #define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n) + #else + #define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict + #define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict + #endif + + void operator delete(void* p) noexcept { mi_free(p); }; + void operator delete[](void* p) noexcept { mi_free(p); }; + + void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); } + void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); } + + mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); } + mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); } + + mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); }; + void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); }; + #endif + + #if (__cplusplus > 201402L || defined(__cpp_aligned_new)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); }; + void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + + void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); } + void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); } + #endif +#endif + +#endif // MIMALLOC_NEW_DELETE_H diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc-override.h b/lib/Utils.Memory/mimalloc/include/mimalloc-override.h new file mode 100644 index 0000000..c63b0b9 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc-override.h @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_OVERRIDE_H +#define MIMALLOC_OVERRIDE_H + +/* ---------------------------------------------------------------------------- +This header can be used to statically redirect malloc/free and new/delete +to the mimalloc variants. This can be useful if one can include this file on +each source file in a project (but be careful when using external code to +not accidentally mix pointers from different allocators). +-----------------------------------------------------------------------------*/ + +#include <mimalloc.h> + +// Standard C allocation +#define malloc(n) mi_malloc(n) +#define calloc(n,c) mi_calloc(n,c) +#define realloc(p,n) mi_realloc(p,n) +#define free(p) mi_free(p) + +#define strdup(s) mi_strdup(s) +#define strndup(s,n) mi_strndup(s,n) +#define realpath(f,n) mi_realpath(f,n) + +// Microsoft extensions +#define _expand(p,n) mi_expand(p,n) +#define _msize(p) mi_usable_size(p) +#define _recalloc(p,n,c) mi_recalloc(p,n,c) + +#define _strdup(s) mi_strdup(s) +#define _strndup(s,n) mi_strndup(s,n) +#define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s)) +#define _mbsdup(s) mi_mbsdup(s) +#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v) +#define _wdupenv_s(b,n,v) mi_wdupenv_s((unsigned short*)(b),n,(const unsigned short*)(v)) + +// Various Posix and Unix variants +#define reallocf(p,n) mi_reallocf(p,n) +#define malloc_size(p) mi_usable_size(p) +#define malloc_usable_size(p) mi_usable_size(p) +#define cfree(p) mi_free(p) + +#define valloc(n) mi_valloc(n) +#define pvalloc(n) mi_pvalloc(n) +#define reallocarray(p,s,n) mi_reallocarray(p,s,n) +#define reallocarr(p,s,n) mi_reallocarr(p,s,n) +#define memalign(a,n) mi_memalign(a,n) +#define aligned_alloc(a,n) mi_aligned_alloc(a,n) +#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n) +#define _posix_memalign(p,a,n) mi_posix_memalign(p,a,n) + +// Microsoft aligned variants +#define _aligned_malloc(n,a) mi_malloc_aligned(n,a) +#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a) +#define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a) +#define _aligned_msize(p,a,o) mi_usable_size(p) +#define _aligned_free(p) mi_free(p) +#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o) +#define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o) +#define _aligned_offset_recalloc(p,s,n,a,o) mi_recalloc_aligned_at(p,s,n,a,o) + +#endif // MIMALLOC_OVERRIDE_H diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc.h b/lib/Utils.Memory/mimalloc/include/mimalloc.h new file mode 100644 index 0000000..f77c2ea --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc.h @@ -0,0 +1,565 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_H +#define MIMALLOC_H + +#define MI_MALLOC_VERSION 212 // major + 2 digits minor + +// ------------------------------------------------------ +// Compiler specific attributes +// ------------------------------------------------------ + +#ifdef __cplusplus + #if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 + #define mi_attr_noexcept noexcept + #else + #define mi_attr_noexcept throw() + #endif +#else + #define mi_attr_noexcept +#endif + +#if defined(__cplusplus) && (__cplusplus >= 201703) + #define mi_decl_nodiscard [[nodiscard]] +#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // includes clang, icc, and clang-cl + #define mi_decl_nodiscard __attribute__((warn_unused_result)) +#elif defined(_HAS_NODISCARD) + #define mi_decl_nodiscard _NODISCARD +#elif (_MSC_VER >= 1700) + #define mi_decl_nodiscard _Check_return_ +#else + #define mi_decl_nodiscard +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) + #if !defined(MI_SHARED_LIB) + #define mi_decl_export + #elif defined(MI_SHARED_LIB_EXPORT) + #define mi_decl_export __declspec(dllexport) + #else + #define mi_decl_export __declspec(dllimport) + #endif + #if defined(__MINGW32__) + #define mi_decl_restrict + #define mi_attr_malloc __attribute__((malloc)) + #else + #if (_MSC_VER >= 1900) && !defined(__EDG__) + #define mi_decl_restrict __declspec(allocator) __declspec(restrict) + #else + #define mi_decl_restrict __declspec(restrict) + #endif + #define mi_attr_malloc + #endif + #define mi_cdecl __cdecl + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) +#elif defined(__GNUC__) // includes clang and icc + #if defined(MI_SHARED_LIB) && defined(MI_SHARED_LIB_EXPORT) + #define mi_decl_export __attribute__((visibility("default"))) + #else + #define mi_decl_export + #endif + #define mi_cdecl // leads to warnings... __attribute__((cdecl)) + #define mi_decl_restrict + #define mi_attr_malloc __attribute__((malloc)) + #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5) + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) + #elif defined(__INTEL_COMPILER) + #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) + #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) + #define mi_attr_alloc_align(p) + #else + #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) + #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) + #define mi_attr_alloc_align(p) __attribute__((alloc_align(p))) + #endif +#else + #define mi_cdecl + #define mi_decl_export + #define mi_decl_restrict + #define mi_attr_malloc + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) +#endif + +// ------------------------------------------------------ +// Includes +// ------------------------------------------------------ + +#include <stddef.h> // size_t +#include <stdbool.h> // bool +#include <stdint.h> // INTPTR_MAX + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------------------------------------------ +// Standard malloc interface +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_export void* mi_expand(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); + +mi_decl_export void mi_free(void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; + +// ------------------------------------------------------ +// Extended functionality +// ------------------------------------------------------ +#define MI_SMALL_WSIZE_MAX (128) +#define MI_SMALL_SIZE_MAX (MI_SMALL_WSIZE_MAX*sizeof(void*)) + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); + +mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept; + + +// ------------------------------------------------------ +// Internals +// ------------------------------------------------------ + +typedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg); +mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept; + +typedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg); +mi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept; + +typedef void (mi_cdecl mi_error_fun)(int err, void* arg); +mi_decl_export void mi_register_error(mi_error_fun* fun, void* arg); + +mi_decl_export void mi_collect(bool force) mi_attr_noexcept; +mi_decl_export int mi_version(void) mi_attr_noexcept; +mi_decl_export void mi_stats_reset(void) mi_attr_noexcept; +mi_decl_export void mi_stats_merge(void) mi_attr_noexcept; +mi_decl_export void mi_stats_print(void* out) mi_attr_noexcept; // backward compatibility: `out` is ignored and should be NULL +mi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; + +mi_decl_export void mi_process_init(void) mi_attr_noexcept; +mi_decl_export void mi_thread_init(void) mi_attr_noexcept; +mi_decl_export void mi_thread_done(void) mi_attr_noexcept; +mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; + +mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, + size_t* current_rss, size_t* peak_rss, + size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept; + +// ------------------------------------------------------------------------------------- +// Aligned allocation +// Note that `alignment` always follows `size` for consistency with unaligned +// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`. +// ------------------------------------------------------------------------------------- + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); + + +// ------------------------------------------------------------------------------------- +// Heaps: first-class, but can only allocate from the same thread that created it. +// ------------------------------------------------------------------------------------- + +struct mi_heap_s; +typedef struct mi_heap_s mi_heap_t; + +mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void); +mi_decl_export void mi_heap_delete(mi_heap_t* heap); +mi_decl_export void mi_heap_destroy(mi_heap_t* heap); +mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap); +mi_decl_export mi_heap_t* mi_heap_get_default(void); +mi_decl_export mi_heap_t* mi_heap_get_backing(void); +mi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); + +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); +mi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); + + +// -------------------------------------------------------------------------------- +// Zero initialized re-allocation. +// Only valid on memory that was originally allocated with zero initialization too. +// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. +// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992> +// -------------------------------------------------------------------------------- + +mi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); + +mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3); + +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); + +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3,4) mi_attr_alloc_align(5); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3,4); + + +// ------------------------------------------------------ +// Analysis +// ------------------------------------------------------ + +mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p); +mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p); +mi_decl_export bool mi_check_owned(const void* p); + +// An area of heap space contains blocks of a single size. +typedef struct mi_heap_area_s { + void* blocks; // start of the area containing heap blocks + size_t reserved; // bytes reserved for this area (virtual) + size_t committed; // current available bytes for this area + size_t used; // number of allocated blocks + size_t block_size; // size in bytes of each block + size_t full_block_size; // size in bytes of a full block including padding and metadata. +} mi_heap_area_t; + +typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); + +mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); + +// Experimental +mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept; + +mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept; +mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept; + +mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept; +mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept; + +mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept; + +// Experimental: heaps associated with specific memory arena's +typedef int mi_arena_id_t; +mi_decl_export void* mi_arena_area(mi_arena_id_t arena_id, size_t* size); +mi_decl_export int mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept; +mi_decl_export int mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept; +mi_decl_export bool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept; + +#if MI_MALLOC_VERSION >= 182 +// Create a heap that only allocates in the specified arena +mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id); +#endif + +// deprecated +mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept; + + +// ------------------------------------------------------ +// Convenience +// ------------------------------------------------------ + +#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) +#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) +#define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp))) +#define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp))) +#define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp))) +#define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp))) + +#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) +#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) +#define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp))) +#define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp))) +#define mi_heap_reallocn_tp(hp,p,tp,n) ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp))) +#define mi_heap_recalloc_tp(hp,p,tp,n) ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp))) + + +// ------------------------------------------------------ +// Options +// ------------------------------------------------------ + +typedef enum mi_option_e { + // stable options + mi_option_show_errors, // print error messages + mi_option_show_stats, // print statistics on termination + mi_option_verbose, // print verbose messages + // the following options are experimental (see src/options.h) + mi_option_eager_commit, // eager commit segments? (after `eager_commit_delay` segments) (=1) + mi_option_arena_eager_commit, // eager commit arenas? Use 2 to enable just on overcommit systems (=2) + mi_option_purge_decommits, // should a memory purge decommit (or only reset) (=1) + mi_option_allow_large_os_pages, // allow large (2MiB) OS pages, implies eager commit + mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB/page) at startup + mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node + mi_option_reserve_os_memory, // reserve specified amount of OS memory in an arena at startup + mi_option_deprecated_segment_cache, + mi_option_deprecated_page_reset, + mi_option_abandoned_page_purge, // immediately purge delayed purges on thread termination + mi_option_deprecated_segment_reset, + mi_option_eager_commit_delay, + mi_option_purge_delay, // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all. + mi_option_use_numa_nodes, // 0 = use all available numa nodes, otherwise use at most N nodes. + mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only programmatically reserved arenas) + mi_option_os_tag, // tag used for OS logging (macOS only for now) + mi_option_max_errors, // issue at most N error messages + mi_option_max_warnings, // issue at most N warning messages + mi_option_max_segment_reclaim, + mi_option_destroy_on_exit, // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe. + mi_option_arena_reserve, // initial memory size in KiB for arena reservation (1GiB on 64-bit) + mi_option_arena_purge_mult, + mi_option_purge_extend_delay, + _mi_option_last, + // legacy option names + mi_option_large_os_pages = mi_option_allow_large_os_pages, + mi_option_eager_region_commit = mi_option_arena_eager_commit, + mi_option_reset_decommits = mi_option_purge_decommits, + mi_option_reset_delay = mi_option_purge_delay, + mi_option_abandoned_page_reset = mi_option_abandoned_page_purge +} mi_option_t; + + +mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option); +mi_decl_export void mi_option_enable(mi_option_t option); +mi_decl_export void mi_option_disable(mi_option_t option); +mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable); +mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable); + +mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option); +mi_decl_nodiscard mi_decl_export long mi_option_get_clamp(mi_option_t option, long min, long max); +mi_decl_nodiscard mi_decl_export size_t mi_option_get_size(mi_option_t option); +mi_decl_export void mi_option_set(mi_option_t option, long value); +mi_decl_export void mi_option_set_default(mi_option_t option, long value); + + +// ------------------------------------------------------------------------------------------------------- +// "mi" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions. +// (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.) +// note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing. +// ------------------------------------------------------------------------------------------------------- + +mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; +mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_good_size(size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; + +mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); + +mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export int mi_reallocarr(void* p, size_t count, size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_export int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept; +mi_decl_export int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept; + +mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; +mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept; +mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept; + +// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`. +// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception). +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size) mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(1, 2); +mi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize) mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(2, 3); + +#ifdef __cplusplus +} +#endif + +// --------------------------------------------------------------------------------------------- +// Implement the C++ std::allocator interface for use in STL containers. +// (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally) +// --------------------------------------------------------------------------------------------- +#ifdef __cplusplus + +#include <cstddef> // std::size_t +#include <cstdint> // PTRDIFF_MAX +#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 +#include <type_traits> // std::true_type +#include <utility> // std::forward +#endif + +template<class T> struct _mi_stl_allocator_common { + typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef value_type& reference; + typedef value_type const& const_reference; + typedef value_type* pointer; + typedef value_type const* const_pointer; + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using propagate_on_container_copy_assignment = std::true_type; + using propagate_on_container_move_assignment = std::true_type; + using propagate_on_container_swap = std::true_type; + template <class U, class ...Args> void construct(U* p, Args&& ...args) { ::new(p) U(std::forward<Args>(args)...); } + template <class U> void destroy(U* p) mi_attr_noexcept { p->~U(); } + #else + void construct(pointer p, value_type const& val) { ::new(p) value_type(val); } + void destroy(pointer p) { p->~value_type(); } + #endif + + size_type max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); } + pointer address(reference x) const { return &x; } + const_pointer address(const_reference x) const { return &x; } +}; + +template<class T> struct mi_stl_allocator : public _mi_stl_allocator_common<T> { + using typename _mi_stl_allocator_common<T>::size_type; + using typename _mi_stl_allocator_common<T>::value_type; + using typename _mi_stl_allocator_common<T>::pointer; + template <class U> struct rebind { typedef mi_stl_allocator<U> other; }; + + mi_stl_allocator() mi_attr_noexcept = default; + mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default; + template<class U> mi_stl_allocator(const mi_stl_allocator<U>&) mi_attr_noexcept { } + mi_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T* p, size_type) { mi_free(p); } + + #if (__cplusplus >= 201703L) // C++17 + mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_new_n(count, sizeof(T))); } + mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); } + #else + mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_new_n(count, sizeof(value_type))); } + #endif + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using is_always_equal = std::true_type; + #endif +}; + +template<class T1,class T2> bool operator==(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return true; } +template<class T1,class T2> bool operator!=(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return false; } + + +#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900) // C++11 +#define MI_HAS_HEAP_STL_ALLOCATOR 1 + +#include <memory> // std::shared_ptr + +// Common base class for STL allocators in a specific heap +template<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : public _mi_stl_allocator_common<T> { + using typename _mi_stl_allocator_common<T>::size_type; + using typename _mi_stl_allocator_common<T>::value_type; + using typename _mi_stl_allocator_common<T>::pointer; + + _mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp) { } /* will not delete nor destroy the passed in heap */ + + #if (__cplusplus >= 201703L) // C++17 + mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(T))); } + mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); } + #else + mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(value_type))); } + #endif + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using is_always_equal = std::false_type; + #endif + + void collect(bool force) { mi_heap_collect(this->heap.get(), force); } + template<class U> bool is_equal(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) const { return (this->heap == x.heap); } + +protected: + std::shared_ptr<mi_heap_t> heap; + template<class U, bool D> friend struct _mi_heap_stl_allocator_common; + + _mi_heap_stl_allocator_common() { + mi_heap_t* hp = mi_heap_new(); + this->heap.reset(hp, (_mi_destroy ? &heap_destroy : &heap_delete)); /* calls heap_delete/destroy when the refcount drops to zero */ + } + _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common& x) mi_attr_noexcept : heap(x.heap) { } + template<class U> _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) mi_attr_noexcept : heap(x.heap) { } + +private: + static void heap_delete(mi_heap_t* hp) { if (hp != NULL) { mi_heap_delete(hp); } } + static void heap_destroy(mi_heap_t* hp) { if (hp != NULL) { mi_heap_destroy(hp); } } +}; + +// STL allocator allocation in a specific heap +template<class T> struct mi_heap_stl_allocator : public _mi_heap_stl_allocator_common<T, false> { + using typename _mi_heap_stl_allocator_common<T, false>::size_type; + mi_heap_stl_allocator() : _mi_heap_stl_allocator_common<T, false>() { } // creates fresh heap that is deleted when the destructor is called + mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, false>(hp) { } // no delete nor destroy on the passed in heap + template<class U> mi_heap_stl_allocator(const mi_heap_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, false>(x) { } + + mi_heap_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T* p, size_type) { mi_free(p); } + template<class U> struct rebind { typedef mi_heap_stl_allocator<U> other; }; +}; + +template<class T1, class T2> bool operator==(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); } +template<class T1, class T2> bool operator!=(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); } + + +// STL allocator allocation in a specific heap, where `free` does nothing and +// the heap is destroyed in one go on destruction -- use with care! +template<class T> struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_allocator_common<T, true> { + using typename _mi_heap_stl_allocator_common<T, true>::size_type; + mi_heap_destroy_stl_allocator() : _mi_heap_stl_allocator_common<T, true>() { } // creates fresh heap that is destroyed when the destructor is called + mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, true>(hp) { } // no delete nor destroy on the passed in heap + template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { } + + mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T*, size_type) { /* do nothing as we destroy the heap on destruct. */ } + template<class U> struct rebind { typedef mi_heap_destroy_stl_allocator<U> other; }; +}; + +template<class T1, class T2> bool operator==(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); } +template<class T1, class T2> bool operator!=(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); } + +#endif // C++11 + +#endif // __cplusplus + +#endif diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc/atomic.h b/lib/Utils.Memory/mimalloc/include/mimalloc/atomic.h new file mode 100644 index 0000000..fe418fa --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc/atomic.h @@ -0,0 +1,385 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_ATOMIC_H +#define MIMALLOC_ATOMIC_H + +// -------------------------------------------------------------------------------------------- +// Atomics +// We need to be portable between C, C++, and MSVC. +// We base the primitives on the C/C++ atomics and create a mimimal wrapper for MSVC in C compilation mode. +// This is why we try to use only `uintptr_t` and `<type>*` as atomic types. +// To gain better insight in the range of used atomics, we use explicitly named memory order operations +// instead of passing the memory order as a parameter. +// ----------------------------------------------------------------------------------------------- + +#if defined(__cplusplus) +// Use C++ atomics +#include <atomic> +#define _Atomic(tp) std::atomic<tp> +#define mi_atomic(name) std::atomic_##name +#define mi_memory_order(name) std::memory_order_##name +#if !defined(ATOMIC_VAR_INIT) || (__cplusplus >= 202002L) // c++20, see issue #571 + #define MI_ATOMIC_VAR_INIT(x) x +#else + #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) +#endif +#elif defined(_MSC_VER) +// Use MSVC C wrapper for C11 atomics +#define _Atomic(tp) tp +#define MI_ATOMIC_VAR_INIT(x) x +#define mi_atomic(name) mi_atomic_##name +#define mi_memory_order(name) mi_memory_order_##name +#else +// Use C11 atomics +#include <stdatomic.h> +#define mi_atomic(name) atomic_##name +#define mi_memory_order(name) memory_order_##name +#if !defined(ATOMIC_VAR_INIT) || (__STDC_VERSION__ >= 201710L) // c17, see issue #735 + #define MI_ATOMIC_VAR_INIT(x) x +#else + #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) +#endif +#endif + +// Various defines for all used memory orders in mimalloc +#define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail) \ + mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail) + +#define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail) \ + mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail) + +#define mi_atomic_load_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_load_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_store_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_store_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) +#define mi_atomic_exchange_release(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_exchange_acq_rel(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_cas_weak_release(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed)) +#define mi_atomic_cas_weak_acq_rel(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire)) +#define mi_atomic_cas_strong_release(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed)) +#define mi_atomic_cas_strong_acq_rel(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire)) + +#define mi_atomic_add_relaxed(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed)) +#define mi_atomic_sub_relaxed(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed)) +#define mi_atomic_add_acq_rel(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_sub_acq_rel(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_and_acq_rel(p,x) mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_or_acq_rel(p,x) mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel)) + +#define mi_atomic_increment_relaxed(p) mi_atomic_add_relaxed(p,(uintptr_t)1) +#define mi_atomic_decrement_relaxed(p) mi_atomic_sub_relaxed(p,(uintptr_t)1) +#define mi_atomic_increment_acq_rel(p) mi_atomic_add_acq_rel(p,(uintptr_t)1) +#define mi_atomic_decrement_acq_rel(p) mi_atomic_sub_acq_rel(p,(uintptr_t)1) + +static inline void mi_atomic_yield(void); +static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add); +static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub); + + +#if defined(__cplusplus) || !defined(_MSC_VER) + +// In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value) +// We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well +#define mi_atomic_load_ptr_acquire(tp,p) mi_atomic_load_acquire(p) +#define mi_atomic_load_ptr_relaxed(tp,p) mi_atomic_load_relaxed(p) + +// In C++ we need to add casts to help resolve templates if NULL is passed +#if defined(__cplusplus) +#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,(tp*)x) +#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,(tp*)x) +#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,(tp*)des) +#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des) +#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,(tp*)des) +#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,(tp*)x) +#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,(tp*)x) +#else +#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,x) +#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,x) +#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,des) +#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,des) +#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,des) +#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,x) +#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,x) +#endif + +// These are used by the statistics +static inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) { + return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed)); +} +static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) { + int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p); + while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, ¤t, x)) { /* nothing */ }; +} + +// Used by timers +#define mi_atomic_loadi64_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_loadi64_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_storei64_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_storei64_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) + +#define mi_atomic_casi64_strong_acq_rel(p,e,d) mi_atomic_cas_strong_acq_rel(p,e,d) +#define mi_atomic_addi64_acq_rel(p,i) mi_atomic_add_acq_rel(p,i) + + +#elif defined(_MSC_VER) + +// MSVC C compilation wrapper that uses Interlocked operations to model C11 atomics. +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <intrin.h> +#ifdef _WIN64 +typedef LONG64 msc_intptr_t; +#define MI_64(f) f##64 +#else +typedef LONG msc_intptr_t; +#define MI_64(f) f +#endif + +typedef enum mi_memory_order_e { + mi_memory_order_relaxed, + mi_memory_order_consume, + mi_memory_order_acquire, + mi_memory_order_release, + mi_memory_order_acq_rel, + mi_memory_order_seq_cst +} mi_memory_order; + +static inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add); +} +static inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub)); +} +static inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x); +} +static inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x); +} +static inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) { + (void)(mo1); (void)(mo2); + uintptr_t read = (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected)); + if (read == *expected) { + return true; + } + else { + *expected = read; + return false; + } +} +static inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) { + return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2); +} +static inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange); +} +static inline void mi_atomic_thread_fence(mi_memory_order mo) { + (void)(mo); + _Atomic(uintptr_t) x = 0; + mi_atomic_exchange_explicit(&x, 1, mo); +} +static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) { + (void)(mo); +#if defined(_M_IX86) || defined(_M_X64) + return *p; +#else + uintptr_t x = *p; + if (mo > mi_memory_order_relaxed) { + while (!mi_atomic_compare_exchange_weak_explicit(p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ }; + } + return x; +#endif +} +static inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { + (void)(mo); +#if defined(_M_IX86) || defined(_M_X64) + *p = x; +#else + mi_atomic_exchange_explicit(p, x, mo); +#endif +} +static inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) { + (void)(mo); +#if defined(_M_X64) + return *p; +#else + int64_t old = *p; + int64_t x = old; + while ((old = InterlockedCompareExchange64(p, x, old)) != x) { + x = old; + } + return x; +#endif +} +static inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) { + (void)(mo); +#if defined(x_M_IX86) || defined(_M_X64) + *p = x; +#else + InterlockedExchange64(p, x); +#endif +} + +// These are used by the statistics +static inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) { +#ifdef _WIN64 + return (int64_t)mi_atomic_addi((int64_t*)p, add); +#else + int64_t current; + int64_t sum; + do { + current = *p; + sum = current + add; + } while (_InterlockedCompareExchange64(p, sum, current) != current); + return current; +#endif +} +static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) { + int64_t current; + do { + current = *p; + } while (current < x && _InterlockedCompareExchange64(p, x, current) != current); +} + +static inline void mi_atomic_addi64_acq_rel(volatile _Atomic(int64_t*)p, int64_t i) { + mi_atomic_addi64_relaxed(p, i); +} + +static inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p, int64_t* exp, int64_t des) { + int64_t read = _InterlockedCompareExchange64(p, des, *exp); + if (read == *exp) { + return true; + } + else { + *exp = read; + return false; + } +} + +// The pointer macros cast to `uintptr_t`. +#define mi_atomic_load_ptr_acquire(tp,p) (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p)) +#define mi_atomic_load_ptr_relaxed(tp,p) (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p)) +#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x)) +#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x)) +#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) +#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) +#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) +#define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x) +#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x) + +#define mi_atomic_loadi64_acquire(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_loadi64_relaxed(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed)) + + +#endif + + +// Atomically add a signed value; returns the previous value. +static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) { + return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add); +} + +// Atomically subtract a signed value; returns the previous value. +static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) { + return (intptr_t)mi_atomic_addi(p, -sub); +} + +typedef _Atomic(uintptr_t) mi_atomic_once_t; + +// Returns true only on the first invocation +static inline bool mi_atomic_once( mi_atomic_once_t* once ) { + if (mi_atomic_load_relaxed(once) != 0) return false; // quick test + uintptr_t expected = 0; + return mi_atomic_cas_strong_acq_rel(once, &expected, (uintptr_t)1); // try to set to 1 +} + +typedef _Atomic(uintptr_t) mi_atomic_guard_t; + +// Allows only one thread to execute at a time +#define mi_atomic_guard(guard) \ + uintptr_t _mi_guard_expected = 0; \ + for(bool _mi_guard_once = true; \ + _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,(uintptr_t)1); \ + (mi_atomic_store_release(guard,(uintptr_t)0), _mi_guard_once = false) ) + + + +// Yield +#if defined(__cplusplus) +#include <thread> +static inline void mi_atomic_yield(void) { + std::this_thread::yield(); +} +#elif defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +static inline void mi_atomic_yield(void) { + YieldProcessor(); +} +#elif defined(__SSE2__) +#include <emmintrin.h> +static inline void mi_atomic_yield(void) { + _mm_pause(); +} +#elif (defined(__GNUC__) || defined(__clang__)) && \ + (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__armel__) || defined(__ARMEL__) || \ + defined(__aarch64__) || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)) || defined(__POWERPC__) +#if defined(__x86_64__) || defined(__i386__) +static inline void mi_atomic_yield(void) { + __asm__ volatile ("pause" ::: "memory"); +} +#elif defined(__aarch64__) +static inline void mi_atomic_yield(void) { + __asm__ volatile("wfe"); +} +#elif (defined(__arm__) && __ARM_ARCH__ >= 7) +static inline void mi_atomic_yield(void) { + __asm__ volatile("yield" ::: "memory"); +} +#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__) +#ifdef __APPLE__ +static inline void mi_atomic_yield(void) { + __asm__ volatile ("or r27,r27,r27" ::: "memory"); +} +#else +static inline void mi_atomic_yield(void) { + __asm__ __volatile__ ("or 27,27,27" ::: "memory"); +} +#endif +#elif defined(__armel__) || defined(__ARMEL__) +static inline void mi_atomic_yield(void) { + __asm__ volatile ("nop" ::: "memory"); +} +#endif +#elif defined(__sun) +// Fallback for other archs +#include <synch.h> +static inline void mi_atomic_yield(void) { + smt_pause(); +} +#elif defined(__wasi__) +#include <sched.h> +static inline void mi_atomic_yield(void) { + sched_yield(); +} +#else +#include <unistd.h> +static inline void mi_atomic_yield(void) { + sleep(0); +} +#endif + + +#endif // __MIMALLOC_ATOMIC_H diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc/internal.h b/lib/Utils.Memory/mimalloc/include/mimalloc/internal.h new file mode 100644 index 0000000..00d2626 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc/internal.h @@ -0,0 +1,979 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_INTERNAL_H +#define MIMALLOC_INTERNAL_H + + +// -------------------------------------------------------------------------- +// This file contains the interal API's of mimalloc and various utility +// functions and macros. +// -------------------------------------------------------------------------- + +#include "mimalloc/types.h" +#include "mimalloc/track.h" + +#if (MI_DEBUG>0) +#define mi_trace_message(...) _mi_trace_message(__VA_ARGS__) +#else +#define mi_trace_message(...) +#endif + +#define MI_CACHE_LINE 64 +#if defined(_MSC_VER) +#pragma warning(disable:4127) // suppress constant conditional warning (due to MI_SECURE paths) +#pragma warning(disable:26812) // unscoped enum warning +#define mi_decl_noinline __declspec(noinline) +#define mi_decl_thread __declspec(thread) +#define mi_decl_cache_align __declspec(align(MI_CACHE_LINE)) +#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc +#define mi_decl_noinline __attribute__((noinline)) +#define mi_decl_thread __thread +#define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE))) +#else +#define mi_decl_noinline +#define mi_decl_thread __thread // hope for the best :-) +#define mi_decl_cache_align +#endif + +#if defined(__EMSCRIPTEN__) && !defined(__wasi__) +#define __wasi__ +#endif + +#if defined(__cplusplus) +#define mi_decl_externc extern "C" +#else +#define mi_decl_externc +#endif + +// pthreads +#if !defined(_WIN32) && !defined(__wasi__) +#define MI_USE_PTHREADS +#include <pthread.h> +#endif + +// "options.c" +void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message); +void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...); +void _mi_warning_message(const char* fmt, ...); +void _mi_verbose_message(const char* fmt, ...); +void _mi_trace_message(const char* fmt, ...); +void _mi_options_init(void); +void _mi_error_message(int err, const char* fmt, ...); + +// random.c +void _mi_random_init(mi_random_ctx_t* ctx); +void _mi_random_init_weak(mi_random_ctx_t* ctx); +void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx); +void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx); +uintptr_t _mi_random_next(mi_random_ctx_t* ctx); +uintptr_t _mi_heap_random_next(mi_heap_t* heap); +uintptr_t _mi_os_random_weak(uintptr_t extra_seed); +static inline uintptr_t _mi_random_shuffle(uintptr_t x); + +// init.c +extern mi_decl_cache_align mi_stats_t _mi_stats_main; +extern mi_decl_cache_align const mi_page_t _mi_page_empty; +bool _mi_is_main_thread(void); +size_t _mi_current_thread_count(void); +bool _mi_preloading(void); // true while the C runtime is not initialized yet +mi_threadid_t _mi_thread_id(void) mi_attr_noexcept; +mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap +void _mi_thread_done(mi_heap_t* heap); +void _mi_thread_data_collect(void); + +// os.c +void _mi_os_init(void); // called from process init +void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* stats); +void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* stats); +void _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* stats); + +size_t _mi_os_page_size(void); +size_t _mi_os_good_alloc_size(size_t size); +bool _mi_os_has_overcommit(void); +bool _mi_os_has_virtual_reserve(void); + +bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_reset(void* addr, size_t size, mi_stats_t* tld_stats); +bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); +bool _mi_os_protect(void* addr, size_t size); +bool _mi_os_unprotect(void* addr, size_t size); +bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats); + +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* stats); +void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats); + +void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size); +bool _mi_os_use_large_page(size_t size, size_t alignment); +size_t _mi_os_large_page_size(void); + +void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid); + +// arena.c +mi_arena_id_t _mi_arena_id_none(void); +void _mi_arena_free(void* p, size_t size, size_t still_committed_size, mi_memid_t memid, mi_stats_t* stats); +void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld); +void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld); +bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id); +bool _mi_arena_contains(const void* p); +void _mi_arena_collect(bool force_purge, mi_stats_t* stats); +void _mi_arena_unsafe_destroy_all(mi_stats_t* stats); + +// "segment-map.c" +void _mi_segment_map_allocated_at(const mi_segment_t* segment); +void _mi_segment_map_freed_at(const mi_segment_t* segment); + +// "segment.c" +mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld); +void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld); +void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld); +bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld); +void _mi_segment_thread_collect(mi_segments_tld_t* tld); + +#if MI_HUGE_PAGE_ABANDON +void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block); +#else +void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block); +#endif + +uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page +void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld); +void _mi_abandoned_await_readers(void); +void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld); + +// "page.c" +void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept mi_attr_malloc; + +void _mi_page_retire(mi_page_t* page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks +void _mi_page_unfull(mi_page_t* page); +void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page +void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread... +void _mi_heap_delayed_free_all(mi_heap_t* heap); +bool _mi_heap_delayed_free_partial(mi_heap_t* heap); +void _mi_heap_collect_retired(mi_heap_t* heap, bool force); + +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append); +void _mi_deferred_free(mi_heap_t* heap, bool force); + +void _mi_page_free_collect(mi_page_t* page,bool force); +void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments + +size_t _mi_bin_size(uint8_t bin); // for stats +uint8_t _mi_bin(size_t size); // for stats + +// "heap.c" +void _mi_heap_destroy_pages(mi_heap_t* heap); +void _mi_heap_collect_abandon(mi_heap_t* heap); +void _mi_heap_set_default_direct(mi_heap_t* heap); +bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid); +void _mi_heap_unsafe_destroy_all(void); + +// "stats.c" +void _mi_stats_done(mi_stats_t* stats); +mi_msecs_t _mi_clock_now(void); +mi_msecs_t _mi_clock_end(mi_msecs_t start); +mi_msecs_t _mi_clock_start(void); + +// "alloc.c" +void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept; // called from `_mi_malloc_generic` +void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept; +void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned` +void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept; +mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p); +bool _mi_free_delayed_block(mi_block_t* block); +void _mi_free_generic(const mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept; // for runtime integration +void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size); + +// option.c, c primitives +char _mi_toupper(char c); +int _mi_strnicmp(const char* s, const char* t, size_t n); +void _mi_strlcpy(char* dest, const char* src, size_t dest_size); +void _mi_strlcat(char* dest, const char* src, size_t dest_size); +size_t _mi_strlen(const char* s); +size_t _mi_strnlen(const char* s, size_t max_len); + + +#if MI_DEBUG>1 +bool _mi_page_is_valid(mi_page_t* page); +#endif + + +// ------------------------------------------------------ +// Branches +// ------------------------------------------------------ + +#if defined(__GNUC__) || defined(__clang__) +#define mi_unlikely(x) (__builtin_expect(!!(x),false)) +#define mi_likely(x) (__builtin_expect(!!(x),true)) +#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) +#define mi_unlikely(x) (x) [[unlikely]] +#define mi_likely(x) (x) [[likely]] +#else +#define mi_unlikely(x) (x) +#define mi_likely(x) (x) +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + + +/* ----------------------------------------------------------- + Error codes passed to `_mi_fatal_error` + All are recoverable but EFAULT is a serious error and aborts by default in secure mode. + For portability define undefined error codes using common Unix codes: + <https://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html> +----------------------------------------------------------- */ +#include <errno.h> +#ifndef EAGAIN // double free +#define EAGAIN (11) +#endif +#ifndef ENOMEM // out of memory +#define ENOMEM (12) +#endif +#ifndef EFAULT // corrupted free-list or meta-data +#define EFAULT (14) +#endif +#ifndef EINVAL // trying to free an invalid pointer +#define EINVAL (22) +#endif +#ifndef EOVERFLOW // count*size overflow +#define EOVERFLOW (75) +#endif + + +/* ----------------------------------------------------------- + Inlined definitions +----------------------------------------------------------- */ +#define MI_UNUSED(x) (void)(x) +#if (MI_DEBUG>0) +#define MI_UNUSED_RELEASE(x) +#else +#define MI_UNUSED_RELEASE(x) MI_UNUSED(x) +#endif + +#define MI_INIT4(x) x(),x(),x(),x() +#define MI_INIT8(x) MI_INIT4(x),MI_INIT4(x) +#define MI_INIT16(x) MI_INIT8(x),MI_INIT8(x) +#define MI_INIT32(x) MI_INIT16(x),MI_INIT16(x) +#define MI_INIT64(x) MI_INIT32(x),MI_INIT32(x) +#define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x) +#define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x) + + +#include <string.h> +// initialize a local variable to zero; use memset as compilers optimize constant sized memset's +#define _mi_memzero_var(x) memset(&x,0,sizeof(x)) + +// Is `x` a power of two? (0 is considered a power of two) +static inline bool _mi_is_power_of_two(uintptr_t x) { + return ((x & (x - 1)) == 0); +} + +// Is a pointer aligned? +static inline bool _mi_is_aligned(void* p, size_t alignment) { + mi_assert_internal(alignment != 0); + return (((uintptr_t)p % alignment) == 0); +} + +// Align upwards +static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) { + mi_assert_internal(alignment != 0); + uintptr_t mask = alignment - 1; + if ((alignment & mask) == 0) { // power of two? + return ((sz + mask) & ~mask); + } + else { + return (((sz + mask)/alignment)*alignment); + } +} + +// Align downwards +static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) { + mi_assert_internal(alignment != 0); + uintptr_t mask = alignment - 1; + if ((alignment & mask) == 0) { // power of two? + return (sz & ~mask); + } + else { + return ((sz / alignment) * alignment); + } +} + +// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`. +static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) { + mi_assert_internal(divider != 0); + return (divider == 0 ? size : ((size + divider - 1) / divider)); +} + +// Is memory zero initialized? +static inline bool mi_mem_is_zero(const void* p, size_t size) { + for (size_t i = 0; i < size; i++) { + if (((uint8_t*)p)[i] != 0) return false; + } + return true; +} + + +// Align a byte size to a size in _machine words_, +// i.e. byte size == `wsize*sizeof(void*)`. +static inline size_t _mi_wsize_from_size(size_t size) { + mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t)); + return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); +} + +// Overflow detecting multiply +#if __has_builtin(__builtin_umul_overflow) || (defined(__GNUC__) && (__GNUC__ >= 5)) +#include <limits.h> // UINT_MAX, ULONG_MAX +#if defined(_CLOCK_T) // for Illumos +#undef _CLOCK_T +#endif +static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { + #if (SIZE_MAX == ULONG_MAX) + return __builtin_umull_overflow(count, size, (unsigned long *)total); + #elif (SIZE_MAX == UINT_MAX) + return __builtin_umul_overflow(count, size, (unsigned int *)total); + #else + return __builtin_umulll_overflow(count, size, (unsigned long long *)total); + #endif +} +#else /* __builtin_umul_overflow is unavailable */ +static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { + #define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX) + *total = count * size; + // note: gcc/clang optimize this to directly check the overflow flag + return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW) && size > 0 && (SIZE_MAX / size) < count); +} +#endif + +// Safe multiply `count*size` into `total`; return `true` on overflow. +static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) { + if (count==1) { // quick check for the case where count is one (common for C++ allocators) + *total = size; + return false; + } + else if mi_unlikely(mi_mul_overflow(count, size, total)) { + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "allocation request is too large (%zu * %zu bytes)\n", count, size); + #endif + *total = SIZE_MAX; + return true; + } + else return false; +} + + +/*---------------------------------------------------------------------------------------- + Heap functions +------------------------------------------------------------------------------------------- */ + +extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap + +static inline bool mi_heap_is_backing(const mi_heap_t* heap) { + return (heap->tld->heap_backing == heap); +} + +static inline bool mi_heap_is_initialized(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + return (heap != &_mi_heap_empty); +} + +static inline uintptr_t _mi_ptr_cookie(const void* p) { + extern mi_heap_t _mi_heap_main; + mi_assert_internal(_mi_heap_main.cookie != 0); + return ((uintptr_t)p ^ _mi_heap_main.cookie); +} + +/* ----------------------------------------------------------- + Pages +----------------------------------------------------------- */ + +static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) { + mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE)); + const size_t idx = _mi_wsize_from_size(size); + mi_assert_internal(idx < MI_PAGES_DIRECT); + return heap->pages_free_direct[idx]; +} + +// Segment that contains the pointer +// Large aligned blocks may be aligned at N*MI_SEGMENT_SIZE (inside a huge segment > MI_SEGMENT_SIZE), +// and we need align "down" to the segment info which is `MI_SEGMENT_SIZE` bytes before it; +// therefore we align one byte before `p`. +static inline mi_segment_t* _mi_ptr_segment(const void* p) { + mi_assert_internal(p != NULL); + return (mi_segment_t*)(((uintptr_t)p - 1) & ~MI_SEGMENT_MASK); +} + +static inline mi_page_t* mi_slice_to_page(mi_slice_t* s) { + mi_assert_internal(s->slice_offset== 0 && s->slice_count > 0); + return (mi_page_t*)(s); +} + +static inline mi_slice_t* mi_page_to_slice(mi_page_t* p) { + mi_assert_internal(p->slice_offset== 0 && p->slice_count > 0); + return (mi_slice_t*)(p); +} + +// Segment belonging to a page +static inline mi_segment_t* _mi_page_segment(const mi_page_t* page) { + mi_segment_t* segment = _mi_ptr_segment(page); + mi_assert_internal(segment == NULL || ((mi_slice_t*)page >= segment->slices && (mi_slice_t*)page < segment->slices + segment->slice_entries)); + return segment; +} + +static inline mi_slice_t* mi_slice_first(const mi_slice_t* slice) { + mi_slice_t* start = (mi_slice_t*)((uint8_t*)slice - slice->slice_offset); + mi_assert_internal(start >= _mi_ptr_segment(slice)->slices); + mi_assert_internal(start->slice_offset == 0); + mi_assert_internal(start + start->slice_count > slice); + return start; +} + +// Get the page containing the pointer (performance critical as it is called in mi_free) +static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) { + mi_assert_internal(p > (void*)segment); + ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment; + mi_assert_internal(diff > 0 && diff <= (ptrdiff_t)MI_SEGMENT_SIZE); + size_t idx = (size_t)diff >> MI_SEGMENT_SLICE_SHIFT; + mi_assert_internal(idx <= segment->slice_entries); + mi_slice_t* slice0 = (mi_slice_t*)&segment->slices[idx]; + mi_slice_t* slice = mi_slice_first(slice0); // adjust to the block that holds the page data + mi_assert_internal(slice->slice_offset == 0); + mi_assert_internal(slice >= segment->slices && slice < segment->slices + segment->slice_entries); + return mi_slice_to_page(slice); +} + +// Quick page start for initialized pages +static inline uint8_t* _mi_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) { + return _mi_segment_page_start(segment, page, page_size); +} + +// Get the page containing the pointer +static inline mi_page_t* _mi_ptr_page(void* p) { + return _mi_segment_page_of(_mi_ptr_segment(p), p); +} + +// Get the block size of a page (special case for huge objects) +static inline size_t mi_page_block_size(const mi_page_t* page) { + const size_t bsize = page->xblock_size; + mi_assert_internal(bsize > 0); + if mi_likely(bsize < MI_HUGE_BLOCK_SIZE) { + return bsize; + } + else { + size_t psize; + _mi_segment_page_start(_mi_page_segment(page), page, &psize); + return psize; + } +} + +static inline bool mi_page_is_huge(const mi_page_t* page) { + return (_mi_page_segment(page)->kind == MI_SEGMENT_HUGE); +} + +// Get the usable block size of a page without fixed padding. +// This may still include internal padding due to alignment and rounding up size classes. +static inline size_t mi_page_usable_block_size(const mi_page_t* page) { + return mi_page_block_size(page) - MI_PADDING_SIZE; +} + +// size of a segment +static inline size_t mi_segment_size(mi_segment_t* segment) { + return segment->segment_slices * MI_SEGMENT_SLICE_SIZE; +} + +static inline uint8_t* mi_segment_end(mi_segment_t* segment) { + return (uint8_t*)segment + mi_segment_size(segment); +} + +// Thread free access +static inline mi_block_t* mi_page_thread_free(const mi_page_t* page) { + return (mi_block_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & ~3); +} + +static inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) { + return (mi_delayed_t)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & 3); +} + +// Heap access +static inline mi_heap_t* mi_page_heap(const mi_page_t* page) { + return (mi_heap_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xheap)); +} + +static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) { + mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING); + mi_atomic_store_release(&page->xheap,(uintptr_t)heap); +} + +// Thread free flag helpers +static inline mi_block_t* mi_tf_block(mi_thread_free_t tf) { + return (mi_block_t*)(tf & ~0x03); +} +static inline mi_delayed_t mi_tf_delayed(mi_thread_free_t tf) { + return (mi_delayed_t)(tf & 0x03); +} +static inline mi_thread_free_t mi_tf_make(mi_block_t* block, mi_delayed_t delayed) { + return (mi_thread_free_t)((uintptr_t)block | (uintptr_t)delayed); +} +static inline mi_thread_free_t mi_tf_set_delayed(mi_thread_free_t tf, mi_delayed_t delayed) { + return mi_tf_make(mi_tf_block(tf),delayed); +} +static inline mi_thread_free_t mi_tf_set_block(mi_thread_free_t tf, mi_block_t* block) { + return mi_tf_make(block, mi_tf_delayed(tf)); +} + +// are all blocks in a page freed? +// note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`. +static inline bool mi_page_all_free(const mi_page_t* page) { + mi_assert_internal(page != NULL); + return (page->used == 0); +} + +// are there any available blocks? +static inline bool mi_page_has_any_available(const mi_page_t* page) { + mi_assert_internal(page != NULL && page->reserved > 0); + return (page->used < page->reserved || (mi_page_thread_free(page) != NULL)); +} + +// are there immediately available blocks, i.e. blocks available on the free list. +static inline bool mi_page_immediate_available(const mi_page_t* page) { + mi_assert_internal(page != NULL); + return (page->free != NULL); +} + +// is more than 7/8th of a page in use? +static inline bool mi_page_mostly_used(const mi_page_t* page) { + if (page==NULL) return true; + uint16_t frac = page->reserved / 8U; + return (page->reserved - page->used <= frac); +} + +static inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) { + return &((mi_heap_t*)heap)->pages[_mi_bin(size)]; +} + + + +//----------------------------------------------------------- +// Page flags +//----------------------------------------------------------- +static inline bool mi_page_is_in_full(const mi_page_t* page) { + return page->flags.x.in_full; +} + +static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) { + page->flags.x.in_full = in_full; +} + +static inline bool mi_page_has_aligned(const mi_page_t* page) { + return page->flags.x.has_aligned; +} + +static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) { + page->flags.x.has_aligned = has_aligned; +} + + +/* ------------------------------------------------------------------- +Encoding/Decoding the free list next pointers + +This is to protect against buffer overflow exploits where the +free list is mutated. Many hardened allocators xor the next pointer `p` +with a secret key `k1`, as `p^k1`. This prevents overwriting with known +values but might be still too weak: if the attacker can guess +the pointer `p` this can reveal `k1` (since `p^k1^p == k1`). +Moreover, if multiple blocks can be read as well, the attacker can +xor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot +about the pointers (and subsequently `k1`). + +Instead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<<k1)+k1`. +Since these operations are not associative, the above approaches do not +work so well any more even if the `p` can be guesstimated. For example, +for the read case we can subtract two entries to discard the `+k1` term, +but that leads to `((p1^k2)<<<k1) - ((p2^k2)<<<k1)` at best. +We include the left-rotation since xor and addition are otherwise linear +in the lowest bit. Finally, both keys are unique per page which reduces +the re-use of keys by a large factor. + +We also pass a separate `null` value to be used as `NULL` or otherwise +`(k2<<<k1)+k1` would appear (too) often as a sentinel value. +------------------------------------------------------------------- */ + +static inline bool mi_is_in_same_segment(const void* p, const void* q) { + return (_mi_ptr_segment(p) == _mi_ptr_segment(q)); +} + +static inline bool mi_is_in_same_page(const void* p, const void* q) { + mi_segment_t* segment = _mi_ptr_segment(p); + if (_mi_ptr_segment(q) != segment) return false; + // assume q may be invalid // return (_mi_segment_page_of(segment, p) == _mi_segment_page_of(segment, q)); + mi_page_t* page = _mi_segment_page_of(segment, p); + size_t psize; + uint8_t* start = _mi_segment_page_start(segment, page, &psize); + return (start <= (uint8_t*)q && (uint8_t*)q < start + psize); +} + +static inline uintptr_t mi_rotl(uintptr_t x, uintptr_t shift) { + shift %= MI_INTPTR_BITS; + return (shift==0 ? x : ((x << shift) | (x >> (MI_INTPTR_BITS - shift)))); +} +static inline uintptr_t mi_rotr(uintptr_t x, uintptr_t shift) { + shift %= MI_INTPTR_BITS; + return (shift==0 ? x : ((x >> shift) | (x << (MI_INTPTR_BITS - shift)))); +} + +static inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) { + void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]); + return (p==null ? NULL : p); +} + +static inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) { + uintptr_t x = (uintptr_t)(p==NULL ? null : p); + return mi_rotl(x ^ keys[1], keys[0]) + keys[0]; +} + +static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) { + mi_track_mem_defined(block,sizeof(mi_block_t)); + mi_block_t* next; + #ifdef MI_ENCODE_FREELIST + next = (mi_block_t*)mi_ptr_decode(null, block->next, keys); + #else + MI_UNUSED(keys); MI_UNUSED(null); + next = (mi_block_t*)block->next; + #endif + mi_track_mem_noaccess(block,sizeof(mi_block_t)); + return next; +} + +static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) { + mi_track_mem_undefined(block,sizeof(mi_block_t)); + #ifdef MI_ENCODE_FREELIST + block->next = mi_ptr_encode(null, next, keys); + #else + MI_UNUSED(keys); MI_UNUSED(null); + block->next = (mi_encoded_t)next; + #endif + mi_track_mem_noaccess(block,sizeof(mi_block_t)); +} + +static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) { + #ifdef MI_ENCODE_FREELIST + mi_block_t* next = mi_block_nextx(page,block,page->keys); + // check for free list corruption: is `next` at least in the same page? + // TODO: check if `next` is `page->block_size` aligned? + if mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next)) { + _mi_error_message(EFAULT, "corrupted free list entry of size %zub at %p: value 0x%zx\n", mi_page_block_size(page), block, (uintptr_t)next); + next = NULL; + } + return next; + #else + MI_UNUSED(page); + return mi_block_nextx(page,block,NULL); + #endif +} + +static inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) { + #ifdef MI_ENCODE_FREELIST + mi_block_set_nextx(page,block,next, page->keys); + #else + MI_UNUSED(page); + mi_block_set_nextx(page,block,next,NULL); + #endif +} + + +// ------------------------------------------------------------------- +// commit mask +// ------------------------------------------------------------------- + +static inline void mi_commit_mask_create_empty(mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + cm->mask[i] = 0; + } +} + +static inline void mi_commit_mask_create_full(mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + cm->mask[i] = ~((size_t)0); + } +} + +static inline bool mi_commit_mask_is_empty(const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if (cm->mask[i] != 0) return false; + } + return true; +} + +static inline bool mi_commit_mask_is_full(const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if (cm->mask[i] != ~((size_t)0)) return false; + } + return true; +} + +// defined in `segment.c`: +size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total); +size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx); + +#define mi_commit_mask_foreach(cm,idx,count) \ + idx = 0; \ + while ((count = _mi_commit_mask_next_run(cm,&idx)) > 0) { + +#define mi_commit_mask_foreach_end() \ + idx += count; \ + } + + + +/* ----------------------------------------------------------- + memory id's +----------------------------------------------------------- */ + +static inline mi_memid_t _mi_memid_create(mi_memkind_t memkind) { + mi_memid_t memid; + _mi_memzero_var(memid); + memid.memkind = memkind; + return memid; +} + +static inline mi_memid_t _mi_memid_none(void) { + return _mi_memid_create(MI_MEM_NONE); +} + +static inline mi_memid_t _mi_memid_create_os(bool committed, bool is_zero, bool is_large) { + mi_memid_t memid = _mi_memid_create(MI_MEM_OS); + memid.initially_committed = committed; + memid.initially_zero = is_zero; + memid.is_pinned = is_large; + return memid; +} + + +// ------------------------------------------------------------------- +// Fast "random" shuffle +// ------------------------------------------------------------------- + +static inline uintptr_t _mi_random_shuffle(uintptr_t x) { + if (x==0) { x = 17; } // ensure we don't get stuck in generating zeros +#if (MI_INTPTR_SIZE==8) + // by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c> + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9UL; + x ^= x >> 27; + x *= 0x94d049bb133111ebUL; + x ^= x >> 31; +#elif (MI_INTPTR_SIZE==4) + // by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/> + x ^= x >> 16; + x *= 0x7feb352dUL; + x ^= x >> 15; + x *= 0x846ca68bUL; + x ^= x >> 16; +#endif + return x; +} + +// ------------------------------------------------------------------- +// Optimize numa node access for the common case (= one node) +// ------------------------------------------------------------------- + +int _mi_os_numa_node_get(mi_os_tld_t* tld); +size_t _mi_os_numa_node_count_get(void); + +extern _Atomic(size_t) _mi_numa_node_count; +static inline int _mi_os_numa_node(mi_os_tld_t* tld) { + if mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1) { return 0; } + else return _mi_os_numa_node_get(tld); +} +static inline size_t _mi_os_numa_node_count(void) { + const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count); + if mi_likely(count > 0) { return count; } + else return _mi_os_numa_node_count_get(); +} + + + +// ----------------------------------------------------------------------- +// Count bits: trailing or leading zeros (with MI_INTPTR_BITS on all zero) +// ----------------------------------------------------------------------- + +#if defined(__GNUC__) + +#include <limits.h> // LONG_MAX +#define MI_HAVE_FAST_BITSCAN +static inline size_t mi_clz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (INTPTR_MAX == LONG_MAX) + return __builtin_clzl(x); +#else + return __builtin_clzll(x); +#endif +} +static inline size_t mi_ctz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (INTPTR_MAX == LONG_MAX) + return __builtin_ctzl(x); +#else + return __builtin_ctzll(x); +#endif +} + +#elif defined(_MSC_VER) + +#include <limits.h> // LONG_MAX +#include <intrin.h> // BitScanReverse64 +#define MI_HAVE_FAST_BITSCAN +static inline size_t mi_clz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; + unsigned long idx; +#if (INTPTR_MAX == LONG_MAX) + _BitScanReverse(&idx, x); +#else + _BitScanReverse64(&idx, x); +#endif + return ((MI_INTPTR_BITS - 1) - idx); +} +static inline size_t mi_ctz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; + unsigned long idx; +#if (INTPTR_MAX == LONG_MAX) + _BitScanForward(&idx, x); +#else + _BitScanForward64(&idx, x); +#endif + return idx; +} + +#else +static inline size_t mi_ctz32(uint32_t x) { + // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf> + static const unsigned char debruijn[32] = { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + if (x==0) return 32; + return debruijn[((x & -(int32_t)x) * 0x077CB531UL) >> 27]; +} +static inline size_t mi_clz32(uint32_t x) { + // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf> + static const uint8_t debruijn[32] = { + 31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1, + 23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0 + }; + if (x==0) return 32; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return debruijn[(uint32_t)(x * 0x07C4ACDDUL) >> 27]; +} + +static inline size_t mi_clz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (MI_INTPTR_BITS <= 32) + return mi_clz32((uint32_t)x); +#else + size_t count = mi_clz32((uint32_t)(x >> 32)); + if (count < 32) return count; + return (32 + mi_clz32((uint32_t)x)); +#endif +} +static inline size_t mi_ctz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (MI_INTPTR_BITS <= 32) + return mi_ctz32((uint32_t)x); +#else + size_t count = mi_ctz32((uint32_t)x); + if (count < 32) return count; + return (32 + mi_ctz32((uint32_t)(x>>32))); +#endif +} + +#endif + +// "bit scan reverse": Return index of the highest bit (or MI_INTPTR_BITS if `x` is zero) +static inline size_t mi_bsr(uintptr_t x) { + return (x==0 ? MI_INTPTR_BITS : MI_INTPTR_BITS - 1 - mi_clz(x)); +} + + +// --------------------------------------------------------------------------------- +// Provide our own `_mi_memcpy` for potential performance optimizations. +// +// For now, only on Windows with msvc/clang-cl we optimize to `rep movsb` if +// we happen to run on x86/x64 cpu's that have "fast short rep movsb" (FSRM) support +// (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017). See also issue #201 and pr #253. +// --------------------------------------------------------------------------------- + +#if !MI_TRACK_ENABLED && defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) +#include <intrin.h> +extern bool _mi_cpu_has_fsrm; +static inline void _mi_memcpy(void* dst, const void* src, size_t n) { + if (_mi_cpu_has_fsrm) { + __movsb((unsigned char*)dst, (const unsigned char*)src, n); + } + else { + memcpy(dst, src, n); + } +} +static inline void _mi_memzero(void* dst, size_t n) { + if (_mi_cpu_has_fsrm) { + __stosb((unsigned char*)dst, 0, n); + } + else { + memset(dst, 0, n); + } +} +#else +static inline void _mi_memcpy(void* dst, const void* src, size_t n) { + memcpy(dst, src, n); +} +static inline void _mi_memzero(void* dst, size_t n) { + memset(dst, 0, n); +} +#endif + +// ------------------------------------------------------------------------------- +// The `_mi_memcpy_aligned` can be used if the pointers are machine-word aligned +// This is used for example in `mi_realloc`. +// ------------------------------------------------------------------------------- + +#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) +// On GCC/CLang we provide a hint that the pointers are word aligned. +static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) { + mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0)); + void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE); + const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE); + _mi_memcpy(adst, asrc, n); +} + +static inline void _mi_memzero_aligned(void* dst, size_t n) { + mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0); + void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE); + _mi_memzero(adst, n); +} +#else +// Default fallback on `_mi_memcpy` +static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) { + mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0)); + _mi_memcpy(dst, src, n); +} + +static inline void _mi_memzero_aligned(void* dst, size_t n) { + mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0); + _mi_memzero(dst, n); +} +#endif + + +#endif diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc/prim.h b/lib/Utils.Memory/mimalloc/include/mimalloc/prim.h new file mode 100644 index 0000000..9e56069 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc/prim.h @@ -0,0 +1,323 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_PRIM_H +#define MIMALLOC_PRIM_H + + +// -------------------------------------------------------------------------- +// This file specifies the primitive portability API. +// Each OS/host needs to implement these primitives, see `src/prim` +// for implementations on Window, macOS, WASI, and Linux/Unix. +// +// note: on all primitive functions, we always have result parameters != NUL, and: +// addr != NULL and page aligned +// size > 0 and page aligned +// return value is an error code an int where 0 is success. +// -------------------------------------------------------------------------- + +// OS memory configuration +typedef struct mi_os_mem_config_s { + size_t page_size; // 4KiB + size_t large_page_size; // 2MiB + size_t alloc_granularity; // smallest allocation size (on Windows 64KiB) + bool has_overcommit; // can we reserve more memory than can be actually committed? + bool must_free_whole; // must allocated blocks be freed as a whole (false for mmap, true for VirtualAlloc) + bool has_virtual_reserve; // supports virtual address space reservation? (if true we can reserve virtual address space without using commit or physical memory) +} mi_os_mem_config_t; + +// Initialize +void _mi_prim_mem_init( mi_os_mem_config_t* config ); + +// Free OS memory +int _mi_prim_free(void* addr, size_t size ); + +// Allocate OS memory. Return NULL on error. +// The `try_alignment` is just a hint and the returned pointer does not have to be aligned. +// If `commit` is false, the virtual memory range only needs to be reserved (with no access) +// which will later be committed explicitly using `_mi_prim_commit`. +// `is_zero` is set to true if the memory was zero initialized (as on most OS's) +// pre: !commit => !allow_large +// try_alignment >= _mi_os_page_size() and a power of 2 +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr); + +// Commit memory. Returns error code or 0 on success. +// For example, on Linux this would make the memory PROT_READ|PROT_WRITE. +// `is_zero` is set to true if the memory was zero initialized (e.g. on Windows) +int _mi_prim_commit(void* addr, size_t size, bool* is_zero); + +// Decommit memory. Returns error code or 0 on success. The `needs_recommit` result is true +// if the memory would need to be re-committed. For example, on Windows this is always true, +// but on Linux we could use MADV_DONTNEED to decommit which does not need a recommit. +// pre: needs_recommit != NULL +int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit); + +// Reset memory. The range keeps being accessible but the content might be reset. +// Returns error code or 0 on success. +int _mi_prim_reset(void* addr, size_t size); + +// Protect memory. Returns error code or 0 on success. +int _mi_prim_protect(void* addr, size_t size, bool protect); + +// Allocate huge (1GiB) pages possibly associated with a NUMA node. +// `is_zero` is set to true if the memory was zero initialized (as on most OS's) +// pre: size > 0 and a multiple of 1GiB. +// numa_node is either negative (don't care), or a numa node number. +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr); + +// Return the current NUMA node +size_t _mi_prim_numa_node(void); + +// Return the number of logical NUMA nodes +size_t _mi_prim_numa_node_count(void); + +// Clock ticks +mi_msecs_t _mi_prim_clock_now(void); + +// Return process information (only for statistics) +typedef struct mi_process_info_s { + mi_msecs_t elapsed; + mi_msecs_t utime; + mi_msecs_t stime; + size_t current_rss; + size_t peak_rss; + size_t current_commit; + size_t peak_commit; + size_t page_faults; +} mi_process_info_t; + +void _mi_prim_process_info(mi_process_info_t* pinfo); + +// Default stderr output. (only for warnings etc. with verbose enabled) +// msg != NULL && _mi_strlen(msg) > 0 +void _mi_prim_out_stderr( const char* msg ); + +// Get an environment variable. (only for options) +// name != NULL, result != NULL, result_size >= 64 +bool _mi_prim_getenv(const char* name, char* result, size_t result_size); + + +// Fill a buffer with strong randomness; return `false` on error or if +// there is no strong randomization available. +bool _mi_prim_random_buf(void* buf, size_t buf_len); + +// Called on the first thread start, and should ensure `_mi_thread_done` is called on thread termination. +void _mi_prim_thread_init_auto_done(void); + +// Called on process exit and may take action to clean up resources associated with the thread auto done. +void _mi_prim_thread_done_auto_done(void); + +// Called when the default heap for a thread changes +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap); + + +//------------------------------------------------------------------- +// Thread id: `_mi_prim_thread_id()` +// +// Getting the thread id should be performant as it is called in the +// fast path of `_mi_free` and we specialize for various platforms as +// inlined definitions. Regular code should call `init.c:_mi_thread_id()`. +// We only require _mi_prim_thread_id() to return a unique id +// for each thread (unequal to zero). +//------------------------------------------------------------------- + +// defined in `init.c`; do not use these directly +extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from +extern bool _mi_process_is_initialized; // has mi_process_init been called? + +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept; + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { + // Windows: works on Intel and ARM in both 32- and 64-bit + return (uintptr_t)NtCurrentTeb(); +} + +// We use assembly for a fast thread id on the main platforms. The TLS layout depends on +// both the OS and libc implementation so we use specific tests for each main platform. +// If you test on another platform and it works please send a PR :-) +// see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register. +#elif defined(__GNUC__) && ( \ + (defined(__GLIBC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \ + || (defined(__APPLE__) && (defined(__x86_64__) || defined(__aarch64__))) \ + || (defined(__BIONIC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \ + || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \ + || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \ + ) + +static inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept { + void* res; + const size_t ofs = (slot*sizeof(void*)); + #if defined(__i386__) + __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86 32-bit always uses GS + #elif defined(__APPLE__) && defined(__x86_64__) + __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS + #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4) + __asm__("movl %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x32 ABI + #elif defined(__x86_64__) + __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS + #elif defined(__arm__) + void** tcb; MI_UNUSED(ofs); + __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); + res = tcb[slot]; + #elif defined(__aarch64__) + void** tcb; MI_UNUSED(ofs); + #if defined(__APPLE__) // M1, issue #343 + __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb)); + #else + __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); + #endif + res = tcb[slot]; + #endif + return res; +} + +// setting a tls slot is only used on macOS for now +static inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexcept { + const size_t ofs = (slot*sizeof(void*)); + #if defined(__i386__) + __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS + #elif defined(__APPLE__) && defined(__x86_64__) + __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOS uses GS + #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4) + __asm__("movl %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x32 ABI + #elif defined(__x86_64__) + __asm__("movq %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS + #elif defined(__arm__) + void** tcb; MI_UNUSED(ofs); + __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); + tcb[slot] = value; + #elif defined(__aarch64__) + void** tcb; MI_UNUSED(ofs); + #if defined(__APPLE__) // M1, issue #343 + __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb)); + #else + __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); + #endif + tcb[slot] = value; + #endif +} + +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { + #if defined(__BIONIC__) + // issue #384, #495: on the Bionic libc (Android), slot 1 is the thread id + // see: https://github.com/aosp-mirror/platform_bionic/blob/c44b1d0676ded732df4b3b21c5f798eacae93228/libc/platform/bionic/tls_defines.h#L86 + return (uintptr_t)mi_prim_tls_slot(1); + #else + // in all our other targets, slot 0 is the thread id + // glibc: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysdeps/x86_64/nptl/tls.h + // apple: https://github.com/apple/darwin-xnu/blob/main/libsyscall/os/tsd.h#L36 + return (uintptr_t)mi_prim_tls_slot(0); + #endif +} + +#else + +// otherwise use portable C, taking the address of a thread local variable (this is still very fast on most platforms). +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { + return (uintptr_t)&_mi_heap_default; +} + +#endif + + + +/* ---------------------------------------------------------------------------------------- +The thread local default heap: `_mi_prim_get_default_heap()` +This is inlined here as it is on the fast path for allocation functions. + +On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a +__thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures +that the storage will always be available (allocated on the thread stacks). + +On some platforms though we cannot use that when overriding `malloc` since the underlying +TLS implementation (or the loader) will call itself `malloc` on a first access and recurse. +We try to circumvent this in an efficient way: +- macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the + loader itself calls `malloc` even before the modules are initialized. +- OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS). +- DragonFly: defaults are working but seem slow compared to freeBSD (see PR #323) +------------------------------------------------------------------------------------------- */ + +static inline mi_heap_t* mi_prim_get_default_heap(void); + +#if defined(MI_MALLOC_OVERRIDE) +#if defined(__APPLE__) // macOS + #define MI_TLS_SLOT 89 // seems unused? + // #define MI_TLS_RECURSE_GUARD 1 + // other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89) + // see <https://github.com/rweichler/substrate/blob/master/include/pthread_machdep.h> +#elif defined(__OpenBSD__) + // use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16) + // see <https://github.com/openbsd/src/blob/master/lib/libc/include/thread_private.h#L371> + #define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24) + // #elif defined(__DragonFly__) + // #warning "mimalloc is not working correctly on DragonFly yet." + // #define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) <https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libthread_xu/thread/thr_private.h#L458> +#elif defined(__ANDROID__) + // See issue #381 + #define MI_TLS_PTHREAD +#endif +#endif + + +#if defined(MI_TLS_SLOT) + +static inline mi_heap_t* mi_prim_get_default_heap(void) { + mi_heap_t* heap = (mi_heap_t*)mi_prim_tls_slot(MI_TLS_SLOT); + if mi_unlikely(heap == NULL) { + #ifdef __GNUC__ + __asm(""); // prevent conditional load of the address of _mi_heap_empty + #endif + heap = (mi_heap_t*)&_mi_heap_empty; + } + return heap; +} + +#elif defined(MI_TLS_PTHREAD_SLOT_OFS) + +static inline mi_heap_t** mi_prim_tls_pthread_heap_slot(void) { + pthread_t self = pthread_self(); + #if defined(__DragonFly__) + if (self==NULL) return NULL; + #endif + return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS); +} + +static inline mi_heap_t* mi_prim_get_default_heap(void) { + mi_heap_t** pheap = mi_prim_tls_pthread_heap_slot(); + if mi_unlikely(pheap == NULL) return _mi_heap_main_get(); + mi_heap_t* heap = *pheap; + if mi_unlikely(heap == NULL) return (mi_heap_t*)&_mi_heap_empty; + return heap; +} + +#elif defined(MI_TLS_PTHREAD) + +extern pthread_key_t _mi_heap_default_key; +static inline mi_heap_t* mi_prim_get_default_heap(void) { + mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key)); + return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); +} + +#else // default using a thread local variable; used on most platforms. + +static inline mi_heap_t* mi_prim_get_default_heap(void) { + #if defined(MI_TLS_RECURSE_GUARD) + if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get(); + #endif + return _mi_heap_default; +} + +#endif // mi_prim_get_default_heap() + + + +#endif // MIMALLOC_PRIM_H diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc/track.h b/lib/Utils.Memory/mimalloc/include/mimalloc/track.h new file mode 100644 index 0000000..9545f75 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc/track.h @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_TRACK_H +#define MIMALLOC_TRACK_H + +/* ------------------------------------------------------------------------------------------------------ +Track memory ranges with macros for tools like Valgrind address sanitizer, or other memory checkers. +These can be defined for tracking allocation: + + #define mi_track_malloc_size(p,reqsize,size,zero) + #define mi_track_free_size(p,_size) + +The macros are set up such that the size passed to `mi_track_free_size` +always matches the size of `mi_track_malloc_size`. (currently, `size == mi_usable_size(p)`). +The `reqsize` is what the user requested, and `size >= reqsize`. +The `size` is either byte precise (and `size==reqsize`) if `MI_PADDING` is enabled, +or otherwise it is the usable block size which may be larger than the original request. +Use `_mi_block_size_of(void* p)` to get the full block size that was allocated (including padding etc). +The `zero` parameter is `true` if the allocated block is zero initialized. + +Optional: + + #define mi_track_align(p,alignedp,offset,size) + #define mi_track_resize(p,oldsize,newsize) + #define mi_track_init() + +The `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block. +The corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`). +The `mi_track_resize` is currently unused but could be called on reallocations within a block. +`mi_track_init` is called at program start. + +The following macros are for tools like asan and valgrind to track whether memory is +defined, undefined, or not accessible at all: + + #define mi_track_mem_defined(p,size) + #define mi_track_mem_undefined(p,size) + #define mi_track_mem_noaccess(p,size) + +-------------------------------------------------------------------------------------------------------*/ + +#if MI_TRACK_VALGRIND +// valgrind tool + +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 1 // track free of individual blocks on heap_destroy +#define MI_TRACK_TOOL "valgrind" + +#include <valgrind/valgrind.h> +#include <valgrind/memcheck.h> + +#define mi_track_malloc_size(p,reqsize,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero) +#define mi_track_free_size(p,_size) VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/) +#define mi_track_resize(p,oldsize,newsize) VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/) +#define mi_track_mem_defined(p,size) VALGRIND_MAKE_MEM_DEFINED(p,size) +#define mi_track_mem_undefined(p,size) VALGRIND_MAKE_MEM_UNDEFINED(p,size) +#define mi_track_mem_noaccess(p,size) VALGRIND_MAKE_MEM_NOACCESS(p,size) + +#elif MI_TRACK_ASAN +// address sanitizer + +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 0 +#define MI_TRACK_TOOL "asan" + +#include <sanitizer/asan_interface.h> + +#define mi_track_malloc_size(p,reqsize,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size) +#define mi_track_free_size(p,size) ASAN_POISON_MEMORY_REGION(p,size) +#define mi_track_mem_defined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size) +#define mi_track_mem_undefined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size) +#define mi_track_mem_noaccess(p,size) ASAN_POISON_MEMORY_REGION(p,size) + +#elif MI_TRACK_ETW +// windows event tracing + +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 1 +#define MI_TRACK_TOOL "ETW" + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include "../src/prim/windows/etw.h" + +#define mi_track_init() EventRegistermicrosoft_windows_mimalloc(); +#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size) +#define mi_track_free_size(p,size) EventWriteETW_MI_FREE((UINT64)(p), size) + +#else +// no tracking + +#define MI_TRACK_ENABLED 0 +#define MI_TRACK_HEAP_DESTROY 0 +#define MI_TRACK_TOOL "none" + +#define mi_track_malloc_size(p,reqsize,size,zero) +#define mi_track_free_size(p,_size) + +#endif + +// ------------------- +// Utility definitions + +#ifndef mi_track_resize +#define mi_track_resize(p,oldsize,newsize) mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false) +#endif + +#ifndef mi_track_align +#define mi_track_align(p,alignedp,offset,size) mi_track_mem_noaccess(p,offset) +#endif + +#ifndef mi_track_init +#define mi_track_init() +#endif + +#ifndef mi_track_mem_defined +#define mi_track_mem_defined(p,size) +#endif + +#ifndef mi_track_mem_undefined +#define mi_track_mem_undefined(p,size) +#endif + +#ifndef mi_track_mem_noaccess +#define mi_track_mem_noaccess(p,size) +#endif + + +#if MI_PADDING +#define mi_track_malloc(p,reqsize,zero) \ + if ((p)!=NULL) { \ + mi_assert_internal(mi_usable_size(p)==(reqsize)); \ + mi_track_malloc_size(p,reqsize,reqsize,zero); \ + } +#else +#define mi_track_malloc(p,reqsize,zero) \ + if ((p)!=NULL) { \ + mi_assert_internal(mi_usable_size(p)>=(reqsize)); \ + mi_track_malloc_size(p,reqsize,mi_usable_size(p),zero); \ + } +#endif + +#endif diff --git a/lib/Utils.Memory/mimalloc/include/mimalloc/types.h b/lib/Utils.Memory/mimalloc/include/mimalloc/types.h new file mode 100644 index 0000000..2005238 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/include/mimalloc/types.h @@ -0,0 +1,670 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_TYPES_H +#define MIMALLOC_TYPES_H + +// -------------------------------------------------------------------------- +// This file contains the main type definitions for mimalloc: +// mi_heap_t : all data for a thread-local heap, contains +// lists of all managed heap pages. +// mi_segment_t : a larger chunk of memory (32GiB) from where pages +// are allocated. +// mi_page_t : a mimalloc page (usually 64KiB or 512KiB) from +// where objects are allocated. +// -------------------------------------------------------------------------- + + +#include <stddef.h> // ptrdiff_t +#include <stdint.h> // uintptr_t, uint16_t, etc +#include "mimalloc/atomic.h" // _Atomic + +#ifdef _MSC_VER +#pragma warning(disable:4214) // bitfield is not int +#endif + +// Minimal alignment necessary. On most platforms 16 bytes are needed +// due to SSE registers for example. This must be at least `sizeof(void*)` +#ifndef MI_MAX_ALIGN_SIZE +#define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t) +#endif + +// ------------------------------------------------------ +// Variants +// ------------------------------------------------------ + +// Define NDEBUG in the release version to disable assertions. +// #define NDEBUG + +// Define MI_TRACK_<tool> to enable tracking support +// #define MI_TRACK_VALGRIND 1 +// #define MI_TRACK_ASAN 1 +// #define MI_TRACK_ETW 1 + +// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance). +// #define MI_STAT 1 + +// Define MI_SECURE to enable security mitigations +// #define MI_SECURE 1 // guard page around metadata +// #define MI_SECURE 2 // guard page around each mimalloc page +// #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free) +// #define MI_SECURE 4 // checks for double free. (may be more expensive) + +#if !defined(MI_SECURE) +#define MI_SECURE 0 +#endif + +// Define MI_DEBUG for debug mode +// #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free. +// #define MI_DEBUG 2 // + internal assertion checks +// #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON) +#if !defined(MI_DEBUG) +#if !defined(NDEBUG) || defined(_DEBUG) +#define MI_DEBUG 2 +#else +#define MI_DEBUG 0 +#endif +#endif + +// Reserve extra padding at the end of each block to be more resilient against heap block overflows. +// The padding can detect buffer overflow on free. +#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW)) +#define MI_PADDING 1 +#endif + +// Check padding bytes; allows byte-precise buffer overflow detection +#if !defined(MI_PADDING_CHECK) && MI_PADDING && (MI_SECURE>=3 || MI_DEBUG>=1) +#define MI_PADDING_CHECK 1 +#endif + + +// Encoded free lists allow detection of corrupted free lists +// and can detect buffer overflows, modify after free, and double `free`s. +#if (MI_SECURE>=3 || MI_DEBUG>=1) +#define MI_ENCODE_FREELIST 1 +#endif + + +// We used to abandon huge pages but to eagerly deallocate if freed from another thread, +// but that makes it not possible to visit them during a heap walk or include them in a +// `mi_heap_destroy`. We therefore instead reset/decommit the huge blocks if freed from +// another thread so most memory is available until it gets properly freed by the owning thread. +// #define MI_HUGE_PAGE_ABANDON 1 + + +// ------------------------------------------------------ +// Platform specific values +// ------------------------------------------------------ + +// ------------------------------------------------------ +// Size of a pointer. +// We assume that `sizeof(void*)==sizeof(intptr_t)` +// and it holds for all platforms we know of. +// +// However, the C standard only requires that: +// p == (void*)((intptr_t)p)) +// but we also need: +// i == (intptr_t)((void*)i) +// or otherwise one might define an intptr_t type that is larger than a pointer... +// ------------------------------------------------------ + +#if INTPTR_MAX > INT64_MAX +# define MI_INTPTR_SHIFT (4) // assume 128-bit (as on arm CHERI for example) +#elif INTPTR_MAX == INT64_MAX +# define MI_INTPTR_SHIFT (3) +#elif INTPTR_MAX == INT32_MAX +# define MI_INTPTR_SHIFT (2) +#else +#error platform pointers must be 32, 64, or 128 bits +#endif + +#if SIZE_MAX == UINT64_MAX +# define MI_SIZE_SHIFT (3) +typedef int64_t mi_ssize_t; +#elif SIZE_MAX == UINT32_MAX +# define MI_SIZE_SHIFT (2) +typedef int32_t mi_ssize_t; +#else +#error platform objects must be 32 or 64 bits +#endif + +#if (SIZE_MAX/2) > LONG_MAX +# define MI_ZU(x) x##ULL +# define MI_ZI(x) x##LL +#else +# define MI_ZU(x) x##UL +# define MI_ZI(x) x##L +#endif + +#define MI_INTPTR_SIZE (1<<MI_INTPTR_SHIFT) +#define MI_INTPTR_BITS (MI_INTPTR_SIZE*8) + +#define MI_SIZE_SIZE (1<<MI_SIZE_SHIFT) +#define MI_SIZE_BITS (MI_SIZE_SIZE*8) + +#define MI_KiB (MI_ZU(1024)) +#define MI_MiB (MI_KiB*MI_KiB) +#define MI_GiB (MI_MiB*MI_KiB) + + +// ------------------------------------------------------ +// Main internal data-structures +// ------------------------------------------------------ + +// Main tuning parameters for segment and page sizes +// Sizes for 64-bit (usually divide by two for 32-bit) +#define MI_SEGMENT_SLICE_SHIFT (13 + MI_INTPTR_SHIFT) // 64KiB (32KiB on 32-bit) + +#if MI_INTPTR_SIZE > 4 +#define MI_SEGMENT_SHIFT ( 9 + MI_SEGMENT_SLICE_SHIFT) // 32MiB +#else +#define MI_SEGMENT_SHIFT ( 7 + MI_SEGMENT_SLICE_SHIFT) // 4MiB on 32-bit +#endif + +#define MI_SMALL_PAGE_SHIFT (MI_SEGMENT_SLICE_SHIFT) // 64KiB +#define MI_MEDIUM_PAGE_SHIFT ( 3 + MI_SMALL_PAGE_SHIFT) // 512KiB + + +// Derived constants +#define MI_SEGMENT_SIZE (MI_ZU(1)<<MI_SEGMENT_SHIFT) +#define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE +#define MI_SEGMENT_MASK ((uintptr_t)(MI_SEGMENT_ALIGN - 1)) +#define MI_SEGMENT_SLICE_SIZE (MI_ZU(1)<< MI_SEGMENT_SLICE_SHIFT) +#define MI_SLICES_PER_SEGMENT (MI_SEGMENT_SIZE / MI_SEGMENT_SLICE_SIZE) // 1024 + +#define MI_SMALL_PAGE_SIZE (MI_ZU(1)<<MI_SMALL_PAGE_SHIFT) +#define MI_MEDIUM_PAGE_SIZE (MI_ZU(1)<<MI_MEDIUM_PAGE_SHIFT) + +#define MI_SMALL_OBJ_SIZE_MAX (MI_SMALL_PAGE_SIZE/4) // 8KiB on 64-bit +#define MI_MEDIUM_OBJ_SIZE_MAX (MI_MEDIUM_PAGE_SIZE/4) // 128KiB on 64-bit +#define MI_MEDIUM_OBJ_WSIZE_MAX (MI_MEDIUM_OBJ_SIZE_MAX/MI_INTPTR_SIZE) +#define MI_LARGE_OBJ_SIZE_MAX (MI_SEGMENT_SIZE/2) // 32MiB on 64-bit +#define MI_LARGE_OBJ_WSIZE_MAX (MI_LARGE_OBJ_SIZE_MAX/MI_INTPTR_SIZE) + +// Maximum number of size classes. (spaced exponentially in 12.5% increments) +#define MI_BIN_HUGE (73U) + +#if (MI_MEDIUM_OBJ_WSIZE_MAX >= 655360) +#error "mimalloc internal: define more bins" +#endif + +// Maximum slice offset (15) +#define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1) + +// Used as a special value to encode block sizes in 32 bits. +#define MI_HUGE_BLOCK_SIZE ((uint32_t)(2*MI_GiB)) + +// blocks up to this size are always allocated aligned +#define MI_MAX_ALIGN_GUARANTEE (8*MI_MAX_ALIGN_SIZE) + +// Alignments over MI_ALIGNMENT_MAX are allocated in dedicated huge page segments +#define MI_ALIGNMENT_MAX (MI_SEGMENT_SIZE >> 1) + + +// ------------------------------------------------------ +// Mimalloc pages contain allocated blocks +// ------------------------------------------------------ + +// The free lists use encoded next fields +// (Only actually encodes when MI_ENCODED_FREELIST is defined.) +typedef uintptr_t mi_encoded_t; + +// thread id's +typedef size_t mi_threadid_t; + +// free lists contain blocks +typedef struct mi_block_s { + mi_encoded_t next; +} mi_block_t; + + +// The delayed flags are used for efficient multi-threaded free-ing +typedef enum mi_delayed_e { + MI_USE_DELAYED_FREE = 0, // push on the owning heap thread delayed list + MI_DELAYED_FREEING = 1, // temporary: another thread is accessing the owning heap + MI_NO_DELAYED_FREE = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list + MI_NEVER_DELAYED_FREE = 3 // sticky, only resets on page reclaim +} mi_delayed_t; + + +// The `in_full` and `has_aligned` page flags are put in a union to efficiently +// test if both are false (`full_aligned == 0`) in the `mi_free` routine. +#if !MI_TSAN +typedef union mi_page_flags_s { + uint8_t full_aligned; + struct { + uint8_t in_full : 1; + uint8_t has_aligned : 1; + } x; +} mi_page_flags_t; +#else +// under thread sanitizer, use a byte for each flag to suppress warning, issue #130 +typedef union mi_page_flags_s { + uint16_t full_aligned; + struct { + uint8_t in_full; + uint8_t has_aligned; + } x; +} mi_page_flags_t; +#endif + +// Thread free list. +// We use the bottom 2 bits of the pointer for mi_delayed_t flags +typedef uintptr_t mi_thread_free_t; + +// A page contains blocks of one specific size (`block_size`). +// Each page has three list of free blocks: +// `free` for blocks that can be allocated, +// `local_free` for freed blocks that are not yet available to `mi_malloc` +// `thread_free` for freed blocks by other threads +// The `local_free` and `thread_free` lists are migrated to the `free` list +// when it is exhausted. The separate `local_free` list is necessary to +// implement a monotonic heartbeat. The `thread_free` list is needed for +// avoiding atomic operations in the common case. +// +// +// `used - |thread_free|` == actual blocks that are in use (alive) +// `used - |thread_free| + |free| + |local_free| == capacity` +// +// We don't count `freed` (as |free|) but use `used` to reduce +// the number of memory accesses in the `mi_page_all_free` function(s). +// +// Notes: +// - Access is optimized for `mi_free` and `mi_page_alloc` (in `alloc.c`) +// - Using `uint16_t` does not seem to slow things down +// - The size is 8 words on 64-bit which helps the page index calculations +// (and 10 words on 32-bit, and encoded free lists add 2 words. Sizes 10 +// and 12 are still good for address calculation) +// - To limit the structure size, the `xblock_size` is 32-bits only; for +// blocks > MI_HUGE_BLOCK_SIZE the size is determined from the segment page size +// - `thread_free` uses the bottom bits as a delayed-free flags to optimize +// concurrent frees where only the first concurrent free adds to the owning +// heap `thread_delayed_free` list (see `alloc.c:mi_free_block_mt`). +// The invariant is that no-delayed-free is only set if there is +// at least one block that will be added, or as already been added, to +// the owning heap `thread_delayed_free` list. This guarantees that pages +// will be freed correctly even if only other threads free blocks. +typedef struct mi_page_s { + // "owned" by the segment + uint32_t slice_count; // slices in this page (0 if not a page) + uint32_t slice_offset; // distance from the actual page data slice (0 if a page) + uint8_t is_committed : 1; // `true` if the page virtual memory is committed + uint8_t is_zero_init : 1; // `true` if the page was initially zero initialized + + // layout like this to optimize access in `mi_malloc` and `mi_free` + uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear` + uint16_t reserved; // number of blocks reserved in memory + mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits) + uint8_t free_is_zero : 1; // `true` if the blocks in the free list are zero initialized + uint8_t retire_expire : 7; // expiration count for retired blocks + + mi_block_t* free; // list of available free blocks (`malloc` allocates from this list) + uint32_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`) + uint32_t xblock_size; // size available in each block (always `>0`) + mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`) + + #if (MI_ENCODE_FREELIST || MI_PADDING) + uintptr_t keys[2]; // two random keys to encode the free lists (see `_mi_block_next`) or padding canary + #endif + + _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads + _Atomic(uintptr_t) xheap; + + struct mi_page_s* next; // next page owned by this thread with the same `block_size` + struct mi_page_s* prev; // previous page owned by this thread with the same `block_size` + + // 64-bit 9 words, 32-bit 12 words, (+2 for secure) + #if MI_INTPTR_SIZE==8 + uintptr_t padding[1]; + #endif +} mi_page_t; + + + +// ------------------------------------------------------ +// Mimalloc segments contain mimalloc pages +// ------------------------------------------------------ + +typedef enum mi_page_kind_e { + MI_PAGE_SMALL, // small blocks go into 64KiB pages inside a segment + MI_PAGE_MEDIUM, // medium blocks go into medium pages inside a segment + MI_PAGE_LARGE, // larger blocks go into a page of just one block + MI_PAGE_HUGE, // huge blocks (> 16 MiB) are put into a single page in a single segment. +} mi_page_kind_t; + +typedef enum mi_segment_kind_e { + MI_SEGMENT_NORMAL, // MI_SEGMENT_SIZE size with pages inside. + MI_SEGMENT_HUGE, // > MI_LARGE_SIZE_MAX segment with just one huge page inside. +} mi_segment_kind_t; + +// ------------------------------------------------------ +// A segment holds a commit mask where a bit is set if +// the corresponding MI_COMMIT_SIZE area is committed. +// The MI_COMMIT_SIZE must be a multiple of the slice +// size. If it is equal we have the most fine grained +// decommit (but setting it higher can be more efficient). +// The MI_MINIMAL_COMMIT_SIZE is the minimal amount that will +// be committed in one go which can be set higher than +// MI_COMMIT_SIZE for efficiency (while the decommit mask +// is still tracked in fine-grained MI_COMMIT_SIZE chunks) +// ------------------------------------------------------ + +#define MI_MINIMAL_COMMIT_SIZE (1*MI_SEGMENT_SLICE_SIZE) +#define MI_COMMIT_SIZE (MI_SEGMENT_SLICE_SIZE) // 64KiB +#define MI_COMMIT_MASK_BITS (MI_SEGMENT_SIZE / MI_COMMIT_SIZE) +#define MI_COMMIT_MASK_FIELD_BITS MI_SIZE_BITS +#define MI_COMMIT_MASK_FIELD_COUNT (MI_COMMIT_MASK_BITS / MI_COMMIT_MASK_FIELD_BITS) + +#if (MI_COMMIT_MASK_BITS != (MI_COMMIT_MASK_FIELD_COUNT * MI_COMMIT_MASK_FIELD_BITS)) +#error "the segment size must be exactly divisible by the (commit size * size_t bits)" +#endif + +typedef struct mi_commit_mask_s { + size_t mask[MI_COMMIT_MASK_FIELD_COUNT]; +} mi_commit_mask_t; + +typedef mi_page_t mi_slice_t; +typedef int64_t mi_msecs_t; + + +// Memory can reside in arena's, direct OS allocated, or statically allocated. The memid keeps track of this. +typedef enum mi_memkind_e { + MI_MEM_NONE, // not allocated + MI_MEM_EXTERNAL, // not owned by mimalloc but provided externally (via `mi_manage_os_memory` for example) + MI_MEM_STATIC, // allocated in a static area and should not be freed (for arena meta data for example) + MI_MEM_OS, // allocated from the OS + MI_MEM_OS_HUGE, // allocated as huge os pages + MI_MEM_OS_REMAP, // allocated in a remapable area (i.e. using `mremap`) + MI_MEM_ARENA // allocated from an arena (the usual case) +} mi_memkind_t; + +static inline bool mi_memkind_is_os(mi_memkind_t memkind) { + return (memkind >= MI_MEM_OS && memkind <= MI_MEM_OS_REMAP); +} + +typedef struct mi_memid_os_info { + void* base; // actual base address of the block (used for offset aligned allocations) + size_t alignment; // alignment at allocation +} mi_memid_os_info_t; + +typedef struct mi_memid_arena_info { + size_t block_index; // index in the arena + mi_arena_id_t id; // arena id (>= 1) + bool is_exclusive; // the arena can only be used for specific arena allocations +} mi_memid_arena_info_t; + +typedef struct mi_memid_s { + union { + mi_memid_os_info_t os; // only used for MI_MEM_OS + mi_memid_arena_info_t arena; // only used for MI_MEM_ARENA + } mem; + bool is_pinned; // `true` if we cannot decommit/reset/protect in this memory (e.g. when allocated using large OS pages) + bool initially_committed;// `true` if the memory was originally allocated as committed + bool initially_zero; // `true` if the memory was originally zero initialized + mi_memkind_t memkind; +} mi_memid_t; + + +// Segments are large allocated memory blocks (8mb on 64 bit) from +// the OS. Inside segments we allocated fixed size _pages_ that +// contain blocks. +typedef struct mi_segment_s { + // constant fields + mi_memid_t memid; // memory id for arena allocation + bool allow_decommit; + bool allow_purge; + size_t segment_size; + + // segment fields + mi_msecs_t purge_expire; + mi_commit_mask_t purge_mask; + mi_commit_mask_t commit_mask; + + _Atomic(struct mi_segment_s*) abandoned_next; + + // from here is zero initialized + struct mi_segment_s* next; // the list of freed segments in the cache (must be first field, see `segment.c:mi_segment_init`) + + size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`) + size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long) + size_t used; // count of pages in use + uintptr_t cookie; // verify addresses in debug mode: `mi_ptr_cookie(segment) == segment->cookie` + + size_t segment_slices; // for huge segments this may be different from `MI_SLICES_PER_SEGMENT` + size_t segment_info_slices; // initial slices we are using segment info and possible guard pages. + + // layout like this to optimize access in `mi_free` + mi_segment_kind_t kind; + size_t slice_entries; // entries in the `slices` array, at most `MI_SLICES_PER_SEGMENT` + _Atomic(mi_threadid_t) thread_id; // unique id of the thread owning this segment + + mi_slice_t slices[MI_SLICES_PER_SEGMENT+1]; // one more for huge blocks with large alignment +} mi_segment_t; + + +// ------------------------------------------------------ +// Heaps +// Provide first-class heaps to allocate from. +// A heap just owns a set of pages for allocation and +// can only be allocate/reallocate from the thread that created it. +// Freeing blocks can be done from any thread though. +// Per thread, the segments are shared among its heaps. +// Per thread, there is always a default heap that is +// used for allocation; it is initialized to statically +// point to an empty heap to avoid initialization checks +// in the fast path. +// ------------------------------------------------------ + +// Thread local data +typedef struct mi_tld_s mi_tld_t; + +// Pages of a certain block size are held in a queue. +typedef struct mi_page_queue_s { + mi_page_t* first; + mi_page_t* last; + size_t block_size; +} mi_page_queue_t; + +#define MI_BIN_FULL (MI_BIN_HUGE+1) + +// Random context +typedef struct mi_random_cxt_s { + uint32_t input[16]; + uint32_t output[16]; + int output_available; + bool weak; +} mi_random_ctx_t; + + +// In debug mode there is a padding structure at the end of the blocks to check for buffer overflows +#if (MI_PADDING) +typedef struct mi_padding_s { + uint32_t canary; // encoded block value to check validity of the padding (in case of overflow) + uint32_t delta; // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes) +} mi_padding_t; +#define MI_PADDING_SIZE (sizeof(mi_padding_t)) +#define MI_PADDING_WSIZE ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE) +#else +#define MI_PADDING_SIZE 0 +#define MI_PADDING_WSIZE 0 +#endif + +#define MI_PAGES_DIRECT (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1) + + +// A heap owns a set of pages. +struct mi_heap_s { + mi_tld_t* tld; + mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size. + mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin") + _Atomic(mi_block_t*) thread_delayed_free; + mi_threadid_t thread_id; // thread this heap belongs too + mi_arena_id_t arena_id; // arena id if the heap belongs to a specific arena (or 0) + uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`) + uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list + mi_random_ctx_t random; // random number context used for secure allocation + size_t page_count; // total number of pages in the `pages` queues. + size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues) + size_t page_retired_max; // largest retired index into the `pages` array. + mi_heap_t* next; // list of heaps per thread + bool no_reclaim; // `true` if this heap should not reclaim abandoned pages +}; + + + +// ------------------------------------------------------ +// Debug +// ------------------------------------------------------ + +#if !defined(MI_DEBUG_UNINIT) +#define MI_DEBUG_UNINIT (0xD0) +#endif +#if !defined(MI_DEBUG_FREED) +#define MI_DEBUG_FREED (0xDF) +#endif +#if !defined(MI_DEBUG_PADDING) +#define MI_DEBUG_PADDING (0xDE) +#endif + +#if (MI_DEBUG) +// use our own assertion to print without memory allocation +void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func ); +#define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__)) +#else +#define mi_assert(x) +#endif + +#if (MI_DEBUG>1) +#define mi_assert_internal mi_assert +#else +#define mi_assert_internal(x) +#endif + +#if (MI_DEBUG>2) +#define mi_assert_expensive mi_assert +#else +#define mi_assert_expensive(x) +#endif + +// ------------------------------------------------------ +// Statistics +// ------------------------------------------------------ + +#ifndef MI_STAT +#if (MI_DEBUG>0) +#define MI_STAT 2 +#else +#define MI_STAT 0 +#endif +#endif + +typedef struct mi_stat_count_s { + int64_t allocated; + int64_t freed; + int64_t peak; + int64_t current; +} mi_stat_count_t; + +typedef struct mi_stat_counter_s { + int64_t total; + int64_t count; +} mi_stat_counter_t; + +typedef struct mi_stats_s { + mi_stat_count_t segments; + mi_stat_count_t pages; + mi_stat_count_t reserved; + mi_stat_count_t committed; + mi_stat_count_t reset; + mi_stat_count_t purged; + mi_stat_count_t page_committed; + mi_stat_count_t segments_abandoned; + mi_stat_count_t pages_abandoned; + mi_stat_count_t threads; + mi_stat_count_t normal; + mi_stat_count_t huge; + mi_stat_count_t large; + mi_stat_count_t malloc; + mi_stat_count_t segments_cache; + mi_stat_counter_t pages_extended; + mi_stat_counter_t mmap_calls; + mi_stat_counter_t commit_calls; + mi_stat_counter_t reset_calls; + mi_stat_counter_t purge_calls; + mi_stat_counter_t page_no_retire; + mi_stat_counter_t searches; + mi_stat_counter_t normal_count; + mi_stat_counter_t huge_count; + mi_stat_counter_t large_count; +#if MI_STAT>1 + mi_stat_count_t normal_bins[MI_BIN_HUGE+1]; +#endif +} mi_stats_t; + + +void _mi_stat_increase(mi_stat_count_t* stat, size_t amount); +void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount); +void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount); + +#if (MI_STAT) +#define mi_stat_increase(stat,amount) _mi_stat_increase( &(stat), amount) +#define mi_stat_decrease(stat,amount) _mi_stat_decrease( &(stat), amount) +#define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount) +#else +#define mi_stat_increase(stat,amount) (void)0 +#define mi_stat_decrease(stat,amount) (void)0 +#define mi_stat_counter_increase(stat,amount) (void)0 +#endif + +#define mi_heap_stat_counter_increase(heap,stat,amount) mi_stat_counter_increase( (heap)->tld->stats.stat, amount) +#define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount) +#define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount) + +// ------------------------------------------------------ +// Thread Local data +// ------------------------------------------------------ + +// A "span" is is an available range of slices. The span queues keep +// track of slice spans of at most the given `slice_count` (but more than the previous size class). +typedef struct mi_span_queue_s { + mi_slice_t* first; + mi_slice_t* last; + size_t slice_count; +} mi_span_queue_t; + +#define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT) + +// OS thread local data +typedef struct mi_os_tld_s { + size_t region_idx; // start point for next allocation + mi_stats_t* stats; // points to tld stats +} mi_os_tld_t; + + +// Segments thread local data +typedef struct mi_segments_tld_s { + mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments + size_t count; // current number of segments; + size_t peak_count; // peak number of segments + size_t current_size; // current size of all segments + size_t peak_size; // peak size of all segments + mi_stats_t* stats; // points to tld stats + mi_os_tld_t* os; // points to os stats +} mi_segments_tld_t; + +// Thread local data +struct mi_tld_s { + unsigned long long heartbeat; // monotonic heartbeat count + bool recurse; // true if deferred was called; used to prevent infinite recursion. + mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted) + mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates) + mi_segments_tld_t segments; // segment tld + mi_os_tld_t os; // os tld + mi_stats_t stats; // statistics +}; + +#endif diff --git a/lib/Utils.Memory/mimalloc/mimalloc.pc.in b/lib/Utils.Memory/mimalloc/mimalloc.pc.in new file mode 100644 index 0000000..36da203 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/mimalloc.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@libdir_for_pc_file@ +includedir=@includedir_for_pc_file@ + +Name: @PROJECT_NAME@ +Description: A compact general purpose allocator with excellent performance +Version: @PACKAGE_VERSION@ +URL: https://github.com/microsoft/mimalloc/ +Libs: -L${libdir} -lmimalloc +Libs.private: @pc_libraries@ +Cflags: -I${includedir} diff --git a/lib/Utils.Memory/mimalloc/readme.md b/lib/Utils.Memory/mimalloc/readme.md new file mode 100644 index 0000000..85d3563 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/readme.md @@ -0,0 +1,827 @@ + +<img align="left" width="100" height="100" src="doc/mimalloc-logo.png"/> + +[<img align="right" src="https://dev.azure.com/Daan0324/mimalloc/_apis/build/status/microsoft.mimalloc?branchName=dev"/>](https://dev.azure.com/Daan0324/mimalloc/_build?definitionId=1&_a=summary) + +# mimalloc + + + +mimalloc (pronounced "me-malloc") +is a general purpose allocator with excellent [performance](#performance) characteristics. +Initially developed by Daan Leijen for the runtime systems of the +[Koka](https://koka-lang.github.io) and [Lean](https://github.com/leanprover/lean) languages. + +Latest release tag: `v2.1.2` (2023-04-24). +Latest stable tag: `v1.8.2` (2023-04-24). + +mimalloc is a drop-in replacement for `malloc` and can be used in other programs +without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as: +``` +> LD_PRELOAD=/usr/lib/libmimalloc.so myprogram +``` +It also includes a robust way to override the default allocator in [Windows](#override_on_windows). Notable aspects of the design include: + +- __small and consistent__: the library is about 8k LOC using simple and + consistent data structures. This makes it very suitable + to integrate and adapt in other projects. For runtime systems it + provides hooks for a monotonic _heartbeat_ and deferred freeing (for + bounded worst-case times with reference counting). + Partly due to its simplicity, mimalloc has been ported to many systems (Windows, macOS, + Linux, WASM, various BSD's, Haiku, MUSL, etc) and has excellent support for dynamic overriding. +- __free list sharding__: instead of one big free list (per size class) we have + many smaller lists per "mimalloc page" which reduces fragmentation and + increases locality -- + things that are allocated close in time get allocated close in memory. + (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system). +- __free list multi-sharding__: the big idea! Not only do we shard the free list + per mimalloc page, but for each page we have multiple free lists. In particular, there + is one list for thread-local `free` operations, and another one for concurrent `free` + operations. Free-ing from another thread can now be a single CAS without needing + sophisticated coordination between threads. Since there will be + thousands of separate free lists, contention is naturally distributed over the heap, + and the chance of contending on a single location will be low -- this is quite + similar to randomized algorithms like skip lists where adding + a random oracle removes the need for a more complex algorithm. +- __eager page purging__: when a "page" becomes empty (with increased chance + due to free list sharding) the memory is marked to the OS as unused (reset or decommitted) + reducing (real) memory pressure and fragmentation, especially in long running + programs. +- __secure__: _mimalloc_ can be built in secure mode, adding guard pages, + randomized allocation, encrypted free lists, etc. to protect against various + heap vulnerabilities. The performance penalty is usually around 10% on average + over our benchmarks. +- __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions. + A heap can be destroyed at once instead of deallocating each object separately. +- __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation + times (_wcat_) (upto OS primitives), bounded space overhead (~0.2% meta-data, with low + internal fragmentation), and has no internal points of contention using only atomic operations. +- __fast__: In our benchmarks (see [below](#performance)), + _mimalloc_ outperforms other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), + and often uses less memory. A nice property is that it does consistently well over a wide range + of benchmarks. There is also good huge OS page support for larger server programs. + +The [documentation](https://microsoft.github.io/mimalloc) gives a full overview of the API. +You can read more on the design of _mimalloc_ in the [technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action) which also has detailed benchmark results. + +Enjoy! + +### Branches + +* `master`: latest stable release (based on `dev-slice`). +* `dev`: development branch for mimalloc v1. Use this branch for submitting PR's. +* `dev-slice`: development branch for mimalloc v2. This branch is downstream of `dev`. + +### Releases + +Note: the `v2.x` version has a new algorithm for managing internal mimalloc pages that tends to reduce memory usage + and fragmentation compared to mimalloc `v1.x` (especially for large workloads). Should otherwise have similar performance + (see [below](#performance)); please report if you observe any significant performance regression. + +* 2023-04-24, `v1.8.2`, `v2.1.2`: Fixes build issues on freeBSD, musl, and C17 (UE 5.1.1). Reduce code size/complexity + by removing regions and segment-cache's and only use arenas with improved memory purging -- this may improve memory + usage as well for larger services. Renamed options for consistency. Improved Valgrind and ASAN checking. + +* 2023-04-03, `v1.8.1`, `v2.1.1`: Fixes build issues on some platforms. + +* 2023-03-29, `v1.8.0`, `v2.1.0`: Improved support dynamic overriding on Windows 11. Improved tracing precision + with [asan](#asan) and [Valgrind](#valgrind), and added Windows event tracing [ETW](#ETW) (contributed by Xinglong He). Created an OS + abstraction layer to make it easier to port and separate platform dependent code (in `src/prim`). Fixed C++ STL compilation on older Microsoft C++ compilers, and various small bug fixes. + +* 2022-12-23, `v1.7.9`, `v2.0.9`: Supports building with [asan](#asan) and improved [Valgrind](#valgrind) support. + Support abitrary large alignments (in particular for `std::pmr` pools). + Added C++ STL allocators attached to a specific heap (thanks @vmarkovtsev). + Heap walks now visit all object (including huge objects). Support Windows nano server containers (by Johannes Schindelin,@dscho). Various small bug fixes. + +* 2022-11-03, `v1.7.7`, `v2.0.7`: Initial support for [Valgrind](#valgrind) for leak testing and heap block overflow + detection. Initial + support for attaching heaps to a speficic memory area (only in v2). Fix `realloc` behavior for zero size blocks, remove restriction to integral multiple of the alignment in `alloc_align`, improved aligned allocation performance, reduced contention with many threads on few processors (thank you @dposluns!), vs2022 support, support `pkg-config`, . + +* 2022-04-14, `v1.7.6`, `v2.0.6`: fix fallback path for aligned OS allocation on Windows, improve Windows aligned allocation + even when compiling with older SDK's, fix dynamic overriding on macOS Monterey, fix MSVC C++ dynamic overriding, fix + warnings under Clang 14, improve performance if many OS threads are created and destroyed, fix statistics for large object + allocations, using MIMALLOC_VERBOSE=1 has no maximum on the number of error messages, various small fixes. + +* 2022-02-14, `v1.7.5`, `v2.0.5` (alpha): fix malloc override on + Windows 11, fix compilation with musl, potentially reduced + committed memory, add `bin/minject` for Windows, + improved wasm support, faster aligned allocation, + various small fixes. + +* [Older release notes](#older-release-notes) + +Special thanks to: + +* [David Carlier](https://devnexen.blogspot.com/) (@devnexen) for his many contributions, and making + mimalloc work better on many less common operating systems, like Haiku, Dragonfly, etc. +* Mary Feofanova (@mary3000), Evgeniy Moiseenko, and Manuel Pöter (@mpoeter) for making mimalloc TSAN checkable, and finding + memory model bugs using the [genMC] model checker. +* Weipeng Liu (@pongba), Zhuowei Li, Junhua Wang, and Jakub Szymanski, for their early support of mimalloc and deployment + at large scale services, leading to many improvements in the mimalloc algorithms for large workloads. +* Jason Gibson (@jasongibson) for exhaustive testing on large scale workloads and server environments, and finding complex bugs + in (early versions of) `mimalloc`. +* Manuel Pöter (@mpoeter) and Sam Gross(@colesbury) for finding an ABA concurrency issue in abandoned segment reclamation. Sam also created the [no GIL](https://github.com/colesbury/nogil) Python fork which + uses mimalloc internally. + + +[genMC]: https://plv.mpi-sws.org/genmc/ + +### Usage + +mimalloc is used in various large scale low-latency services and programs, for example: + +<a href="https://www.bing.com"><img height="50" align="left" src="https://upload.wikimedia.org/wikipedia/commons/e/e9/Bing_logo.svg"></a> +<a href="https://azure.microsoft.com/"><img height="50" align="left" src="https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg"></a> +<a href="https://deathstrandingpc.505games.com"><img height="100" src="doc/ds-logo.png"></a> +<a href="https://docs.unrealengine.com/4.26/en-US/WhatsNew/Builds/ReleaseNotes/4_25/"><img height="100" src="doc/unreal-logo.svg"></a> +<a href="https://cab.spbu.ru/software/spades/"><img height="100" src="doc/spades-logo.png"></a> + + +# Building + +## Windows + +Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build. +The `mimalloc` project builds a static library (in `out/msvc-x64`), while the +`mimalloc-override` project builds a DLL for overriding malloc +in the entire program. + +## macOS, Linux, BSD, etc. + +We use [`cmake`](https://cmake.org)<sup>1</sup> as the build system: + +``` +> mkdir -p out/release +> cd out/release +> cmake ../.. +> make +``` +This builds the library as a shared (dynamic) +library (`.so` or `.dylib`), a static library (`.a`), and +as a single object file (`.o`). + +`> sudo make install` (install the library and header files in `/usr/local/lib` and `/usr/local/include`) + +You can build the debug version which does many internal checks and +maintains detailed statistics as: + +``` +> mkdir -p out/debug +> cd out/debug +> cmake -DCMAKE_BUILD_TYPE=Debug ../.. +> make +``` +This will name the shared library as `libmimalloc-debug.so`. + +Finally, you can build a _secure_ version that uses guard pages, encrypted +free lists, etc., as: +``` +> mkdir -p out/secure +> cd out/secure +> cmake -DMI_SECURE=ON ../.. +> make +``` +This will name the shared library as `libmimalloc-secure.so`. +Use `ccmake`<sup>2</sup> instead of `cmake` +to see and customize all the available build options. + +Notes: +1. Install CMake: `sudo apt-get install cmake` +2. Install CCMake: `sudo apt-get install cmake-curses-gui` + + +## Single source + +You can also directly build the single `src/static.c` file as part of your project without +needing `cmake` at all. Make sure to also add the mimalloc `include` directory to the include path. + + +# Using the library + +The preferred usage is including `<mimalloc.h>`, linking with +the shared- or static library, and using the `mi_malloc` API exclusively for allocation. For example, +``` +> gcc -o myprogram -lmimalloc myfile.c +``` + +mimalloc uses only safe OS calls (`mmap` and `VirtualAlloc`) and can co-exist +with other allocators linked to the same program. +If you use `cmake`, you can simply use: +``` +find_package(mimalloc 1.4 REQUIRED) +``` +in your `CMakeLists.txt` to find a locally installed mimalloc. Then use either: +``` +target_link_libraries(myapp PUBLIC mimalloc) +``` +to link with the shared (dynamic) library, or: +``` +target_link_libraries(myapp PUBLIC mimalloc-static) +``` +to link with the static library. See `test\CMakeLists.txt` for an example. + +For best performance in C++ programs, it is also recommended to override the +global `new` and `delete` operators. For convience, mimalloc provides +[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) which does this for you -- just include it in a single(!) source file in your project. +In C++, mimalloc also provides the `mi_stl_allocator` struct which implements the `std::allocator` +interface. + +You can pass environment variables to print verbose messages (`MIMALLOC_VERBOSE=1`) +and statistics (`MIMALLOC_SHOW_STATS=1`) (in the debug version): +``` +> env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363 + +175451865205073170563711388363 = 374456281610909315237213 * 468551 + +heap stats: peak total freed unit +normal 2: 16.4 kb 17.5 mb 17.5 mb 16 b ok +normal 3: 16.3 kb 15.2 mb 15.2 mb 24 b ok +normal 4: 64 b 4.6 kb 4.6 kb 32 b ok +normal 5: 80 b 118.4 kb 118.4 kb 40 b ok +normal 6: 48 b 48 b 48 b 48 b ok +normal 17: 960 b 960 b 960 b 320 b ok + +heap stats: peak total freed unit + normal: 33.9 kb 32.8 mb 32.8 mb 1 b ok + huge: 0 b 0 b 0 b 1 b ok + total: 33.9 kb 32.8 mb 32.8 mb 1 b ok +malloc requested: 32.8 mb + + committed: 58.2 kb 58.2 kb 58.2 kb 1 b ok + reserved: 2.0 mb 2.0 mb 2.0 mb 1 b ok + reset: 0 b 0 b 0 b 1 b ok + segments: 1 1 1 +-abandoned: 0 + pages: 6 6 6 +-abandoned: 0 + mmaps: 3 + mmap fast: 0 + mmap slow: 1 + threads: 0 + elapsed: 2.022s + process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb +``` + +The above model of using the `mi_` prefixed API is not always possible +though in existing programs that already use the standard malloc interface, +and another option is to override the standard malloc interface +completely and redirect all calls to the _mimalloc_ library instead . + +## Environment Options + +You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)), or via environment variables: + +- `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates. +- `MIMALLOC_VERBOSE=1`: show verbose messages. +- `MIMALLOC_SHOW_ERRORS=1`: show error and warning messages. + +Advanced options: + +- `MIMALLOC_PURGE_DELAY=N`: the delay in `N` milli-seconds (by default `10`) after which mimalloc will purge + OS pages that are not in use. This signals to the OS that the underlying physical memory can be reused which + can reduce memory fragmentation especially in long running (server) programs. Setting `N` to `0` purges immediately when + a page becomes unused which can improve memory usage but also decreases performance. Setting `N` to a higher + value like `100` can improve performance (sometimes by a lot) at the cost of potentially using more memory at times. + Setting it to `-1` disables purging completely. +- `MIMALLOC_ARENA_EAGER_COMMIT=1`: turns on eager commit for the large arenas (usually 1GiB) from which mimalloc + allocates segments and pages. This is by default + only enabled on overcommit systems (e.g. Linux) but enabling it explicitly on other systems (like Windows or macOS) + may improve performance. Note that eager commit only increases the commit but not the actual the peak resident set + (rss) so it is generally ok to enable this. + +Further options for large workloads and services: + +- `MIMALLOC_USE_NUMA_NODES=N`: pretend there are at most `N` NUMA nodes. If not set, the actual NUMA nodes are detected + at runtime. Setting `N` to 1 may avoid problems in some virtual environments. Also, setting it to a lower number than + the actual NUMA nodes is fine and will only cause threads to potentially allocate more memory across actual NUMA + nodes (but this can happen in any case as NUMA local allocation is always a best effort but not guaranteed). +- `MIMALLOC_ALLOW_LARGE_OS_PAGES=1`: use large OS pages (2MiB) when available; for some workloads this can significantly + improve performance. Use `MIMALLOC_VERBOSE` to check if the large OS pages are enabled -- usually one needs + to explicitly allow large OS pages (as on [Windows][windows-huge] and [Linux][linux-huge]). However, sometimes + the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that + can have fragmented memory (for that reason, we generally recommend to use `MIMALLOC_RESERVE_HUGE_OS_PAGES` instead whenever possible). +- `MIMALLOC_RESERVE_HUGE_OS_PAGES=N`: where `N` is the number of 1GiB _huge_ OS pages. This reserves the huge pages at + startup and sometimes this can give a large (latency) performance improvement on big workloads. + Usually it is better to not use `MIMALLOC_ALLOW_LARGE_OS_PAGES=1` in combination with this setting. Just like large + OS pages, use with care as reserving + contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at + startup only once). + Note that we usually need to explicitly enable huge OS pages (as on [Windows][windows-huge] and [Linux][linux-huge])). + With huge OS pages, it may be beneficial to set the setting + `MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB) + of a thread to not allocate in the huge OS pages; this prevents threads that are short lived + and allocate just a little to take up space in the huge OS page area (which cannot be purged). + The huge pages are usually allocated evenly among NUMA nodes. + We can use `MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N` where `N` is the numa node (starting at 0) to allocate all + the huge pages at a specific numa node instead. + +Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write +for all pages in the original process including the huge OS pages. When any memory is now written in that area, the +OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in large increments. + +[linux-huge]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5 +[windows-huge]: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017 + +## Secure Mode + +_mimalloc_ can be build in secure mode by using the `-DMI_SECURE=ON` flags in `cmake`. This build enables various mitigations +to make mimalloc more robust against exploits. In particular: + +- All internal mimalloc pages are surrounded by guard pages and the heap metadata is behind a guard page as well (so a buffer overflow + exploit cannot reach into the metadata). +- All free list pointers are + [encoded](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) + with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption. +- Double free's are detected (and ignored). +- The free lists are initialized in a random order and allocation randomly chooses between extension and reuse within a page to + mitigate against attacks that rely on a predicable allocation order. Similarly, the larger heap blocks allocated by mimalloc + from the OS are also address randomized. + +As always, evaluate with care as part of an overall security strategy as all of the above are mitigations but not guarantees. + +## Debug Mode + +When _mimalloc_ is built using debug mode, various checks are done at runtime to catch development errors. + +- Statistics are maintained in detail for each object size. They can be shown using `MIMALLOC_SHOW_STATS=1` at runtime. +- All objects have padding at the end to detect (byte precise) heap block overflows. +- Double free's, and freeing invalid heap pointers are detected. +- Corrupted free-lists and some forms of use-after-free are detected. + + +# Overriding Standard Malloc + +Overriding the standard `malloc` (and `new`) can be done either _dynamically_ or _statically_. + +## Dynamic override + +This is the recommended way to override the standard malloc interface. + +### Dynamic Override on Linux, BSD + +On these ELF-based systems we preload the mimalloc shared +library so all calls to the standard `malloc` interface are +resolved to the _mimalloc_ library. +``` +> env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram +``` + +You can set extra environment variables to check that mimalloc is running, +like: +``` +> env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram +``` +or run with the debug version to get detailed statistics: +``` +> env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram +``` + +### Dynamic Override on MacOS + +On macOS we can also preload the mimalloc shared +library so all calls to the standard `malloc` interface are +resolved to the _mimalloc_ library. +``` +> env DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram +``` + +Note that certain security restrictions may apply when doing this from +the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash). + + +### Dynamic Override on Windows + +<span id="override_on_windows">Overriding on Windows</span> is robust and has the +particular advantage to be able to redirect all malloc/free calls that go through +the (dynamic) C runtime allocator, including those from other DLL's or libraries. + +The overriding on Windows requires that you link your program explicitly with +the mimalloc DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch). +Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be put +in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency). +The redirection DLL ensures that all calls to the C runtime malloc API get redirected to +mimalloc (in `mimalloc-override.dll`). + +To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some +call to the mimalloc API in the `main` function, like `mi_version()` +(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project +for an example on how to use this. For best performance on Windows with C++, it +is also recommended to also override the `new`/`delete` operations (by including +[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) a single(!) source file in your project). + +The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic +overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc was successfully redirected. + +(Note: in principle, it is possible to even patch existing executables without any recompilation +if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `mimalloc-override.dll` +into the import table (and put `mimalloc-redirect.dll` in the same folder) +Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388)). + + +## Static override + +On Unix-like systems, you can also statically link with _mimalloc_ to override the standard +malloc interface. The recommended way is to link the final program with the +_mimalloc_ single object file (`mimalloc.o`). We use +an object file instead of a library file as linkers give preference to +that over archives to resolve symbols. To ensure that the standard +malloc interface resolves to the _mimalloc_ library, link it as the first +object file. For example: +``` +> gcc -o myprogram mimalloc.o myfile1.c ... +``` + +Another way to override statically that works on all platforms, is to +link statically to mimalloc (as shown in the introduction) and include a +header file in each source file that re-defines `malloc` etc. to `mi_malloc`. +This is provided by [`mimalloc-override.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-override.h). This only works reliably though if all sources are +under your control or otherwise mixing of pointers from different heaps may occur! + + +## Tools + +Generally, we recommend using the standard allocator with memory tracking tools, but mimalloc +can also be build to support the [address sanitizer][asan] or the excellent [Valgrind] tool. +Moreover, it can be build to support Windows event tracing ([ETW]). +This has a small performance overhead but does allow detecting memory leaks and byte-precise +buffer overflows directly on final executables. See also the `test/test-wrong.c` file to test with various tools. + +### Valgrind + +To build with [valgrind] support, use the `MI_TRACK_VALGRIND=ON` cmake option: + +``` +> cmake ../.. -DMI_TRACK_VALGRIND=ON +``` + +This can also be combined with secure mode or debug mode. +You can then run your programs directly under valgrind: + +``` +> valgrind <myprogram> +``` + +If you rely on overriding `malloc`/`free` by mimalloc (instead of using the `mi_malloc`/`mi_free` API directly), +you also need to tell `valgrind` to not intercept those calls itself, and use: + +``` +> MIMALLOC_SHOW_STATS=1 valgrind --soname-synonyms=somalloc=*mimalloc* -- <myprogram> +``` + +By setting the `MIMALLOC_SHOW_STATS` environment variable you can check that mimalloc is indeed +used and not the standard allocator. Even though the [Valgrind option][valgrind-soname] +is called `--soname-synonyms`, this also +works when overriding with a static library or object file. Unfortunately, it is not possible to +dynamically override mimalloc using `LD_PRELOAD` together with `valgrind`. +See also the `test/test-wrong.c` file to test with `valgrind`. + +Valgrind support is in its initial development -- please report any issues. + +[Valgrind]: https://valgrind.org/ +[valgrind-soname]: https://valgrind.org/docs/manual/manual-core.html#opt.soname-synonyms + +### ASAN + +To build with the address sanitizer, use the `-DMI_TRACK_ASAN=ON` cmake option: + +``` +> cmake ../.. -DMI_TRACK_ASAN=ON +``` + +This can also be combined with secure mode or debug mode. +You can then run your programs as:' + +``` +> ASAN_OPTIONS=verbosity=1 <myprogram> +``` + +When you link a program with an address sanitizer build of mimalloc, you should +generally compile that program too with the address sanitizer enabled. +For example, assuming you build mimalloc in `out/debug`: + +``` +clang -g -o test-wrong -Iinclude test/test-wrong.c out/debug/libmimalloc-asan-debug.a -lpthread -fsanitize=address -fsanitize-recover=address +``` + +Since the address sanitizer redirects the standard allocation functions, on some platforms (macOSX for example) +it is required to compile mimalloc with `-DMI_OVERRIDE=OFF`. +Adress sanitizer support is in its initial development -- please report any issues. + +[asan]: https://github.com/google/sanitizers/wiki/AddressSanitizer + +### ETW + +Event tracing for Windows ([ETW]) provides a high performance way to capture all allocations though +mimalloc and analyze them later. To build with ETW support, use the `-DMI_TRACK_ETW=ON` cmake option. + +You can then capture an allocation trace using the Windows performance recorder (WPR), using the +`src/prim/windows/etw-mimalloc.wprp` profile. In an admin prompt, you can use: +``` +> wpr -start src\prim\windows\etw-mimalloc.wprp -filemode +> <my_mimalloc_program> +> wpr -stop <my_mimalloc_program>.etl +``` +and then open `<my_mimalloc_program>.etl` in the Windows Performance Analyzer (WPA), or +use a tool like [TraceControl] that is specialized for analyzing mimalloc traces. + +[ETW]: https://learn.microsoft.com/en-us/windows-hardware/test/wpt/event-tracing-for-windows +[TraceControl]: https://github.com/xinglonghe/TraceControl + + +# Performance + +Last update: 2021-01-30 + +We tested _mimalloc_ against many other top allocators over a wide +range of benchmarks, ranging from various real world programs to +synthetic benchmarks that see how the allocator behaves under more +extreme circumstances. In our benchmark suite, _mimalloc_ outperforms other leading +allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), and has a similar memory footprint. A nice property is that it +does consistently well over the wide range of benchmarks. + +General memory allocators are interesting as there exists no algorithm that is +optimal -- for a given allocator one can usually construct a workload +where it does not do so well. The goal is thus to find an allocation +strategy that performs well over a wide range of benchmarks without +suffering from (too much) underperformance in less common situations. + +As always, interpret these results with care since some benchmarks test synthetic +or uncommon situations that may never apply to your workloads. For example, most +allocators do not do well on `xmalloc-testN` but that includes even the best +industrial allocators like _jemalloc_ and _tcmalloc_ that are used in some of +the world's largest systems (like Chrome or FreeBSD). + +Also, the benchmarks here do not measure the behaviour on very large and long-running server workloads, +or worst-case latencies of allocation. Much work has gone into `mimalloc` to work well on such +workloads (for example, to reduce virtual memory fragmentation on long-running services) +but such optimizations are not always reflected in the current benchmark suite. + +We show here only an overview -- for +more specific details and further benchmarks we refer to the +[technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action). +The benchmark suite is automated and available separately +as [mimalloc-bench](https://github.com/daanx/mimalloc-bench). + + +## Benchmark Results on a 16-core AMD 5950x (Zen3) + +Testing on the 16-core AMD 5950x processor at 3.4Ghz (4.9Ghz boost), with +with 32GiB memory at 3600Mhz, running Ubuntu 20.04 with glibc 2.31 and GCC 9.3.0. + +We measure three versions of _mimalloc_: the main version `mi` (tag:v1.7.0), +the new v2.0 beta version as `xmi` (tag:v2.0.0), and the main version in secure mode as `smi` (tag:v1.7.0). + +The other allocators are +Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (`tc`, tag:gperftools-2.8.1) used in Chrome, +Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (`je`, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD, +the Intel thread building blocks [allocator](https://github.com/intel/tbb) (`tbb`, tag:v2020.3), +[rpmalloc](https://github.com/mjansson/rpmalloc) (`rp`,tag:1.4.1) by Mattias Jansson, +the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (git:d880f72) allocator by Emery Berger \[1], +the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:67ff31a) allocator by +Bobby Powers _et al_ \[8], +and finally the default system allocator (`glibc`, 2.31) (based on _PtMalloc2_). + +<img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-a.svg"/> +<img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-b.svg"/> + +Any benchmarks ending in `N` run on all 32 logical cores in parallel. +Results are averaged over 10 runs and reported relative +to mimalloc (where 1.2 means it took 1.2× longer to run). +The legend also contains the _overall relative score_ between the +allocators where 100 points is the maximum if an allocator is fastest on +all benchmarks. + +The single threaded _cfrac_ benchmark by Dave Barrett is an implementation of +continued fraction factorization which uses many small short-lived allocations. +All allocators do well on such common usage, where _mimalloc_ is just a tad +faster than _tcmalloc_ and +_jemalloc_. + +The _leanN_ program is interesting as a large realistic and +concurrent workload of the [Lean](https://github.com/leanprover/lean) +theorem prover compiling its own standard library, and there is a 13% +speedup over _tcmalloc_. This is +quite significant: if Lean spends 20% of its time in the +allocator that means that _mimalloc_ is 1.6× faster than _tcmalloc_ +here. (This is surprising as that is not measured in a pure +allocation benchmark like _alloc-test_. We conjecture that we see this +outsized improvement here because _mimalloc_ has better locality in +the allocation which improves performance for the *other* computations +in a program as well). + +The single threaded _redis_ benchmark again show that most allocators do well on such workloads. + +The _larsonN_ server benchmark by Larson and Krishnan \[2] allocates and frees between threads. They observed this +behavior (which they call _bleeding_) in actual server applications, and the benchmark simulates this. +Here, _mimalloc_ is quite a bit faster than _tcmalloc_ and _jemalloc_ probably due to the object migration between different threads. + +The _mstressN_ workload performs many allocations and re-allocations, +and migrates objects between threads (as in _larsonN_). However, it also +creates and destroys the _N_ worker threads a few times keeping some objects +alive beyond the life time of the allocating thread. We observed this +behavior in many larger server applications. + +The [_rptestN_](https://github.com/mjansson/rpmalloc-benchmark) benchmark +by Mattias Jansson is a allocator test originally designed +for _rpmalloc_, and tries to simulate realistic allocation patterns over +multiple threads. Here the differences between allocators become more apparent. + +The second benchmark set tests specific aspects of the allocators and +shows even more extreme differences between them. + +The _alloc-test_, by +[OLogN Technologies AG](http://ithare.com/testing-memory-allocators-ptmalloc2-tcmalloc-hoard-jemalloc-while-trying-to-simulate-real-world-loads/), is a very allocation intensive benchmark doing millions of +allocations in various size classes. The test is scaled such that when an +allocator performs almost identically on _alloc-test1_ as _alloc-testN_ it +means that it scales linearly. + +The _sh6bench_ and _sh8bench_ benchmarks are +developed by [MicroQuill](http://www.microquill.com/) as part of SmartHeap. +In _sh6bench_ _mimalloc_ does much +better than the others (more than 2.5× faster than _jemalloc_). +We cannot explain this well but believe it is +caused in part by the "reverse" free-ing pattern in _sh6bench_. +The _sh8bench_ is a variation with object migration +between threads; whereas _tcmalloc_ did well on _sh6bench_, the addition of object migration causes it to be 10× slower than before. + +The _xmalloc-testN_ benchmark by Lever and Boreham \[5] and Christian Eder, simulates an asymmetric workload where +some threads only allocate, and others only free -- they observed this pattern in +larger server applications. Here we see that +the _mimalloc_ technique of having non-contended sharded thread free +lists pays off as it outperforms others by a very large margin. Only _rpmalloc_, _tbb_, and _glibc_ also scale well on this benchmark. + +The _cache-scratch_ benchmark by Emery Berger \[1], and introduced with +the Hoard allocator to test for _passive-false_ sharing of cache lines. +With a single thread they all +perform the same, but when running with multiple threads the potential allocator +induced false sharing of the cache lines can cause large run-time differences. +Crundal \[6] describes in detail why the false cache line sharing occurs in the _tcmalloc_ design, and also discusses how this +can be avoided with some small implementation changes. +Only the _tbb_, _rpmalloc_ and _mesh_ allocators also avoid the +cache line sharing completely, while _Hoard_ and _glibc_ seem to mitigate +the effects. Kukanov and Voss \[7] describe in detail +how the design of _tbb_ avoids the false cache line sharing. + + +## On a 36-core Intel Xeon + +For completeness, here are the results on a big Amazon +[c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized) instance +consisting of a 2×18-core Intel Xeon (Cascade Lake) at 3.4GHz (boost 3.5GHz) +with 144GiB ECC memory, running Ubuntu 20.04 with glibc 2.31, GCC 9.3.0, and +Clang 10.0.0. This time, the mimalloc allocators (mi, xmi, and smi) were +compiled with the Clang compiler instead of GCC. +The results are similar to the AMD results but it is interesting to +see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks. + +<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg"/> +<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg"/> + + +## Peak Working Set + +The following figure shows the peak working set (rss) of the allocators +on the benchmarks (on the c5.18xlarge instance). + +<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg"/> +<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg"/> + +Note that the _xmalloc-testN_ memory usage should be disregarded as it +allocates more the faster the program runs. Similarly, memory usage of +_larsonN_, _mstressN_, _rptestN_ and _sh8bench_ can vary depending on scheduling and +speed. Nevertheless, we hope to improve the memory usage on _mstressN_ +and _rptestN_ (just as _cfrac_, _larsonN_ and _sh8bench_ have a small working set which skews the results). + +<!-- +# Previous Benchmarks + +Todo: should we create a separate page for this? + +## Benchmark Results on 36-core Intel: 2020-01-20 + +Testing on a big Amazon EC2 compute instance +([c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized)) +consisting of a 72 processor Intel Xeon at 3GHz +with 144GiB ECC memory, running Ubuntu 18.04.1 with glibc 2.27 and GCC 7.4.0. +The measured allocators are _mimalloc_ (xmi, tag:v1.4.0, page reset enabled) +and its secure build as _smi_, +Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (tc, tag:gperftools-2.7) used in Chrome, +Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (je, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD, +the Intel thread building blocks [allocator](https://github.com/intel/tbb) (tbb, tag:2020), +[rpmalloc](https://github.com/mjansson/rpmalloc) (rp,tag:1.4.0) by Mattias Jansson, +the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (tag:3.13) allocator by Emery Berger \[1], +the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:51222e7) allocator by +Bobby Powers _et al_ \[8], +and finally the default system allocator (glibc, 2.27) (based on _PtMalloc2_). + +<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg"/> +<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg"/> + +The following figure shows the peak working set (rss) of the allocators +on the benchmarks (on the c5.18xlarge instance). + +<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg"/> +<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg"/> + + +## On 24-core AMD Epyc, 2020-01-16 + +For completeness, here are the results on a +[r5a.12xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance +having a 48 processor AMD Epyc 7000 at 2.5GHz with 384GiB of memory. +The results are similar to the Intel results but it is interesting to +see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks. + +<img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg"/> +<img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg"/> + +--> + + +# References + +- \[1] Emery D. Berger, Kathryn S. McKinley, Robert D. Blumofe, and Paul R. Wilson. + _Hoard: A Scalable Memory Allocator for Multithreaded Applications_ + the Ninth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS-IX). Cambridge, MA, November 2000. + [pdf](http://www.cs.utexas.edu/users/mckinley/papers/asplos-2000.pdf) + +- \[2] P. Larson and M. Krishnan. _Memory allocation for long-running server applications_. + In ISMM, Vancouver, B.C., Canada, 1998. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1947&rep=rep1&type=pdf) + +- \[3] D. Grunwald, B. Zorn, and R. Henderson. + _Improving the cache locality of memory allocation_. In R. Cartwright, editor, + Proceedings of the Conference on Programming Language Design and Implementation, pages 177–186, New York, NY, USA, June 1993. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.43.6621&rep=rep1&type=pdf) + +- \[4] J. Barnes and P. Hut. _A hierarchical O(n*log(n)) force-calculation algorithm_. Nature, 324:446-449, 1986. + +- \[5] C. Lever, and D. Boreham. _Malloc() Performance in a Multithreaded Linux Environment._ + In USENIX Annual Technical Conference, Freenix Session. San Diego, CA. Jun. 2000. + Available at <https://github.com/kuszmaul/SuperMalloc/tree/master/tests> + +- \[6] Timothy Crundal. _Reducing Active-False Sharing in TCMalloc_. 2016. CS16S1 project at the Australian National University. [pdf](http://courses.cecs.anu.edu.au/courses/CSPROJECTS/16S1/Reports/Timothy_Crundal_Report.pdf) + +- \[7] Alexey Kukanov, and Michael J Voss. + _The Foundations for Scalable Multi-Core Software in Intel Threading Building Blocks._ + Intel Technology Journal 11 (4). 2007 + +- \[8] Bobby Powers, David Tench, Emery D. Berger, and Andrew McGregor. + _Mesh: Compacting Memory Management for C/C++_ + In Proceedings of the 40th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI'19), June 2019, pages 333-–346. + +<!-- +- \[9] Paul Liétar, Theodore Butler, Sylvan Clebsch, Sophia Drossopoulou, Juliana Franco, Matthew J Parkinson, + Alex Shamis, Christoph M Wintersteiger, and David Chisnall. + _Snmalloc: A Message Passing Allocator._ + In Proceedings of the 2019 ACM SIGPLAN International Symposium on Memory Management, 122–135. ACM. 2019. +--> + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + + +# Older Release Notes + +* 2021-11-14, `v1.7.3`, `v2.0.3` (beta): improved WASM support, improved macOS support and performance (including + M1), improved performance for v2 for large objects, Python integration improvements, more standard + installation directories, various small fixes. +* 2021-06-17, `v1.7.2`, `v2.0.2` (beta): support M1, better installation layout on Linux, fix + thread_id on Android, prefer 2-6TiB area for aligned allocation to work better on pre-windows 8, various small fixes. +* 2021-04-06, `v1.7.1`, `v2.0.1` (beta): fix bug in arena allocation for huge pages, improved aslr on large allocations, initial M1 support (still experimental). +* 2021-01-31, `v2.0.0`: beta release 2.0: new slice algorithm for managing internal mimalloc pages. +* 2021-01-31, `v1.7.0`: stable release 1.7: support explicit user provided memory regions, more precise statistics, + improve macOS overriding, initial support for Apple M1, improved DragonFly support, faster memcpy on Windows, various small fixes. + +* 2020-09-24, `v1.6.7`: stable release 1.6: using standard C atomics, passing tsan testing, improved + handling of failing to commit on Windows, add [`mi_process_info`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc.h#L156) api call. +* 2020-08-06, `v1.6.4`: stable release 1.6: improved error recovery in low-memory situations, + support for IllumOS and Haiku, NUMA support for Vista/XP, improved NUMA detection for AMD Ryzen, ubsan support. +* 2020-05-05, `v1.6.3`: stable release 1.6: improved behavior in out-of-memory situations, improved malloc zones on macOS, + build PIC static libraries by default, add option to abort on out-of-memory, line buffered statistics. +* 2020-04-20, `v1.6.2`: stable release 1.6: fix compilation on Android, MingW, Raspberry, and Conda, + stability fix for Windows 7, fix multiple mimalloc instances in one executable, fix `strnlen` overload, + fix aligned debug padding. +* 2020-02-17, `v1.6.1`: stable release 1.6: minor updates (build with clang-cl, fix alignment issue for small objects). +* 2020-02-09, `v1.6.0`: stable release 1.6: fixed potential memory leak, improved overriding + and thread local support on FreeBSD, NetBSD, DragonFly, and macOSX. New byte-precise + heap block overflow detection in debug mode (besides the double-free detection and free-list + corruption detection). Add `nodiscard` attribute to most allocation functions. + Enable `MIMALLOC_PAGE_RESET` by default. New reclamation strategy for abandoned heap pages + for better memory footprint. +* 2020-02-09, `v1.5.0`: stable release 1.5: improved free performance, small bug fixes. +* 2020-01-22, `v1.4.0`: stable release 1.4: improved performance for delayed OS page reset, +more eager concurrent free, addition of STL allocator, fixed potential memory leak. +* 2020-01-15, `v1.3.0`: stable release 1.3: bug fixes, improved randomness and [stronger +free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) in secure mode. + +* 2019-12-22, `v1.2.2`: stable release 1.2: minor updates. +* 2019-11-22, `v1.2.0`: stable release 1.2: bug fixes, improved secure mode (free list corruption checks, double free mitigation). Improved dynamic overriding on Windows. +* 2019-10-07, `v1.1.0`: stable release 1.1. +* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support. +* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements. diff --git a/lib/Utils.Memory/mimalloc/src/alloc-aligned.c b/lib/Utils.Memory/mimalloc/src/alloc-aligned.c new file mode 100644 index 0000000..1cd809f --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/alloc-aligned.c @@ -0,0 +1,298 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/prim.h" // mi_prim_get_default_heap + +#include <string.h> // memset + +// ------------------------------------------------------ +// Aligned Allocation +// ------------------------------------------------------ + +// Fallback primitive aligned allocation -- split out for better codegen +static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept +{ + mi_assert_internal(size <= PTRDIFF_MAX); + mi_assert_internal(alignment != 0 && _mi_is_power_of_two(alignment)); + + const uintptr_t align_mask = alignment - 1; // for any x, `(x & align_mask) == (x % alignment)` + const size_t padsize = size + MI_PADDING_SIZE; + + // use regular allocation if it is guaranteed to fit the alignment constraints + if (offset==0 && alignment<=padsize && padsize<=MI_MAX_ALIGN_GUARANTEE && (padsize&align_mask)==0) { + void* p = _mi_heap_malloc_zero(heap, size, zero); + mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0); + return p; + } + + void* p; + size_t oversize; + if mi_unlikely(alignment > MI_ALIGNMENT_MAX) { + // use OS allocation for very large alignment and allocate inside a huge page (dedicated segment with 1 page) + // This can support alignments >= MI_SEGMENT_SIZE by ensuring the object can be aligned at a point in the + // first (and single) page such that the segment info is `MI_SEGMENT_SIZE` bytes before it (so it can be found by aligning the pointer down) + if mi_unlikely(offset != 0) { + // todo: cannot support offset alignment for very large alignments yet + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "aligned allocation with a very large alignment cannot be used with an alignment offset (size %zu, alignment %zu, offset %zu)\n", size, alignment, offset); + #endif + return NULL; + } + oversize = (size <= MI_SMALL_SIZE_MAX ? MI_SMALL_SIZE_MAX + 1 /* ensure we use generic malloc path */ : size); + p = _mi_heap_malloc_zero_ex(heap, oversize, false, alignment); // the page block size should be large enough to align in the single huge page block + // zero afterwards as only the area from the aligned_p may be committed! + if (p == NULL) return NULL; + } + else { + // otherwise over-allocate + oversize = size + alignment - 1; + p = _mi_heap_malloc_zero(heap, oversize, zero); + if (p == NULL) return NULL; + } + + // .. and align within the allocation + const uintptr_t poffset = ((uintptr_t)p + offset) & align_mask; + const uintptr_t adjust = (poffset == 0 ? 0 : alignment - poffset); + mi_assert_internal(adjust < alignment); + void* aligned_p = (void*)((uintptr_t)p + adjust); + if (aligned_p != p) { + mi_page_t* page = _mi_ptr_page(p); + mi_page_set_has_aligned(page, true); + _mi_padding_shrink(page, (mi_block_t*)p, adjust + size); + } + // todo: expand padding if overallocated ? + + mi_assert_internal(mi_page_usable_block_size(_mi_ptr_page(p)) >= adjust + size); + mi_assert_internal(p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p), _mi_ptr_page(aligned_p), aligned_p)); + mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0); + mi_assert_internal(mi_usable_size(aligned_p)>=size); + mi_assert_internal(mi_usable_size(p) == mi_usable_size(aligned_p)+adjust); + + // now zero the block if needed + if (alignment > MI_ALIGNMENT_MAX) { + // for the tracker, on huge aligned allocations only from the start of the large block is defined + mi_track_mem_undefined(aligned_p, size); + if (zero) { + _mi_memzero_aligned(aligned_p, mi_usable_size(aligned_p)); + } + } + + if (p != aligned_p) { + mi_track_align(p,aligned_p,adjust,mi_usable_size(aligned_p)); + } + return aligned_p; +} + +// Primitive aligned allocation +static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept +{ + // note: we don't require `size > offset`, we just guarantee that the address at offset is aligned regardless of the allocated size. + if mi_unlikely(alignment == 0 || !_mi_is_power_of_two(alignment)) { // require power-of-two (see <https://en.cppreference.com/w/c/memory/aligned_alloc>) + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "aligned allocation requires the alignment to be a power-of-two (size %zu, alignment %zu)\n", size, alignment); + #endif + return NULL; + } + + if mi_unlikely(size > PTRDIFF_MAX) { // we don't allocate more than PTRDIFF_MAX (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>) + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "aligned allocation request is too large (size %zu, alignment %zu)\n", size, alignment); + #endif + return NULL; + } + const uintptr_t align_mask = alignment-1; // for any x, `(x & align_mask) == (x % alignment)` + const size_t padsize = size + MI_PADDING_SIZE; // note: cannot overflow due to earlier size > PTRDIFF_MAX check + + // try first if there happens to be a small block available with just the right alignment + if mi_likely(padsize <= MI_SMALL_SIZE_MAX && alignment <= padsize) { + mi_page_t* page = _mi_heap_get_free_small_page(heap, padsize); + const bool is_aligned = (((uintptr_t)page->free+offset) & align_mask)==0; + if mi_likely(page->free != NULL && is_aligned) + { + #if MI_STAT>1 + mi_heap_stat_increase(heap, malloc, size); + #endif + void* p = _mi_page_malloc(heap, page, padsize, zero); // TODO: inline _mi_page_malloc + mi_assert_internal(p != NULL); + mi_assert_internal(((uintptr_t)p + offset) % alignment == 0); + mi_track_malloc(p,size,zero); + return p; + } + } + // fallback + return mi_heap_malloc_zero_aligned_at_fallback(heap, size, alignment, offset, zero); +} + + +// ------------------------------------------------------ +// Optimized mi_heap_malloc_aligned / mi_malloc_aligned +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { + if mi_unlikely(alignment == 0 || !_mi_is_power_of_two(alignment)) return NULL; + #if !MI_PADDING + // without padding, any small sized allocation is naturally aligned (see also `_mi_segment_page_start`) + if mi_likely(_mi_is_power_of_two(size) && size >= alignment && size <= MI_SMALL_SIZE_MAX) + #else + // with padding, we can only guarantee this for fixed alignments + if mi_likely((alignment == sizeof(void*) || (alignment == MI_MAX_ALIGN_SIZE && size > (MI_MAX_ALIGN_SIZE/2))) + && size <= MI_SMALL_SIZE_MAX) + #endif + { + // fast path for common alignment and size + return mi_heap_malloc_small(heap, size); + } + else { + return mi_heap_malloc_aligned_at(heap, size, alignment, 0); + } +} + +// ensure a definition is emitted +#if defined(__cplusplus) +static void* _mi_heap_malloc_aligned = (void*)&mi_heap_malloc_aligned; +#endif + +// ------------------------------------------------------ +// Aligned Allocation +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_zalloc_aligned_at(heap, size, alignment, 0); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_zalloc_aligned_at(heap, total, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_calloc_aligned_at(heap,count,size,alignment,0); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_aligned_at(mi_prim_get_default_heap(), size, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_malloc_aligned(mi_prim_get_default_heap(), size, alignment); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_zalloc_aligned_at(mi_prim_get_default_heap(), size, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_zalloc_aligned(mi_prim_get_default_heap(), size, alignment); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_calloc_aligned_at(mi_prim_get_default_heap(), count, size, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_calloc_aligned(mi_prim_get_default_heap(), count, size, alignment); +} + + +// ------------------------------------------------------ +// Aligned re-allocation +// ------------------------------------------------------ + +static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept { + mi_assert(alignment > 0); + if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); + if (p == NULL) return mi_heap_malloc_zero_aligned_at(heap,newsize,alignment,offset,zero); + size_t size = mi_usable_size(p); + if (newsize <= size && newsize >= (size - (size / 2)) + && (((uintptr_t)p + offset) % alignment) == 0) { + return p; // reallocation still fits, is aligned and not more than 50% waste + } + else { + // note: we don't zero allocate upfront so we only zero initialize the expanded part + void* newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset); + if (newp != NULL) { + if (zero && newsize > size) { + // also set last word in the previous allocation to zero to ensure any padding is zero-initialized + size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); + _mi_memzero((uint8_t*)newp + start, newsize - start); + } + _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + mi_free(p); // only free if successful + } + return newp; + } +} + +static void* mi_heap_realloc_zero_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept { + mi_assert(alignment > 0); + if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); + size_t offset = ((uintptr_t)p % alignment); // use offset of previous allocation (p can be NULL) + return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,zero); +} + +mi_decl_nodiscard void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,false); +} + +mi_decl_nodiscard void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned(heap,p,newsize,alignment,false); +} + +mi_decl_nodiscard void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned_at(heap, p, newsize, alignment, offset, true); +} + +mi_decl_nodiscard void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned(heap, p, newsize, alignment, true); +} + +mi_decl_nodiscard void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(newcount, size, &total)) return NULL; + return mi_heap_rezalloc_aligned_at(heap, p, total, alignment, offset); +} + +mi_decl_nodiscard void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(newcount, size, &total)) return NULL; + return mi_heap_rezalloc_aligned(heap, p, total, alignment); +} + +mi_decl_nodiscard void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_aligned_at(mi_prim_get_default_heap(), p, newsize, alignment, offset); +} + +mi_decl_nodiscard void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_aligned(mi_prim_get_default_heap(), p, newsize, alignment); +} + +mi_decl_nodiscard void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_rezalloc_aligned_at(mi_prim_get_default_heap(), p, newsize, alignment, offset); +} + +mi_decl_nodiscard void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_rezalloc_aligned(mi_prim_get_default_heap(), p, newsize, alignment); +} + +mi_decl_nodiscard void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_recalloc_aligned_at(mi_prim_get_default_heap(), p, newcount, size, alignment, offset); +} + +mi_decl_nodiscard void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_recalloc_aligned(mi_prim_get_default_heap(), p, newcount, size, alignment); +} diff --git a/lib/Utils.Memory/mimalloc/src/alloc-override.c b/lib/Utils.Memory/mimalloc/src/alloc-override.c new file mode 100644 index 0000000..873065d --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/alloc-override.c @@ -0,0 +1,297 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#if !defined(MI_IN_ALLOC_C) +#error "this file should be included from 'alloc.c' (so aliases can work)" +#endif + +#if defined(MI_MALLOC_OVERRIDE) && defined(_WIN32) && !(defined(MI_SHARED_LIB) && defined(_DLL)) +#error "It is only possible to override "malloc" on Windows when building as a DLL (and linking the C runtime as a DLL)" +#endif + +#if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) + +#if defined(__APPLE__) +#include <AvailabilityMacros.h> +mi_decl_externc void vfree(void* p); +mi_decl_externc size_t malloc_size(const void* p); +mi_decl_externc size_t malloc_good_size(size_t size); +#endif + +// helper definition for C override of C++ new +typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; + +// ------------------------------------------------------ +// Override system malloc +// ------------------------------------------------------ + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) && !MI_TRACK_ENABLED + // gcc, clang: use aliasing to alias the exported function to one of our `mi_` functions + #if (defined(__GNUC__) && __GNUC__ >= 9) + #pragma GCC diagnostic ignored "-Wattributes" // or we get warnings that nodiscard is ignored on a forward + #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun))); + #else + #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"))); + #endif + #define MI_FORWARD1(fun,x) MI_FORWARD(fun) + #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun) + #define MI_FORWARD3(fun,x,y,z) MI_FORWARD(fun) + #define MI_FORWARD0(fun,x) MI_FORWARD(fun) + #define MI_FORWARD02(fun,x,y) MI_FORWARD(fun) +#else + // otherwise use forwarding by calling our `mi_` function + #define MI_FORWARD1(fun,x) { return fun(x); } + #define MI_FORWARD2(fun,x,y) { return fun(x,y); } + #define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); } + #define MI_FORWARD0(fun,x) { fun(x); } + #define MI_FORWARD02(fun,x,y) { fun(x,y); } +#endif + + +#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_OSX_INTERPOSE) + // define MI_OSX_IS_INTERPOSED as we should not provide forwarding definitions for + // functions that are interposed (or the interposing does not work) + #define MI_OSX_IS_INTERPOSED + + mi_decl_externc size_t mi_malloc_size_checked(void *p) { + if (!mi_is_in_heap_region(p)) return 0; + return mi_usable_size(p); + } + + // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` + // See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73> + struct mi_interpose_s { + const void* replacement; + const void* target; + }; + #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } + #define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) + + __attribute__((used)) static struct mi_interpose_s _mi_interposes[] __attribute__((section("__DATA, __interpose"))) = + { + MI_INTERPOSE_MI(malloc), + MI_INTERPOSE_MI(calloc), + MI_INTERPOSE_MI(realloc), + MI_INTERPOSE_MI(strdup), + MI_INTERPOSE_MI(strndup), + MI_INTERPOSE_MI(realpath), + MI_INTERPOSE_MI(posix_memalign), + MI_INTERPOSE_MI(reallocf), + MI_INTERPOSE_MI(valloc), + MI_INTERPOSE_FUN(malloc_size,mi_malloc_size_checked), + MI_INTERPOSE_MI(malloc_good_size), + #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + MI_INTERPOSE_MI(aligned_alloc), + #endif + #ifdef MI_OSX_ZONE + // we interpose malloc_default_zone in alloc-override-osx.c so we can use mi_free safely + MI_INTERPOSE_MI(free), + MI_INTERPOSE_FUN(vfree,mi_free), + #else + // sometimes code allocates from default zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>) + MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us + MI_INTERPOSE_FUN(vfree,mi_cfree), + #endif + }; + + #ifdef __cplusplus + extern "C" { + #endif + void _ZdlPv(void* p); // delete + void _ZdaPv(void* p); // delete[] + void _ZdlPvm(void* p, size_t n); // delete + void _ZdaPvm(void* p, size_t n); // delete[] + void* _Znwm(size_t n); // new + void* _Znam(size_t n); // new[] + void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow + void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow + #ifdef __cplusplus + } + #endif + __attribute__((used)) static struct mi_interpose_s _mi_cxx_interposes[] __attribute__((section("__DATA, __interpose"))) = + { + MI_INTERPOSE_FUN(_ZdlPv,mi_free), + MI_INTERPOSE_FUN(_ZdaPv,mi_free), + MI_INTERPOSE_FUN(_ZdlPvm,mi_free_size), + MI_INTERPOSE_FUN(_ZdaPvm,mi_free_size), + MI_INTERPOSE_FUN(_Znwm,mi_new), + MI_INTERPOSE_FUN(_Znam,mi_new), + MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow), + MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow), + }; + +#elif defined(_MSC_VER) + // cannot override malloc unless using a dll. + // we just override new/delete which does work in a static library. +#else + // On all other systems forward to our API + mi_decl_export void* malloc(size_t size) MI_FORWARD1(mi_malloc, size) + mi_decl_export void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n) + mi_decl_export void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize) + mi_decl_export void free(void* p) MI_FORWARD0(mi_free, p) +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) +#pragma GCC visibility push(default) +#endif + +// ------------------------------------------------------ +// Override new/delete +// This is not really necessary as they usually call +// malloc/free anyway, but it improves performance. +// ------------------------------------------------------ +#ifdef __cplusplus + // ------------------------------------------------------ + // With a C++ compiler we override the new/delete operators. + // see <https://en.cppreference.com/w/cpp/memory/new/operator_new> + // ------------------------------------------------------ + #include <new> + + #ifndef MI_OSX_IS_INTERPOSED + void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p) + void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p) + + void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n) + void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n) + + void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n) + void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n) + #endif + #endif + + #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); }; + void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); } + + void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); } + void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); } + #endif + +#elif (defined(__GNUC__) || defined(__clang__)) + // ------------------------------------------------------ + // Override by defining the mangled C++ names of the operators (as + // used by GCC and CLang). + // See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling> + // ------------------------------------------------------ + + void _ZdlPv(void* p) MI_FORWARD0(mi_free,p) // delete + void _ZdaPv(void* p) MI_FORWARD0(mi_free,p) // delete[] + void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n) + void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n) + void _ZdlPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } + void _ZdaPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } + void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } + void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } + + #if (MI_INTPTR_SIZE==8) + void* _Znwm(size_t n) MI_FORWARD1(mi_new,n) // new 64-bit + void* _Znam(size_t n) MI_FORWARD1(mi_new,n) // new[] 64-bit + void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + #elif (MI_INTPTR_SIZE==4) + void* _Znwj(size_t n) MI_FORWARD1(mi_new,n) // new 64-bit + void* _Znaj(size_t n) MI_FORWARD1(mi_new,n) // new[] 64-bit + void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + #else + #error "define overloads for new/delete for this platform (just for performance, can be skipped)" + #endif +#endif // __cplusplus + +// ------------------------------------------------------ +// Further Posix & Unix functions definitions +// ------------------------------------------------------ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MI_OSX_IS_INTERPOSED + // Forward Posix/Unix calls as well + void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize) + size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p) + #if !defined(__ANDROID__) && !defined(__FreeBSD__) + size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p) + #else + size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p) + #endif + + // No forwarding here due to aliasing/name mangling issues + void* valloc(size_t size) { return mi_valloc(size); } + void vfree(void* p) { mi_free(p); } + size_t malloc_good_size(size_t size) { return mi_malloc_good_size(size); } + int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); } + + // `aligned_alloc` is only available when __USE_ISOC11 is defined. + // Note: it seems __USE_ISOC11 is not defined in musl (and perhaps other libc's) so we only check + // for it if using glibc. + // Note: Conda has a custom glibc where `aligned_alloc` is declared `static inline` and we cannot + // override it, but both _ISOC11_SOURCE and __USE_ISOC11 are undefined in Conda GCC7 or GCC9. + // Fortunately, in the case where `aligned_alloc` is declared as `static inline` it + // uses internally `memalign`, `posix_memalign`, or `_aligned_malloc` so we can avoid overriding it ourselves. + #if !defined(__GLIBC__) || __USE_ISOC11 + void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } + #endif +#endif + +// no forwarding here due to aliasing/name mangling issues +void cfree(void* p) { mi_free(p); } +void* pvalloc(size_t size) { return mi_pvalloc(size); } +void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); } +int reallocarr(void* p, size_t count, size_t size) { return mi_reallocarr(p, count, size); } +void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } +void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } + +#if defined(__wasi__) + // forward __libc interface (see PR #667) + void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc, size) + void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc, count, size) + void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc, p, size) + void __libc_free(void* p) MI_FORWARD0(mi_free, p) + void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } + +#elif defined(__GLIBC__) && defined(__linux__) + // forward __libc interface (needed for glibc-based Linux distributions) + void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size) + void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size) + void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size) + void __libc_free(void* p) MI_FORWARD0(mi_free,p) + void __libc_cfree(void* p) MI_FORWARD0(mi_free,p) + + void* __libc_valloc(size_t size) { return mi_valloc(size); } + void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); } + void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); } + int __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); } +#endif + +#ifdef __cplusplus +} +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) +#pragma GCC visibility pop +#endif + +#endif // MI_MALLOC_OVERRIDE && !_WIN32 diff --git a/lib/Utils.Memory/mimalloc/src/alloc-posix.c b/lib/Utils.Memory/mimalloc/src/alloc-posix.c new file mode 100644 index 0000000..225752f --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/alloc-posix.c @@ -0,0 +1,185 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// ------------------------------------------------------------------------ +// mi prefixed publi definitions of various Posix, Unix, and C++ functions +// for convenience and used when overriding these functions. +// ------------------------------------------------------------------------ +#include "mimalloc.h" +#include "mimalloc/internal.h" + +// ------------------------------------------------------ +// Posix & Unix functions definitions +// ------------------------------------------------------ + +#include <errno.h> +#include <string.h> // memset +#include <stdlib.h> // getenv + +#ifdef _MSC_VER +#pragma warning(disable:4996) // getenv _wgetenv +#endif + +#ifndef EINVAL +#define EINVAL 22 +#endif +#ifndef ENOMEM +#define ENOMEM 12 +#endif + + +mi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept { + // if (!mi_is_in_heap_region(p)) return 0; + return mi_usable_size(p); +} + +mi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept { + // if (!mi_is_in_heap_region(p)) return 0; + return mi_usable_size(p); +} + +mi_decl_nodiscard size_t mi_malloc_good_size(size_t size) mi_attr_noexcept { + return mi_good_size(size); +} + +void mi_cfree(void* p) mi_attr_noexcept { + if (mi_is_in_heap_region(p)) { + mi_free(p); + } +} + +int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept { + // Note: The spec dictates we should not modify `*p` on an error. (issue#27) + // <http://man7.org/linux/man-pages/man3/posix_memalign.3.html> + if (p == NULL) return EINVAL; + if ((alignment % sizeof(void*)) != 0) return EINVAL; // natural alignment + // it is also required that alignment is a power of 2 and > 0; this is checked in `mi_malloc_aligned` + if (alignment==0 || !_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2 + void* q = mi_malloc_aligned(size, alignment); + if (q==NULL && size != 0) return ENOMEM; + mi_assert_internal(((uintptr_t)q % alignment) == 0); + *p = q; + return 0; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept { + void* p = mi_malloc_aligned(size, alignment); + mi_assert_internal(((uintptr_t)p % alignment) == 0); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept { + return mi_memalign( _mi_os_page_size(), size ); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept { + size_t psize = _mi_os_page_size(); + if (size >= SIZE_MAX - psize) return NULL; // overflow + size_t asize = _mi_align_up(size, psize); + return mi_malloc_aligned(asize, psize); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept { + // C11 requires the size to be an integral multiple of the alignment, see <https://en.cppreference.com/w/c/memory/aligned_alloc>. + // unfortunately, it turns out quite some programs pass a size that is not an integral multiple so skip this check.. + /* if mi_unlikely((size & (alignment - 1)) != 0) { // C11 requires alignment>0 && integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc> + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "(mi_)aligned_alloc requires the size to be an integral multiple of the alignment (size %zu, alignment %zu)\n", size, alignment); + #endif + return NULL; + } + */ + // C11 also requires alignment to be a power-of-two (and > 0) which is checked in mi_malloc_aligned + void* p = mi_malloc_aligned(size, alignment); + mi_assert_internal(((uintptr_t)p % alignment) == 0); + return p; +} + +mi_decl_nodiscard void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD + void* newp = mi_reallocn(p,count,size); + if (newp==NULL) { errno = ENOMEM; } + return newp; +} + +mi_decl_nodiscard int mi_reallocarr( void* p, size_t count, size_t size ) mi_attr_noexcept { // NetBSD + mi_assert(p != NULL); + if (p == NULL) { + errno = EINVAL; + return EINVAL; + } + void** op = (void**)p; + void* newp = mi_reallocarray(*op, count, size); + if mi_unlikely(newp == NULL) { return errno; } + *op = newp; + return 0; +} + +void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft + void* res = mi_expand(p, newsize); + if (res == NULL) { errno = ENOMEM; } + return res; +} + +mi_decl_nodiscard mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept { + if (s==NULL) return NULL; + size_t len; + for(len = 0; s[len] != 0; len++) { } + size_t size = (len+1)*sizeof(unsigned short); + unsigned short* p = (unsigned short*)mi_malloc(size); + if (p != NULL) { + _mi_memcpy(p,s,size); + } + return p; +} + +mi_decl_nodiscard mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept { + return (unsigned char*)mi_strdup((const char*)s); +} + +int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept { + if (buf==NULL || name==NULL) return EINVAL; + if (size != NULL) *size = 0; + char* p = getenv(name); // mscver warning 4996 + if (p==NULL) { + *buf = NULL; + } + else { + *buf = mi_strdup(p); + if (*buf==NULL) return ENOMEM; + if (size != NULL) *size = _mi_strlen(p); + } + return 0; +} + +int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept { + if (buf==NULL || name==NULL) return EINVAL; + if (size != NULL) *size = 0; +#if !defined(_WIN32) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)) + // not supported + *buf = NULL; + return EINVAL; +#else + unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name); // msvc warning 4996 + if (p==NULL) { + *buf = NULL; + } + else { + *buf = mi_wcsdup(p); + if (*buf==NULL) return ENOMEM; + if (size != NULL) *size = wcslen((const wchar_t*)p); + } + return 0; +#endif +} + +mi_decl_nodiscard void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft + return mi_recalloc_aligned_at(p, newcount, size, alignment, offset); +} + +mi_decl_nodiscard void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft + return mi_recalloc_aligned(p, newcount, size, alignment); +} diff --git a/lib/Utils.Memory/mimalloc/src/alloc.c b/lib/Utils.Memory/mimalloc/src/alloc.c new file mode 100644 index 0000000..ffc1747 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/alloc.c @@ -0,0 +1,1060 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2022, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE // for realpath() on Linux +#endif + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" // _mi_prim_thread_id() + +#include <string.h> // memset, strlen (for mi_strdup) +#include <stdlib.h> // malloc, abort + +#define MI_IN_ALLOC_C +#include "alloc-override.c" +#undef MI_IN_ALLOC_C + +// ------------------------------------------------------ +// Allocation +// ------------------------------------------------------ + +// Fast allocation in a page: just pop from the free list. +// Fall back to generic allocation only if the list is empty. +extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept { + mi_assert_internal(page->xblock_size==0||mi_page_block_size(page) >= size); + mi_block_t* const block = page->free; + if mi_unlikely(block == NULL) { + return _mi_malloc_generic(heap, size, zero, 0); + } + mi_assert_internal(block != NULL && _mi_ptr_page(block) == page); + // pop from the free list + page->used++; + page->free = mi_block_next(page, block); + mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page); + #if MI_DEBUG>3 + if (page->free_is_zero) { + mi_assert_expensive(mi_mem_is_zero(block+1,size - sizeof(*block))); + } + #endif + + // allow use of the block internally + // note: when tracking we need to avoid ever touching the MI_PADDING since + // that is tracked by valgrind etc. as non-accessible (through the red-zone, see `mimalloc/track.h`) + mi_track_mem_undefined(block, mi_page_usable_block_size(page)); + + // zero the block? note: we need to zero the full block size (issue #63) + if mi_unlikely(zero) { + mi_assert_internal(page->xblock_size != 0); // do not call with zero'ing for huge blocks (see _mi_malloc_generic) + mi_assert_internal(page->xblock_size >= MI_PADDING_SIZE); + if (page->free_is_zero) { + block->next = 0; + mi_track_mem_defined(block, page->xblock_size - MI_PADDING_SIZE); + } + else { + _mi_memzero_aligned(block, page->xblock_size - MI_PADDING_SIZE); + } + } + +#if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN + if (!zero && !mi_page_is_huge(page)) { + memset(block, MI_DEBUG_UNINIT, mi_page_usable_block_size(page)); + } +#elif (MI_SECURE!=0) + if (!zero) { block->next = 0; } // don't leak internal data +#endif + +#if (MI_STAT>0) + const size_t bsize = mi_page_usable_block_size(page); + if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) { + mi_heap_stat_increase(heap, normal, bsize); + mi_heap_stat_counter_increase(heap, normal_count, 1); +#if (MI_STAT>1) + const size_t bin = _mi_bin(bsize); + mi_heap_stat_increase(heap, normal_bins[bin], 1); +#endif + } +#endif + +#if MI_PADDING // && !MI_TRACK_ENABLED + mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page)); + ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE)); + #if (MI_DEBUG>=2) + mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta)); + #endif + mi_track_mem_defined(padding,sizeof(mi_padding_t)); // note: re-enable since mi_page_usable_block_size may set noaccess + padding->canary = (uint32_t)(mi_ptr_encode(page,block,page->keys)); + padding->delta = (uint32_t)(delta); + #if MI_PADDING_CHECK + if (!mi_page_is_huge(page)) { + uint8_t* fill = (uint8_t*)padding - delta; + const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes + for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; } + } + #endif +#endif + + return block; +} + +static inline mi_decl_restrict void* mi_heap_malloc_small_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept { + mi_assert(heap != NULL); + #if MI_DEBUG + const uintptr_t tid = _mi_thread_id(); + mi_assert(heap->thread_id == 0 || heap->thread_id == tid); // heaps are thread local + #endif + mi_assert(size <= MI_SMALL_SIZE_MAX); + #if (MI_PADDING) + if (size == 0) { size = sizeof(void*); } + #endif + mi_page_t* page = _mi_heap_get_free_small_page(heap, size + MI_PADDING_SIZE); + void* const p = _mi_page_malloc(heap, page, size + MI_PADDING_SIZE, zero); + mi_track_malloc(p,size,zero); + #if MI_STAT>1 + if (p != NULL) { + if (!mi_heap_is_initialized(heap)) { heap = mi_prim_get_default_heap(); } + mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); + } + #endif + #if MI_DEBUG>3 + if (p != NULL && zero) { + mi_assert_expensive(mi_mem_is_zero(p, size)); + } + #endif + return p; +} + +// allocate a small block +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return mi_heap_malloc_small_zero(heap, size, false); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept { + return mi_heap_malloc_small(mi_prim_get_default_heap(), size); +} + +// The main allocation function +extern inline void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept { + if mi_likely(size <= MI_SMALL_SIZE_MAX) { + mi_assert_internal(huge_alignment == 0); + return mi_heap_malloc_small_zero(heap, size, zero); + } + else { + mi_assert(heap!=NULL); + mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local + void* const p = _mi_malloc_generic(heap, size + MI_PADDING_SIZE, zero, huge_alignment); // note: size can overflow but it is detected in malloc_generic + mi_track_malloc(p,size,zero); + #if MI_STAT>1 + if (p != NULL) { + if (!mi_heap_is_initialized(heap)) { heap = mi_prim_get_default_heap(); } + mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); + } + #endif + #if MI_DEBUG>3 + if (p != NULL && zero) { + mi_assert_expensive(mi_mem_is_zero(p, size)); + } + #endif + return p; + } +} + +extern inline void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept { + return _mi_heap_malloc_zero_ex(heap, size, zero, 0); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return _mi_heap_malloc_zero(heap, size, false); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept { + return mi_heap_malloc(mi_prim_get_default_heap(), size); +} + +// zero initialized small block +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept { + return mi_heap_malloc_small_zero(mi_prim_get_default_heap(), size, true); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return _mi_heap_malloc_zero(heap, size, true); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept { + return mi_heap_zalloc(mi_prim_get_default_heap(),size); +} + + +// ------------------------------------------------------ +// Check for double free in secure and debug mode +// This is somewhat expensive so only enabled for secure mode 4 +// ------------------------------------------------------ + +#if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0)) +// linear check if the free list contains a specific element +static bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) { + while (list != NULL) { + if (elem==list) return true; + list = mi_block_next(page, list); + } + return false; +} + +static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) { + // The decoded value is in the same page (or NULL). + // Walk the free lists to verify positively if it is already freed + if (mi_list_contains(page, page->free, block) || + mi_list_contains(page, page->local_free, block) || + mi_list_contains(page, mi_page_thread_free(page), block)) + { + _mi_error_message(EAGAIN, "double free detected of block %p with size %zu\n", block, mi_page_block_size(page)); + return true; + } + return false; +} + +#define mi_track_page(page,access) { size_t psize; void* pstart = _mi_page_start(_mi_page_segment(page),page,&psize); mi_track_mem_##access( pstart, psize); } + +static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { + bool is_double_free = false; + mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field + if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer? + (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL? + { + // Suspicous: decoded value a in block is in the same page (or NULL) -- maybe a double free? + // (continue in separate function to improve code generation) + is_double_free = mi_check_is_double_freex(page, block); + } + return is_double_free; +} +#else +static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(page); + MI_UNUSED(block); + return false; +} +#endif + +// --------------------------------------------------------------------------- +// Check for heap block overflow by setting up padding at the end of the block +// --------------------------------------------------------------------------- + +#if MI_PADDING // && !MI_TRACK_ENABLED +static bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) { + *bsize = mi_page_usable_block_size(page); + const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize); + mi_track_mem_defined(padding,sizeof(mi_padding_t)); + *delta = padding->delta; + uint32_t canary = padding->canary; + uintptr_t keys[2]; + keys[0] = page->keys[0]; + keys[1] = page->keys[1]; + bool ok = ((uint32_t)mi_ptr_encode(page,block,keys) == canary && *delta <= *bsize); + mi_track_mem_noaccess(padding,sizeof(mi_padding_t)); + return ok; +} + +// Return the exact usable size of a block. +static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + mi_assert_internal(ok); mi_assert_internal(delta <= bsize); + return (ok ? bsize - delta : 0); +} + +// When a non-thread-local block is freed, it becomes part of the thread delayed free +// list that is freed later by the owning heap. If the exact usable size is too small to +// contain the pointer for the delayed list, then shrink the padding (by decreasing delta) +// so it will later not trigger an overflow error in `mi_free_block`. +void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + mi_assert_internal(ok); + if (!ok || (bsize - delta) >= min_size) return; // usually already enough space + mi_assert_internal(bsize >= min_size); + if (bsize < min_size) return; // should never happen + size_t new_delta = (bsize - min_size); + mi_assert_internal(new_delta < bsize); + mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize); + mi_track_mem_defined(padding,sizeof(mi_padding_t)); + padding->delta = (uint32_t)new_delta; + mi_track_mem_noaccess(padding,sizeof(mi_padding_t)); +} +#else +static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(block); + return mi_page_usable_block_size(page); +} + +void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { + MI_UNUSED(page); + MI_UNUSED(block); + MI_UNUSED(min_size); +} +#endif + +#if MI_PADDING && MI_PADDING_CHECK + +static bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + *size = *wrong = bsize; + if (!ok) return false; + mi_assert_internal(bsize >= delta); + *size = bsize - delta; + if (!mi_page_is_huge(page)) { + uint8_t* fill = (uint8_t*)block + bsize - delta; + const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes + mi_track_mem_defined(fill, maxpad); + for (size_t i = 0; i < maxpad; i++) { + if (fill[i] != MI_DEBUG_PADDING) { + *wrong = bsize - delta + i; + ok = false; + break; + } + } + mi_track_mem_noaccess(fill, maxpad); + } + return ok; +} + +static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { + size_t size; + size_t wrong; + if (!mi_verify_padding(page,block,&size,&wrong)) { + _mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong ); + } +} + +#else + +static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(page); + MI_UNUSED(block); +} + +#endif + +// only maintain stats for smaller objects if requested +#if (MI_STAT>0) +static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) { + #if (MI_STAT < 2) + MI_UNUSED(block); + #endif + mi_heap_t* const heap = mi_heap_get_default(); + const size_t bsize = mi_page_usable_block_size(page); + #if (MI_STAT>1) + const size_t usize = mi_page_usable_size_of(page, block); + mi_heap_stat_decrease(heap, malloc, usize); + #endif + if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, normal, bsize); + #if (MI_STAT > 1) + mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], 1); + #endif + } + else if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); + } +} +#else +static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(page); MI_UNUSED(block); +} +#endif + +#if MI_HUGE_PAGE_ABANDON +#if (MI_STAT>0) +// maintain stats for huge objects +static void mi_stat_huge_free(const mi_page_t* page) { + mi_heap_t* const heap = mi_heap_get_default(); + const size_t bsize = mi_page_block_size(page); // to match stats in `page.c:mi_page_huge_alloc` + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); + } +} +#else +static void mi_stat_huge_free(const mi_page_t* page) { + MI_UNUSED(page); +} +#endif +#endif + +// ------------------------------------------------------ +// Free +// ------------------------------------------------------ + +// multi-threaded free (or free in huge block if compiled with MI_HUGE_PAGE_ABANDON) +static mi_decl_noinline void _mi_free_block_mt(mi_page_t* page, mi_block_t* block) +{ + // The padding check may access the non-thread-owned page for the key values. + // that is safe as these are constant and the page won't be freed (as the block is not freed yet). + mi_check_padding(page, block); + _mi_padding_shrink(page, block, sizeof(mi_block_t)); // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection + + // huge page segments are always abandoned and can be freed immediately + mi_segment_t* segment = _mi_page_segment(page); + if (segment->kind == MI_SEGMENT_HUGE) { + #if MI_HUGE_PAGE_ABANDON + // huge page segments are always abandoned and can be freed immediately + mi_stat_huge_free(page); + _mi_segment_huge_page_free(segment, page, block); + return; + #else + // huge pages are special as they occupy the entire segment + // as these are large we reset the memory occupied by the page so it is available to other threads + // (as the owning thread needs to actually free the memory later). + _mi_segment_huge_page_reset(segment, page, block); + #endif + } + + #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN // note: when tracking, cannot use mi_usable_size with multi-threading + if (segment->kind != MI_SEGMENT_HUGE) { // not for huge segments as we just reset the content + memset(block, MI_DEBUG_FREED, mi_usable_size(block)); + } + #endif + + // Try to put the block on either the page-local thread free list, or the heap delayed free list. + mi_thread_free_t tfreex; + bool use_delayed; + mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free); + do { + use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE); + if mi_unlikely(use_delayed) { + // unlikely: this only happens on the first concurrent free in a page that is in the full list + tfreex = mi_tf_set_delayed(tfree,MI_DELAYED_FREEING); + } + else { + // usual: directly add to page thread_free list + mi_block_set_next(page, block, mi_tf_block(tfree)); + tfreex = mi_tf_set_block(tfree,block); + } + } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); + + if mi_unlikely(use_delayed) { + // racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`) + mi_heap_t* const heap = (mi_heap_t*)(mi_atomic_load_acquire(&page->xheap)); //mi_page_heap(page); + mi_assert_internal(heap != NULL); + if (heap != NULL) { + // add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity) + mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); + do { + mi_block_set_nextx(heap,block,dfree, heap->keys); + } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block)); + } + + // and reset the MI_DELAYED_FREEING flag + tfree = mi_atomic_load_relaxed(&page->xthread_free); + do { + tfreex = tfree; + mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING); + tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE); + } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); + } +} + +// regular free +static inline void _mi_free_block(mi_page_t* page, bool local, mi_block_t* block) +{ + // and push it on the free list + //const size_t bsize = mi_page_block_size(page); + if mi_likely(local) { + // owning thread can free a block directly + if mi_unlikely(mi_check_is_double_free(page, block)) return; + mi_check_padding(page, block); + #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN + if (!mi_page_is_huge(page)) { // huge page content may be already decommitted + memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); + } + #endif + mi_block_set_next(page, block, page->local_free); + page->local_free = block; + page->used--; + if mi_unlikely(mi_page_all_free(page)) { + _mi_page_retire(page); + } + else if mi_unlikely(mi_page_is_in_full(page)) { + _mi_page_unfull(page); + } + } + else { + _mi_free_block_mt(page,block); + } +} + + +// Adjust a block that was allocated aligned, to the actual start of the block in the page. +mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p) { + mi_assert_internal(page!=NULL && p!=NULL); + const size_t diff = (uint8_t*)p - _mi_page_start(segment, page, NULL); + const size_t adjust = (diff % mi_page_block_size(page)); + return (mi_block_t*)((uintptr_t)p - adjust); +} + + +void mi_decl_noinline _mi_free_generic(const mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept { + mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p); + mi_stat_free(page, block); // stat_free may access the padding + mi_track_free_size(block, mi_page_usable_size_of(page,block)); + _mi_free_block(page, is_local, block); +} + +// Get the segment data belonging to a pointer +// This is just a single `and` in assembly but does further checks in debug mode +// (and secure mode) if this was a valid pointer. +static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg) +{ + MI_UNUSED(msg); + mi_assert(p != NULL); + +#if (MI_DEBUG>0) + if mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) { + _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p); + return NULL; + } +#endif + + mi_segment_t* const segment = _mi_ptr_segment(p); + mi_assert_internal(segment != NULL); + +#if (MI_DEBUG>0) + if mi_unlikely(!mi_is_in_heap_region(p)) { + #if (MI_INTPTR_SIZE == 8 && defined(__linux__)) + if (((uintptr_t)p >> 40) != 0x7F) { // linux tends to align large blocks above 0x7F000000000 (issue #640) + #else + { + #endif + _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n" + "(this may still be a valid very large allocation (over 64MiB))\n", msg, p); + if mi_likely(_mi_ptr_cookie(segment) == segment->cookie) { + _mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p); + } + } + } +#endif +#if (MI_DEBUG>0 || MI_SECURE>=4) + if mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie) { + _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", msg, p); + return NULL; + } +#endif + + return segment; +} + +// Free a block +// fast path written carefully to prevent spilling on the stack +void mi_free(void* p) mi_attr_noexcept +{ + if mi_unlikely(p == NULL) return; + mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free"); + const bool is_local= (_mi_prim_thread_id() == mi_atomic_load_relaxed(&segment->thread_id)); + mi_page_t* const page = _mi_segment_page_of(segment, p); + + if mi_likely(is_local) { // thread-local free? + if mi_likely(page->flags.full_aligned == 0) // and it is not a full page (full pages need to move from the full bin), nor has aligned blocks (aligned blocks need to be unaligned) + { + mi_block_t* const block = (mi_block_t*)p; + if mi_unlikely(mi_check_is_double_free(page, block)) return; + mi_check_padding(page, block); + mi_stat_free(page, block); + #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN + memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); + #endif + mi_track_free_size(p, mi_page_usable_size_of(page,block)); // faster then mi_usable_size as we already know the page and that p is unaligned + mi_block_set_next(page, block, page->local_free); + page->local_free = block; + if mi_unlikely(--page->used == 0) { // using this expression generates better code than: page->used--; if (mi_page_all_free(page)) + _mi_page_retire(page); + } + } + else { + // page is full or contains (inner) aligned blocks; use generic path + _mi_free_generic(segment, page, true, p); + } + } + else { + // not thread-local; use generic path + _mi_free_generic(segment, page, false, p); + } +} + +// return true if successful +bool _mi_free_delayed_block(mi_block_t* block) { + // get segment and page + const mi_segment_t* const segment = _mi_ptr_segment(block); + mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(_mi_thread_id() == segment->thread_id); + mi_page_t* const page = _mi_segment_page_of(segment, block); + + // Clear the no-delayed flag so delayed freeing is used again for this page. + // This must be done before collecting the free lists on this page -- otherwise + // some blocks may end up in the page `thread_free` list with no blocks in the + // heap `thread_delayed_free` list which may cause the page to be never freed! + // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`) + if (!_mi_page_try_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */)) { + return false; + } + + // collect all other non-local frees to ensure up-to-date `used` count + _mi_page_free_collect(page, false); + + // and free the block (possibly freeing the page as well since used is updated) + _mi_free_block(page, true, block); + return true; +} + +// Bytes available in a block +mi_decl_noinline static size_t mi_page_usable_aligned_size_of(const mi_segment_t* segment, const mi_page_t* page, const void* p) mi_attr_noexcept { + const mi_block_t* block = _mi_page_ptr_unalign(segment, page, p); + const size_t size = mi_page_usable_size_of(page, block); + const ptrdiff_t adjust = (uint8_t*)p - (uint8_t*)block; + mi_assert_internal(adjust >= 0 && (size_t)adjust <= size); + return (size - adjust); +} + +static inline size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept { + if (p == NULL) return 0; + const mi_segment_t* const segment = mi_checked_ptr_segment(p, msg); + const mi_page_t* const page = _mi_segment_page_of(segment, p); + if mi_likely(!mi_page_has_aligned(page)) { + const mi_block_t* block = (const mi_block_t*)p; + return mi_page_usable_size_of(page, block); + } + else { + // split out to separate routine for improved code generation + return mi_page_usable_aligned_size_of(segment, page, p); + } +} + +mi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept { + return _mi_usable_size(p, "mi_usable_size"); +} + + +// ------------------------------------------------------ +// Allocation extensions +// ------------------------------------------------------ + +void mi_free_size(void* p, size_t size) mi_attr_noexcept { + MI_UNUSED_RELEASE(size); + mi_assert(p == NULL || size <= _mi_usable_size(p,"mi_free_size")); + mi_free(p); +} + +void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept { + MI_UNUSED_RELEASE(alignment); + mi_assert(((uintptr_t)p % alignment) == 0); + mi_free_size(p,size); +} + +void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept { + MI_UNUSED_RELEASE(alignment); + mi_assert(((uintptr_t)p % alignment) == 0); + mi_free(p); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count,size,&total)) return NULL; + return mi_heap_zalloc(heap,total); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept { + return mi_heap_calloc(mi_prim_get_default_heap(),count,size); +} + +// Uninitialized `calloc` +mi_decl_nodiscard extern mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_malloc(heap, total); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept { + return mi_heap_mallocn(mi_prim_get_default_heap(),count,size); +} + +// Expand (or shrink) in place (or fail) +void* mi_expand(void* p, size_t newsize) mi_attr_noexcept { + #if MI_PADDING + // we do not shrink/expand with padding enabled + MI_UNUSED(p); MI_UNUSED(newsize); + return NULL; + #else + if (p == NULL) return NULL; + const size_t size = _mi_usable_size(p,"mi_expand"); + if (newsize > size) return NULL; + return p; // it fits + #endif +} + +void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept { + // if p == NULL then behave as malloc. + // else if size == 0 then reallocate to a zero-sized block (and don't return NULL, just as mi_malloc(0)). + // (this means that returning NULL always indicates an error, and `p` will not have been freed in that case.) + const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL (with size 0) + if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) { // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0) + mi_assert_internal(p!=NULL); + // todo: do not track as the usable size is still the same in the free; adjust potential padding? + // mi_track_resize(p,size,newsize) + // if (newsize < size) { mi_track_mem_noaccess((uint8_t*)p + newsize, size - newsize); } + return p; // reallocation still fits and not more than 50% waste + } + void* newp = mi_heap_malloc(heap,newsize); + if mi_likely(newp != NULL) { + if (zero && newsize > size) { + // also set last word in the previous allocation to zero to ensure any padding is zero-initialized + const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); + _mi_memzero((uint8_t*)newp + start, newsize - start); + } + else if (newsize == 0) { + ((uint8_t*)newp)[0] = 0; // work around for applications that expect zero-reallocation to be zero initialized (issue #725) + } + if mi_likely(p != NULL) { + const size_t copysize = (newsize > size ? size : newsize); + mi_track_mem_defined(p,copysize); // _mi_useable_size may be too large for byte precise memory tracking.. + _mi_memcpy(newp, p, copysize); + mi_free(p); // only free the original pointer if successful + } + } + return newp; +} + +mi_decl_nodiscard void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + return _mi_heap_realloc_zero(heap, p, newsize, false); +} + +mi_decl_nodiscard void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_realloc(heap, p, total); +} + + +// Reallocate but free `p` on errors +mi_decl_nodiscard void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + void* newp = mi_heap_realloc(heap, p, newsize); + if (newp==NULL && p!=NULL) mi_free(p); + return newp; +} + +mi_decl_nodiscard void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + return _mi_heap_realloc_zero(heap, p, newsize, true); +} + +mi_decl_nodiscard void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_rezalloc(heap, p, total); +} + + +mi_decl_nodiscard void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_realloc(mi_prim_get_default_heap(),p,newsize); +} + +mi_decl_nodiscard void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept { + return mi_heap_reallocn(mi_prim_get_default_heap(),p,count,size); +} + +// Reallocate but free `p` on errors +mi_decl_nodiscard void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_reallocf(mi_prim_get_default_heap(),p,newsize); +} + +mi_decl_nodiscard void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_rezalloc(mi_prim_get_default_heap(), p, newsize); +} + +mi_decl_nodiscard void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { + return mi_heap_recalloc(mi_prim_get_default_heap(), p, count, size); +} + + + +// ------------------------------------------------------ +// strdup, strndup, and realpath +// ------------------------------------------------------ + +// `strdup` using mi_malloc +mi_decl_nodiscard mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept { + if (s == NULL) return NULL; + size_t n = strlen(s); + char* t = (char*)mi_heap_malloc(heap,n+1); + if (t == NULL) return NULL; + _mi_memcpy(t, s, n); + t[n] = 0; + return t; +} + +mi_decl_nodiscard mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept { + return mi_heap_strdup(mi_prim_get_default_heap(), s); +} + +// `strndup` using mi_malloc +mi_decl_nodiscard mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept { + if (s == NULL) return NULL; + const char* end = (const char*)memchr(s, 0, n); // find end of string in the first `n` characters (returns NULL if not found) + const size_t m = (end != NULL ? (size_t)(end - s) : n); // `m` is the minimum of `n` or the end-of-string + mi_assert_internal(m <= n); + char* t = (char*)mi_heap_malloc(heap, m+1); + if (t == NULL) return NULL; + _mi_memcpy(t, s, m); + t[m] = 0; + return t; +} + +mi_decl_nodiscard mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept { + return mi_heap_strndup(mi_prim_get_default_heap(),s,n); +} + +#ifndef __wasi__ +// `realpath` using mi_malloc +#ifdef _WIN32 +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif +#include <windows.h> +mi_decl_nodiscard mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { + // todo: use GetFullPathNameW to allow longer file names + char buf[PATH_MAX]; + DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL); + if (res == 0) { + errno = GetLastError(); return NULL; + } + else if (res > PATH_MAX) { + errno = EINVAL; return NULL; + } + else if (resolved_name != NULL) { + return resolved_name; + } + else { + return mi_heap_strndup(heap, buf, PATH_MAX); + } +} +#else +/* +#include <unistd.h> // pathconf +static size_t mi_path_max(void) { + static size_t path_max = 0; + if (path_max <= 0) { + long m = pathconf("/",_PC_PATH_MAX); + if (m <= 0) path_max = 4096; // guess + else if (m < 256) path_max = 256; // at least 256 + else path_max = m; + } + return path_max; +} +*/ +char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { + if (resolved_name != NULL) { + return realpath(fname,resolved_name); + } + else { + char* rname = realpath(fname, NULL); + if (rname == NULL) return NULL; + char* result = mi_heap_strdup(heap, rname); + free(rname); // use regular free! (which may be redirected to our free but that's ok) + return result; + } + /* + const size_t n = mi_path_max(); + char* buf = (char*)mi_malloc(n+1); + if (buf == NULL) { + errno = ENOMEM; + return NULL; + } + char* rname = realpath(fname,buf); + char* result = mi_heap_strndup(heap,rname,n); // ok if `rname==NULL` + mi_free(buf); + return result; + } + */ +} +#endif + +mi_decl_nodiscard mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept { + return mi_heap_realpath(mi_prim_get_default_heap(),fname,resolved_name); +} +#endif + +/*------------------------------------------------------- +C++ new and new_aligned +The standard requires calling into `get_new_handler` and +throwing the bad_alloc exception on failure. If we compile +with a C++ compiler we can implement this precisely. If we +use a C compiler we cannot throw a `bad_alloc` exception +but we call `exit` instead (i.e. not returning). +-------------------------------------------------------*/ + +#ifdef __cplusplus +#include <new> +static bool mi_try_new_handler(bool nothrow) { + #if defined(_MSC_VER) || (__cplusplus >= 201103L) + std::new_handler h = std::get_new_handler(); + #else + std::new_handler h = std::set_new_handler(); + std::set_new_handler(h); + #endif + if (h==NULL) { + _mi_error_message(ENOMEM, "out of memory in 'new'"); + if (!nothrow) { + throw std::bad_alloc(); + } + return false; + } + else { + h(); + return true; + } +} +#else +typedef void (*std_new_handler_t)(void); + +#if (defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER))) // exclude clang-cl, see issue #631 +std_new_handler_t __attribute__((weak)) _ZSt15get_new_handlerv(void) { + return NULL; +} +static std_new_handler_t mi_get_new_handler(void) { + return _ZSt15get_new_handlerv(); +} +#else +// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`. +static std_new_handler_t mi_get_new_handler() { + return NULL; +} +#endif + +static bool mi_try_new_handler(bool nothrow) { + std_new_handler_t h = mi_get_new_handler(); + if (h==NULL) { + _mi_error_message(ENOMEM, "out of memory in 'new'"); + if (!nothrow) { + abort(); // cannot throw in plain C, use abort + } + return false; + } + else { + h(); + return true; + } +} +#endif + +mi_decl_export mi_decl_noinline void* mi_heap_try_new(mi_heap_t* heap, size_t size, bool nothrow ) { + void* p = NULL; + while(p == NULL && mi_try_new_handler(nothrow)) { + p = mi_heap_malloc(heap,size); + } + return p; +} + +static mi_decl_noinline void* mi_try_new(size_t size, bool nothrow) { + return mi_heap_try_new(mi_prim_get_default_heap(), size, nothrow); +} + + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) { + void* p = mi_heap_malloc(heap,size); + if mi_unlikely(p == NULL) return mi_heap_try_new(heap, size, false); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new(size_t size) { + return mi_heap_alloc_new(mi_prim_get_default_heap(), size); +} + + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) { + size_t total; + if mi_unlikely(mi_count_size_overflow(count, size, &total)) { + mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc + return NULL; + } + else { + return mi_heap_alloc_new(heap,total); + } +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new_n(size_t count, size_t size) { + return mi_heap_alloc_new_n(mi_prim_get_default_heap(), size, count); +} + + +mi_decl_nodiscard mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept { + void* p = mi_malloc(size); + if mi_unlikely(p == NULL) return mi_try_new(size, true); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) { + void* p; + do { + p = mi_malloc_aligned(size, alignment); + } + while(p == NULL && mi_try_new_handler(false)); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept { + void* p; + do { + p = mi_malloc_aligned(size, alignment); + } + while(p == NULL && mi_try_new_handler(true)); + return p; +} + +mi_decl_nodiscard void* mi_new_realloc(void* p, size_t newsize) { + void* q; + do { + q = mi_realloc(p, newsize); + } while (q == NULL && mi_try_new_handler(false)); + return q; +} + +mi_decl_nodiscard void* mi_new_reallocn(void* p, size_t newcount, size_t size) { + size_t total; + if mi_unlikely(mi_count_size_overflow(newcount, size, &total)) { + mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc + return NULL; + } + else { + return mi_new_realloc(p, total); + } +} + +// ------------------------------------------------------ +// ensure explicit external inline definitions are emitted! +// ------------------------------------------------------ + +#ifdef __cplusplus +void* _mi_externs[] = { + (void*)&_mi_page_malloc, + (void*)&_mi_heap_malloc_zero, + (void*)&_mi_heap_malloc_zero_ex, + (void*)&mi_malloc, + (void*)&mi_malloc_small, + (void*)&mi_zalloc_small, + (void*)&mi_heap_malloc, + (void*)&mi_heap_zalloc, + (void*)&mi_heap_malloc_small, + // (void*)&mi_heap_alloc_new, + // (void*)&mi_heap_alloc_new_n +}; +#endif diff --git a/lib/Utils.Memory/mimalloc/src/arena.c b/lib/Utils.Memory/mimalloc/src/arena.c new file mode 100644 index 0000000..a04a04c --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/arena.c @@ -0,0 +1,936 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +"Arenas" are fixed area's of OS memory from which we can allocate +large blocks (>= MI_ARENA_MIN_BLOCK_SIZE, 4MiB). +In contrast to the rest of mimalloc, the arenas are shared between +threads and need to be accessed using atomic operations. + +Arenas are used to for huge OS page (1GiB) reservations or for reserving +OS memory upfront which can be improve performance or is sometimes needed +on embedded devices. We can also employ this with WASI or `sbrk` systems +to reserve large arenas upfront and be able to reuse the memory more effectively. + +The arena allocation needs to be thread safe and we use an atomic bitmap to allocate. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +#include <string.h> // memset +#include <errno.h> // ENOMEM + +#include "bitmap.h" // atomic bitmap + +/* ----------------------------------------------------------- + Arena allocation +----------------------------------------------------------- */ + +// Block info: bit 0 contains the `in_use` bit, the upper bits the +// size in count of arena blocks. +typedef uintptr_t mi_block_info_t; +#define MI_ARENA_BLOCK_SIZE (MI_SEGMENT_SIZE) // 64MiB (must be at least MI_SEGMENT_ALIGN) +#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2) // 32MiB +#define MI_MAX_ARENAS (112) // not more than 126 (since we use 7 bits in the memid and an arena index + 1) + +// A memory arena descriptor +typedef struct mi_arena_s { + mi_arena_id_t id; // arena id; 0 for non-specific + mi_memid_t memid; // memid of the memory area + _Atomic(uint8_t*) start; // the start of the memory area + size_t block_count; // size of the area in arena blocks (of `MI_ARENA_BLOCK_SIZE`) + size_t field_count; // number of bitmap fields (where `field_count * MI_BITMAP_FIELD_BITS >= block_count`) + size_t meta_size; // size of the arena structure itself (including its bitmaps) + mi_memid_t meta_memid; // memid of the arena structure itself (OS or static allocation) + int numa_node; // associated NUMA node + bool exclusive; // only allow allocations if specifically for this arena + bool is_large; // memory area consists of large- or huge OS pages (always committed) + _Atomic(size_t) search_idx; // optimization to start the search for free blocks + _Atomic(mi_msecs_t) purge_expire; // expiration time when blocks should be decommitted from `blocks_decommit`. + mi_bitmap_field_t* blocks_dirty; // are the blocks potentially non-zero? + mi_bitmap_field_t* blocks_committed; // are the blocks committed? (can be NULL for memory that cannot be decommitted) + mi_bitmap_field_t* blocks_purge; // blocks that can be (reset) decommitted. (can be NULL for memory that cannot be (reset) decommitted) + mi_bitmap_field_t blocks_inuse[1]; // in-place bitmap of in-use blocks (of size `field_count`) +} mi_arena_t; + + +// The available arenas +static mi_decl_cache_align _Atomic(mi_arena_t*) mi_arenas[MI_MAX_ARENAS]; +static mi_decl_cache_align _Atomic(size_t) mi_arena_count; // = 0 + + +//static bool mi_manage_os_memory_ex2(void* start, size_t size, bool is_large, int numa_node, bool exclusive, mi_memid_t memid, mi_arena_id_t* arena_id) mi_attr_noexcept; + +/* ----------------------------------------------------------- + Arena id's + id = arena_index + 1 +----------------------------------------------------------- */ + +static size_t mi_arena_id_index(mi_arena_id_t id) { + return (size_t)(id <= 0 ? MI_MAX_ARENAS : id - 1); +} + +static mi_arena_id_t mi_arena_id_create(size_t arena_index) { + mi_assert_internal(arena_index < MI_MAX_ARENAS); + return (int)arena_index + 1; +} + +mi_arena_id_t _mi_arena_id_none(void) { + return 0; +} + +static bool mi_arena_id_is_suitable(mi_arena_id_t arena_id, bool arena_is_exclusive, mi_arena_id_t req_arena_id) { + return ((!arena_is_exclusive && req_arena_id == _mi_arena_id_none()) || + (arena_id == req_arena_id)); +} + +bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id) { + if (memid.memkind == MI_MEM_ARENA) { + return mi_arena_id_is_suitable(memid.mem.arena.id, memid.mem.arena.is_exclusive, request_arena_id); + } + else { + return mi_arena_id_is_suitable(0, false, request_arena_id); + } +} + +bool _mi_arena_memid_is_os_allocated(mi_memid_t memid) { + return (memid.memkind == MI_MEM_OS); +} + +/* ----------------------------------------------------------- + Arena allocations get a (currently) 16-bit memory id where the + lower 8 bits are the arena id, and the upper bits the block index. +----------------------------------------------------------- */ + +static size_t mi_block_count_of_size(size_t size) { + return _mi_divide_up(size, MI_ARENA_BLOCK_SIZE); +} + +static size_t mi_arena_block_size(size_t bcount) { + return (bcount * MI_ARENA_BLOCK_SIZE); +} + +static size_t mi_arena_size(mi_arena_t* arena) { + return mi_arena_block_size(arena->block_count); +} + +static mi_memid_t mi_memid_create_arena(mi_arena_id_t id, bool is_exclusive, mi_bitmap_index_t bitmap_index) { + mi_memid_t memid = _mi_memid_create(MI_MEM_ARENA); + memid.mem.arena.id = id; + memid.mem.arena.block_index = bitmap_index; + memid.mem.arena.is_exclusive = is_exclusive; + return memid; +} + +static bool mi_arena_memid_indices(mi_memid_t memid, size_t* arena_index, mi_bitmap_index_t* bitmap_index) { + mi_assert_internal(memid.memkind == MI_MEM_ARENA); + *arena_index = mi_arena_id_index(memid.mem.arena.id); + *bitmap_index = memid.mem.arena.block_index; + return memid.mem.arena.is_exclusive; +} + + + +/* ----------------------------------------------------------- + Special static area for mimalloc internal structures + to avoid OS calls (for example, for the arena metadata) +----------------------------------------------------------- */ + +#define MI_ARENA_STATIC_MAX (MI_INTPTR_SIZE*MI_KiB) // 8 KiB on 64-bit + +static uint8_t mi_arena_static[MI_ARENA_STATIC_MAX]; +static _Atomic(size_t) mi_arena_static_top; + +static void* mi_arena_static_zalloc(size_t size, size_t alignment, mi_memid_t* memid) { + *memid = _mi_memid_none(); + if (size == 0 || size > MI_ARENA_STATIC_MAX) return NULL; + if ((mi_atomic_load_relaxed(&mi_arena_static_top) + size) > MI_ARENA_STATIC_MAX) return NULL; + + // try to claim space + if (alignment == 0) { alignment = 1; } + const size_t oversize = size + alignment - 1; + if (oversize > MI_ARENA_STATIC_MAX) return NULL; + const size_t oldtop = mi_atomic_add_acq_rel(&mi_arena_static_top, oversize); + size_t top = oldtop + oversize; + if (top > MI_ARENA_STATIC_MAX) { + // try to roll back, ok if this fails + mi_atomic_cas_strong_acq_rel(&mi_arena_static_top, &top, oldtop); + return NULL; + } + + // success + *memid = _mi_memid_create(MI_MEM_STATIC); + const size_t start = _mi_align_up(oldtop, alignment); + uint8_t* const p = &mi_arena_static[start]; + _mi_memzero(p, size); + return p; +} + +static void* mi_arena_meta_zalloc(size_t size, mi_memid_t* memid, mi_stats_t* stats) { + *memid = _mi_memid_none(); + + // try static + void* p = mi_arena_static_zalloc(size, MI_ALIGNMENT_MAX, memid); + if (p != NULL) return p; + + // or fall back to the OS + return _mi_os_alloc(size, memid, stats); +} + +static void mi_arena_meta_free(void* p, mi_memid_t memid, size_t size, mi_stats_t* stats) { + if (mi_memkind_is_os(memid.memkind)) { + _mi_os_free(p, size, memid, stats); + } + else { + mi_assert(memid.memkind == MI_MEM_STATIC); + } +} + +static void* mi_arena_block_start(mi_arena_t* arena, mi_bitmap_index_t bindex) { + return (arena->start + mi_arena_block_size(mi_bitmap_index_bit(bindex))); +} + + +/* ----------------------------------------------------------- + Thread safe allocation in an arena +----------------------------------------------------------- */ + +// claim the `blocks_inuse` bits +static bool mi_arena_try_claim(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx) +{ + size_t idx = 0; // mi_atomic_load_relaxed(&arena->search_idx); // start from last search; ok to be relaxed as the exact start does not matter + if (_mi_bitmap_try_find_from_claim_across(arena->blocks_inuse, arena->field_count, idx, blocks, bitmap_idx)) { + mi_atomic_store_relaxed(&arena->search_idx, mi_bitmap_index_field(*bitmap_idx)); // start search from found location next time around + return true; + }; + return false; +} + + +/* ----------------------------------------------------------- + Arena Allocation +----------------------------------------------------------- */ + +static mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t arena_index, size_t needed_bcount, + bool commit, mi_memid_t* memid, mi_os_tld_t* tld) +{ + MI_UNUSED(arena_index); + mi_assert_internal(mi_arena_id_index(arena->id) == arena_index); + + mi_bitmap_index_t bitmap_index; + if (!mi_arena_try_claim(arena, needed_bcount, &bitmap_index)) return NULL; + + // claimed it! + void* p = mi_arena_block_start(arena, bitmap_index); + *memid = mi_memid_create_arena(arena->id, arena->exclusive, bitmap_index); + memid->is_pinned = arena->memid.is_pinned; + + // none of the claimed blocks should be scheduled for a decommit + if (arena->blocks_purge != NULL) { + // this is thread safe as a potential purge only decommits parts that are not yet claimed as used (in `blocks_inuse`). + _mi_bitmap_unclaim_across(arena->blocks_purge, arena->field_count, needed_bcount, bitmap_index); + } + + // set the dirty bits (todo: no need for an atomic op here?) + if (arena->memid.initially_zero && arena->blocks_dirty != NULL) { + memid->initially_zero = _mi_bitmap_claim_across(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL); + } + + // set commit state + if (arena->blocks_committed == NULL) { + // always committed + memid->initially_committed = true; + } + else if (commit) { + // commit requested, but the range may not be committed as a whole: ensure it is committed now + memid->initially_committed = true; + bool any_uncommitted; + _mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted); + if (any_uncommitted) { + bool commit_zero = false; + if (!_mi_os_commit(p, mi_arena_block_size(needed_bcount), &commit_zero, tld->stats)) { + memid->initially_committed = false; + } + else { + if (commit_zero) { memid->initially_zero = true; } + } + } + } + else { + // no need to commit, but check if already fully committed + memid->initially_committed = _mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index); + } + + return p; +} + +// allocate in a speficic arena +static void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_node, int numa_node, size_t size, size_t alignment, + bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld ) +{ + MI_UNUSED_RELEASE(alignment); + mi_assert_internal(alignment <= MI_SEGMENT_ALIGN); + const size_t bcount = mi_block_count_of_size(size); + const size_t arena_index = mi_arena_id_index(arena_id); + mi_assert_internal(arena_index < mi_atomic_load_relaxed(&mi_arena_count)); + mi_assert_internal(size <= mi_arena_block_size(bcount)); + + // Check arena suitability + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[arena_index]); + if (arena == NULL) return NULL; + if (!allow_large && arena->is_large) return NULL; + if (!mi_arena_id_is_suitable(arena->id, arena->exclusive, req_arena_id)) return NULL; + if (req_arena_id == _mi_arena_id_none()) { // in not specific, check numa affinity + const bool numa_suitable = (numa_node < 0 || arena->numa_node < 0 || arena->numa_node == numa_node); + if (match_numa_node) { if (!numa_suitable) return NULL; } + else { if (numa_suitable) return NULL; } + } + + // try to allocate + void* p = mi_arena_try_alloc_at(arena, arena_index, bcount, commit, memid, tld); + mi_assert_internal(p == NULL || _mi_is_aligned(p, alignment)); + return p; +} + + +// allocate from an arena with fallback to the OS +static mi_decl_noinline void* mi_arena_try_alloc(int numa_node, size_t size, size_t alignment, + bool commit, bool allow_large, + mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld ) +{ + MI_UNUSED(alignment); + mi_assert_internal(alignment <= MI_SEGMENT_ALIGN); + const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count); + if mi_likely(max_arena == 0) return NULL; + + if (req_arena_id != _mi_arena_id_none()) { + // try a specific arena if requested + if (mi_arena_id_index(req_arena_id) < max_arena) { + void* p = mi_arena_try_alloc_at_id(req_arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + } + else { + // try numa affine allocation + for (size_t i = 0; i < max_arena; i++) { + void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + + // try from another numa node instead.. + if (numa_node >= 0) { // if numa_node was < 0 (no specific affinity requested), all arena's have been tried already + for (size_t i = 0; i < max_arena; i++) { + void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), false /* only proceed if not numa local */, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + } + } + return NULL; +} + +// try to reserve a fresh arena space +static bool mi_arena_reserve(size_t req_size, bool allow_large, mi_arena_id_t req_arena_id, mi_arena_id_t *arena_id) +{ + if (_mi_preloading()) return false; // use OS only while pre loading + if (req_arena_id != _mi_arena_id_none()) return false; + + const size_t arena_count = mi_atomic_load_acquire(&mi_arena_count); + if (arena_count > (MI_MAX_ARENAS - 4)) return false; + + size_t arena_reserve = mi_option_get_size(mi_option_arena_reserve); + if (arena_reserve == 0) return false; + + if (!_mi_os_has_virtual_reserve()) { + arena_reserve = arena_reserve/4; // be conservative if virtual reserve is not supported (for some embedded systems for example) + } + arena_reserve = _mi_align_up(arena_reserve, MI_ARENA_BLOCK_SIZE); + if (arena_count >= 8 && arena_count <= 128) { + arena_reserve = ((size_t)1<<(arena_count/8)) * arena_reserve; // scale up the arena sizes exponentially + } + if (arena_reserve < req_size) return false; // should be able to at least handle the current allocation size + + // commit eagerly? + bool arena_commit = false; + if (mi_option_get(mi_option_arena_eager_commit) == 2) { arena_commit = _mi_os_has_overcommit(); } + else if (mi_option_get(mi_option_arena_eager_commit) == 1) { arena_commit = true; } + + return (mi_reserve_os_memory_ex(arena_reserve, arena_commit, allow_large, false /* exclusive */, arena_id) == 0); +} + + +void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, + mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld) +{ + mi_assert_internal(memid != NULL && tld != NULL); + mi_assert_internal(size > 0); + *memid = _mi_memid_none(); + + const int numa_node = _mi_os_numa_node(tld); // current numa node + + // try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data) + if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0) { + void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + + // otherwise, try to first eagerly reserve a new arena + if (req_arena_id == _mi_arena_id_none()) { + mi_arena_id_t arena_id = 0; + if (mi_arena_reserve(size, allow_large, req_arena_id, &arena_id)) { + // and try allocate in there + mi_assert_internal(req_arena_id == _mi_arena_id_none()); + p = mi_arena_try_alloc_at_id(arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + } + } + + // if we cannot use OS allocation, return NULL + if (mi_option_is_enabled(mi_option_limit_os_alloc) || req_arena_id != _mi_arena_id_none()) { + errno = ENOMEM; + return NULL; + } + + // finally, fall back to the OS + if (align_offset > 0) { + return _mi_os_alloc_aligned_at_offset(size, alignment, align_offset, commit, allow_large, memid, tld->stats); + } + else { + return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld->stats); + } +} + +void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld) +{ + return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, 0, commit, allow_large, req_arena_id, memid, tld); +} + + +void* mi_arena_area(mi_arena_id_t arena_id, size_t* size) { + if (size != NULL) *size = 0; + size_t arena_index = mi_arena_id_index(arena_id); + if (arena_index >= MI_MAX_ARENAS) return NULL; + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[arena_index]); + if (arena == NULL) return NULL; + if (size != NULL) { *size = mi_arena_block_size(arena->block_count); } + return arena->start; +} + + +/* ----------------------------------------------------------- + Arena purge +----------------------------------------------------------- */ + +static long mi_arena_purge_delay(void) { + // <0 = no purging allowed, 0=immediate purging, >0=milli-second delay + return (mi_option_get(mi_option_purge_delay) * mi_option_get(mi_option_arena_purge_mult)); +} + +// reset or decommit in an arena and update the committed/decommit bitmaps +// assumes we own the area (i.e. blocks_in_use is claimed by us) +static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) { + mi_assert_internal(arena->blocks_committed != NULL); + mi_assert_internal(arena->blocks_purge != NULL); + mi_assert_internal(!arena->memid.is_pinned); + const size_t size = mi_arena_block_size(blocks); + void* const p = mi_arena_block_start(arena, bitmap_idx); + bool needs_recommit; + if (_mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx)) { + // all blocks are committed, we can purge freely + needs_recommit = _mi_os_purge(p, size, stats); + } + else { + // some blocks are not committed -- this can happen when a partially committed block is freed + // in `_mi_arena_free` and it is conservatively marked as uncommitted but still scheduled for a purge + // we need to ensure we do not try to reset (as that may be invalid for uncommitted memory), + // and also undo the decommit stats (as it was already adjusted) + mi_assert_internal(mi_option_is_enabled(mi_option_purge_decommits)); + needs_recommit = _mi_os_purge_ex(p, size, false /* allow reset? */, stats); + _mi_stat_increase(&stats->committed, size); + } + + // clear the purged blocks + _mi_bitmap_unclaim_across(arena->blocks_purge, arena->field_count, blocks, bitmap_idx); + // update committed bitmap + if (needs_recommit) { + _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx); + } +} + +// Schedule a purge. This is usually delayed to avoid repeated decommit/commit calls. +// Note: assumes we (still) own the area as we may purge immediately +static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) { + mi_assert_internal(arena->blocks_purge != NULL); + const long delay = mi_arena_purge_delay(); + if (delay < 0) return; // is purging allowed at all? + + if (_mi_preloading() || delay == 0) { + // decommit directly + mi_arena_purge(arena, bitmap_idx, blocks, stats); + } + else { + // schedule decommit + mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire); + if (expire != 0) { + mi_atomic_addi64_acq_rel(&arena->purge_expire, delay/10); // add smallish extra delay + } + else { + mi_atomic_storei64_release(&arena->purge_expire, _mi_clock_now() + delay); + } + _mi_bitmap_claim_across(arena->blocks_purge, arena->field_count, blocks, bitmap_idx, NULL); + } +} + +// purge a range of blocks +// return true if the full range was purged. +// assumes we own the area (i.e. blocks_in_use is claimed by us) +static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx, size_t bitlen, size_t purge, mi_stats_t* stats) { + const size_t endidx = startidx + bitlen; + size_t bitidx = startidx; + bool all_purged = false; + while (bitidx < endidx) { + // count consequetive ones in the purge mask + size_t count = 0; + while (bitidx + count < endidx && (purge & ((size_t)1 << (bitidx + count))) != 0) { + count++; + } + if (count > 0) { + // found range to be purged + const mi_bitmap_index_t range_idx = mi_bitmap_index_create(idx, bitidx); + mi_arena_purge(arena, range_idx, count, stats); + if (count == bitlen) { + all_purged = true; + } + } + bitidx += (count+1); // +1 to skip the zero bit (or end) + } + return all_purged; +} + +// returns true if anything was purged +static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi_stats_t* stats) +{ + if (arena->memid.is_pinned || arena->blocks_purge == NULL) return false; + mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire); + if (expire == 0) return false; + if (!force && expire > now) return false; + + // reset expire (if not already set concurrently) + mi_atomic_casi64_strong_acq_rel(&arena->purge_expire, &expire, 0); + + // potential purges scheduled, walk through the bitmap + bool any_purged = false; + bool full_purge = true; + for (size_t i = 0; i < arena->field_count; i++) { + size_t purge = mi_atomic_load_relaxed(&arena->blocks_purge[i]); + if (purge != 0) { + size_t bitidx = 0; + while (bitidx < MI_BITMAP_FIELD_BITS) { + // find consequetive range of ones in the purge mask + size_t bitlen = 0; + while (bitidx + bitlen < MI_BITMAP_FIELD_BITS && (purge & ((size_t)1 << (bitidx + bitlen))) != 0) { + bitlen++; + } + // try to claim the longest range of corresponding in_use bits + const mi_bitmap_index_t bitmap_index = mi_bitmap_index_create(i, bitidx); + while( bitlen > 0 ) { + if (_mi_bitmap_try_claim(arena->blocks_inuse, arena->field_count, bitlen, bitmap_index)) { + break; + } + bitlen--; + } + // actual claimed bits at `in_use` + if (bitlen > 0) { + // read purge again now that we have the in_use bits + purge = mi_atomic_load_acquire(&arena->blocks_purge[i]); + if (!mi_arena_purge_range(arena, i, bitidx, bitlen, purge, stats)) { + full_purge = false; + } + any_purged = true; + // release the claimed `in_use` bits again + _mi_bitmap_unclaim(arena->blocks_inuse, arena->field_count, bitlen, bitmap_index); + } + bitidx += (bitlen+1); // +1 to skip the zero (or end) + } // while bitidx + } // purge != 0 + } + // if not fully purged, make sure to purge again in the future + if (!full_purge) { + const long delay = mi_arena_purge_delay(); + mi_msecs_t expected = 0; + mi_atomic_casi64_strong_acq_rel(&arena->purge_expire,&expected,_mi_clock_now() + delay); + } + return any_purged; +} + +static void mi_arenas_try_purge( bool force, bool visit_all, mi_stats_t* stats ) { + if (_mi_preloading() || mi_arena_purge_delay() <= 0) return; // nothing will be scheduled + + const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count); + if (max_arena == 0) return; + + // allow only one thread to purge at a time + static mi_atomic_guard_t purge_guard; + mi_atomic_guard(&purge_guard) + { + mi_msecs_t now = _mi_clock_now(); + size_t max_purge_count = (visit_all ? max_arena : 1); + for (size_t i = 0; i < max_arena; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]); + if (arena != NULL) { + if (mi_arena_try_purge(arena, now, force, stats)) { + if (max_purge_count <= 1) break; + max_purge_count--; + } + } + } + } +} + + +/* ----------------------------------------------------------- + Arena free +----------------------------------------------------------- */ + +void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memid, mi_stats_t* stats) { + mi_assert_internal(size > 0 && stats != NULL); + mi_assert_internal(committed_size <= size); + if (p==NULL) return; + if (size==0) return; + const bool all_committed = (committed_size == size); + + if (mi_memkind_is_os(memid.memkind)) { + // was a direct OS allocation, pass through + if (!all_committed && committed_size > 0) { + // if partially committed, adjust the committed stats (as `_mi_os_free` will increase decommit by the full size) + _mi_stat_decrease(&stats->committed, committed_size); + } + _mi_os_free(p, size, memid, stats); + } + else if (memid.memkind == MI_MEM_ARENA) { + // allocated in an arena + size_t arena_idx; + size_t bitmap_idx; + mi_arena_memid_indices(memid, &arena_idx, &bitmap_idx); + mi_assert_internal(arena_idx < MI_MAX_ARENAS); + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t,&mi_arenas[arena_idx]); + mi_assert_internal(arena != NULL); + const size_t blocks = mi_block_count_of_size(size); + + // checks + if (arena == NULL) { + _mi_error_message(EINVAL, "trying to free from non-existent arena: %p, size %zu, memid: 0x%zx\n", p, size, memid); + return; + } + mi_assert_internal(arena->field_count > mi_bitmap_index_field(bitmap_idx)); + if (arena->field_count <= mi_bitmap_index_field(bitmap_idx)) { + _mi_error_message(EINVAL, "trying to free from non-existent arena block: %p, size %zu, memid: 0x%zx\n", p, size, memid); + return; + } + + // need to set all memory to undefined as some parts may still be marked as no_access (like padding etc.) + mi_track_mem_undefined(p,size); + + // potentially decommit + if (arena->memid.is_pinned || arena->blocks_committed == NULL) { + mi_assert_internal(all_committed); + } + else { + mi_assert_internal(arena->blocks_committed != NULL); + mi_assert_internal(arena->blocks_purge != NULL); + + if (!all_committed) { + // mark the entire range as no longer committed (so we recommit the full range when re-using) + _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx); + mi_track_mem_noaccess(p,size); + if (committed_size > 0) { + // if partially committed, adjust the committed stats (is it will be recommitted when re-using) + // in the delayed purge, we now need to not count a decommit if the range is not marked as committed. + _mi_stat_decrease(&stats->committed, committed_size); + } + // note: if not all committed, it may be that the purge will reset/decommit the entire range + // that contains already decommitted parts. Since purge consistently uses reset or decommit that + // works (as we should never reset decommitted parts). + } + // (delay) purge the entire range + mi_arena_schedule_purge(arena, bitmap_idx, blocks, stats); + } + + // and make it available to others again + bool all_inuse = _mi_bitmap_unclaim_across(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx); + if (!all_inuse) { + _mi_error_message(EAGAIN, "trying to free an already freed arena block: %p, size %zu\n", p, size); + return; + }; + } + else { + // arena was none, external, or static; nothing to do + mi_assert_internal(memid.memkind < MI_MEM_OS); + } + + // purge expired decommits + mi_arenas_try_purge(false, false, stats); +} + +// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit` +// for dynamic libraries that are unloaded and need to release all their allocated memory. +static void mi_arenas_unsafe_destroy(void) { + const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count); + size_t new_max_arena = 0; + for (size_t i = 0; i < max_arena; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]); + if (arena != NULL) { + if (arena->start != NULL && mi_memkind_is_os(arena->memid.memkind)) { + mi_atomic_store_ptr_release(mi_arena_t, &mi_arenas[i], NULL); + _mi_os_free(arena->start, mi_arena_size(arena), arena->memid, &_mi_stats_main); + } + else { + new_max_arena = i; + } + mi_arena_meta_free(arena, arena->meta_memid, arena->meta_size, &_mi_stats_main); + } + } + + // try to lower the max arena. + size_t expected = max_arena; + mi_atomic_cas_strong_acq_rel(&mi_arena_count, &expected, new_max_arena); +} + +// Purge the arenas; if `force_purge` is true, amenable parts are purged even if not yet expired +void _mi_arena_collect(bool force_purge, mi_stats_t* stats) { + mi_arenas_try_purge(force_purge, true /* visit all */, stats); +} + +// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit` +// for dynamic libraries that are unloaded and need to release all their allocated memory. +void _mi_arena_unsafe_destroy_all(mi_stats_t* stats) { + mi_arenas_unsafe_destroy(); + _mi_arena_collect(true /* force purge */, stats); // purge non-owned arenas +} + +// Is a pointer inside any of our arenas? +bool _mi_arena_contains(const void* p) { + const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count); + for (size_t i = 0; i < max_arena; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]); + if (arena != NULL && arena->start <= (const uint8_t*)p && arena->start + mi_arena_block_size(arena->block_count) > (const uint8_t*)p) { + return true; + } + } + return false; +} + + +/* ----------------------------------------------------------- + Add an arena. +----------------------------------------------------------- */ + +static bool mi_arena_add(mi_arena_t* arena, mi_arena_id_t* arena_id) { + mi_assert_internal(arena != NULL); + mi_assert_internal((uintptr_t)mi_atomic_load_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0); + mi_assert_internal(arena->block_count > 0); + if (arena_id != NULL) { *arena_id = -1; } + + size_t i = mi_atomic_increment_acq_rel(&mi_arena_count); + if (i >= MI_MAX_ARENAS) { + mi_atomic_decrement_acq_rel(&mi_arena_count); + return false; + } + arena->id = mi_arena_id_create(i); + mi_atomic_store_ptr_release(mi_arena_t,&mi_arenas[i], arena); + if (arena_id != NULL) { *arena_id = arena->id; } + return true; +} + +static bool mi_manage_os_memory_ex2(void* start, size_t size, bool is_large, int numa_node, bool exclusive, mi_memid_t memid, mi_arena_id_t* arena_id) mi_attr_noexcept +{ + if (arena_id != NULL) *arena_id = _mi_arena_id_none(); + if (size < MI_ARENA_BLOCK_SIZE) return false; + + if (is_large) { + mi_assert_internal(memid.initially_committed && memid.is_pinned); + } + + const size_t bcount = size / MI_ARENA_BLOCK_SIZE; + const size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS); + const size_t bitmaps = (memid.is_pinned ? 2 : 4); + const size_t asize = sizeof(mi_arena_t) + (bitmaps*fields*sizeof(mi_bitmap_field_t)); + mi_memid_t meta_memid; + mi_arena_t* arena = (mi_arena_t*)mi_arena_meta_zalloc(asize, &meta_memid, &_mi_stats_main); // TODO: can we avoid allocating from the OS? + if (arena == NULL) return false; + + // already zero'd due to os_alloc + // _mi_memzero(arena, asize); + arena->id = _mi_arena_id_none(); + arena->memid = memid; + arena->exclusive = exclusive; + arena->meta_size = asize; + arena->meta_memid = meta_memid; + arena->block_count = bcount; + arena->field_count = fields; + arena->start = (uint8_t*)start; + arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1) + arena->is_large = is_large; + arena->purge_expire = 0; + arena->search_idx = 0; + arena->blocks_dirty = &arena->blocks_inuse[fields]; // just after inuse bitmap + arena->blocks_committed = (arena->memid.is_pinned ? NULL : &arena->blocks_inuse[2*fields]); // just after dirty bitmap + arena->blocks_purge = (arena->memid.is_pinned ? NULL : &arena->blocks_inuse[3*fields]); // just after committed bitmap + // initialize committed bitmap? + if (arena->blocks_committed != NULL && arena->memid.initially_committed) { + memset((void*)arena->blocks_committed, 0xFF, fields*sizeof(mi_bitmap_field_t)); // cast to void* to avoid atomic warning + } + + // and claim leftover blocks if needed (so we never allocate there) + ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount; + mi_assert_internal(post >= 0); + if (post > 0) { + // don't use leftover bits at the end + mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post); + _mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL); + } + return mi_arena_add(arena, arena_id); + +} + +bool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept { + mi_memid_t memid = _mi_memid_create(MI_MEM_EXTERNAL); + memid.initially_committed = is_committed; + memid.initially_zero = is_zero; + memid.is_pinned = is_large; + return mi_manage_os_memory_ex2(start,size,is_large,numa_node,exclusive,memid, arena_id); +} + +// Reserve a range of regular OS memory +int mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept { + if (arena_id != NULL) *arena_id = _mi_arena_id_none(); + size = _mi_align_up(size, MI_ARENA_BLOCK_SIZE); // at least one block + mi_memid_t memid; + void* start = _mi_os_alloc_aligned(size, MI_SEGMENT_ALIGN, commit, allow_large, &memid, &_mi_stats_main); + if (start == NULL) return ENOMEM; + const bool is_large = memid.is_pinned; // todo: use separate is_large field? + if (!mi_manage_os_memory_ex2(start, size, is_large, -1 /* numa node */, exclusive, memid, arena_id)) { + _mi_os_free_ex(start, size, commit, memid, &_mi_stats_main); + _mi_verbose_message("failed to reserve %zu k memory\n", _mi_divide_up(size, 1024)); + return ENOMEM; + } + _mi_verbose_message("reserved %zu KiB memory%s\n", _mi_divide_up(size, 1024), is_large ? " (in large os pages)" : ""); + return 0; +} + + +// Manage a range of regular OS memory +bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept { + return mi_manage_os_memory_ex(start, size, is_committed, is_large, is_zero, numa_node, false /* exclusive? */, NULL); +} + +// Reserve a range of regular OS memory +int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept { + return mi_reserve_os_memory_ex(size, commit, allow_large, false, NULL); +} + + +/* ----------------------------------------------------------- + Debugging +----------------------------------------------------------- */ + +static size_t mi_debug_show_bitmap(const char* prefix, mi_bitmap_field_t* fields, size_t field_count ) { + size_t inuse_count = 0; + for (size_t i = 0; i < field_count; i++) { + char buf[MI_BITMAP_FIELD_BITS + 1]; + uintptr_t field = mi_atomic_load_relaxed(&fields[i]); + for (size_t bit = 0; bit < MI_BITMAP_FIELD_BITS; bit++) { + bool inuse = ((((uintptr_t)1 << bit) & field) != 0); + if (inuse) inuse_count++; + buf[MI_BITMAP_FIELD_BITS - 1 - bit] = (inuse ? 'x' : '.'); + } + buf[MI_BITMAP_FIELD_BITS] = 0; + _mi_verbose_message("%s%s\n", prefix, buf); + } + return inuse_count; +} + +void mi_debug_show_arenas(void) mi_attr_noexcept { + size_t max_arenas = mi_atomic_load_relaxed(&mi_arena_count); + for (size_t i = 0; i < max_arenas; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]); + if (arena == NULL) break; + size_t inuse_count = 0; + _mi_verbose_message("arena %zu: %zu blocks with %zu fields\n", i, arena->block_count, arena->field_count); + inuse_count += mi_debug_show_bitmap(" ", arena->blocks_inuse, arena->field_count); + _mi_verbose_message(" blocks in use ('x'): %zu\n", inuse_count); + } +} + + +/* ----------------------------------------------------------- + Reserve a huge page arena. +----------------------------------------------------------- */ +// reserve at a specific numa node +int mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept { + if (arena_id != NULL) *arena_id = -1; + if (pages==0) return 0; + if (numa_node < -1) numa_node = -1; + if (numa_node >= 0) numa_node = numa_node % _mi_os_numa_node_count(); + size_t hsize = 0; + size_t pages_reserved = 0; + mi_memid_t memid; + void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize, &memid); + if (p==NULL || pages_reserved==0) { + _mi_warning_message("failed to reserve %zu GiB huge pages\n", pages); + return ENOMEM; + } + _mi_verbose_message("numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\n", numa_node, pages_reserved, pages); + + if (!mi_manage_os_memory_ex2(p, hsize, true, numa_node, exclusive, memid, arena_id)) { + _mi_os_free(p, hsize, memid, &_mi_stats_main); + return ENOMEM; + } + return 0; +} + +int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept { + return mi_reserve_huge_os_pages_at_ex(pages, numa_node, timeout_msecs, false, NULL); +} + +// reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected) +int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept { + if (pages == 0) return 0; + + // pages per numa node + size_t numa_count = (numa_nodes > 0 ? numa_nodes : _mi_os_numa_node_count()); + if (numa_count <= 0) numa_count = 1; + const size_t pages_per = pages / numa_count; + const size_t pages_mod = pages % numa_count; + const size_t timeout_per = (timeout_msecs==0 ? 0 : (timeout_msecs / numa_count) + 50); + + // reserve evenly among numa nodes + for (size_t numa_node = 0; numa_node < numa_count && pages > 0; numa_node++) { + size_t node_pages = pages_per; // can be 0 + if (numa_node < pages_mod) node_pages++; + int err = mi_reserve_huge_os_pages_at(node_pages, (int)numa_node, timeout_per); + if (err) return err; + if (pages < node_pages) { + pages = 0; + } + else { + pages -= node_pages; + } + } + + return 0; +} + +int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept { + MI_UNUSED(max_secs); + _mi_warning_message("mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\n"); + if (pages_reserved != NULL) *pages_reserved = 0; + int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0)); + if (err==0 && pages_reserved!=NULL) *pages_reserved = pages; + return err; +} + diff --git a/lib/Utils.Memory/mimalloc/src/bitmap.c b/lib/Utils.Memory/mimalloc/src/bitmap.c new file mode 100644 index 0000000..a13dbe1 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/bitmap.c @@ -0,0 +1,432 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +Concurrent bitmap that can set/reset sequences of bits atomically, +represeted as an array of fields where each field is a machine word (`size_t`) + +There are two api's; the standard one cannot have sequences that cross +between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS). + +The `_across` postfixed functions do allow sequences that can cross over +between the fields. (This is used in arena allocation) +---------------------------------------------------------------------------- */ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "bitmap.h" + +/* ----------------------------------------------------------- + Bitmap definition +----------------------------------------------------------- */ + +// The bit mask for a given number of blocks at a specified bit index. +static inline size_t mi_bitmap_mask_(size_t count, size_t bitidx) { + mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS); + mi_assert_internal(count > 0); + if (count >= MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL; + if (count == 0) return 0; + return ((((size_t)1 << count) - 1) << bitidx); +} + + +/* ----------------------------------------------------------- + Claim a bit sequence atomically +----------------------------------------------------------- */ + +// Try to atomically claim a sequence of `count` bits in a single +// field at `idx` in `bitmap`. Returns `true` on success. +inline bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx) +{ + mi_assert_internal(bitmap_idx != NULL); + mi_assert_internal(count <= MI_BITMAP_FIELD_BITS); + mi_assert_internal(count > 0); + mi_bitmap_field_t* field = &bitmap[idx]; + size_t map = mi_atomic_load_relaxed(field); + if (map==MI_BITMAP_FIELD_FULL) return false; // short cut + + // search for 0-bit sequence of length count + const size_t mask = mi_bitmap_mask_(count, 0); + const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count; + +#ifdef MI_HAVE_FAST_BITSCAN + size_t bitidx = mi_ctz(~map); // quickly find the first zero bit if possible +#else + size_t bitidx = 0; // otherwise start at 0 +#endif + size_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx + + // scan linearly for a free range of zero bits + while (bitidx <= bitidx_max) { + const size_t mapm = (map & m); + if (mapm == 0) { // are the mask bits free at bitidx? + mi_assert_internal((m >> bitidx) == mask); // no overflow? + const size_t newmap = (map | m); + mi_assert_internal((newmap^map) >> bitidx == mask); + if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { // TODO: use weak cas here? + // no success, another thread claimed concurrently.. keep going (with updated `map`) + continue; + } + else { + // success, we claimed the bits! + *bitmap_idx = mi_bitmap_index_create(idx, bitidx); + return true; + } + } + else { + // on to the next bit range +#ifdef MI_HAVE_FAST_BITSCAN + mi_assert_internal(mapm != 0); + const size_t shift = (count == 1 ? 1 : (MI_INTPTR_BITS - mi_clz(mapm) - bitidx)); + mi_assert_internal(shift > 0 && shift <= count); +#else + const size_t shift = 1; +#endif + bitidx += shift; + m <<= shift; + } + } + // no bits found + return false; +} + +// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success. +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +// `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields. +bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) { + size_t idx = start_field_idx; + for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) { + if (idx >= bitmap_fields) { idx = 0; } // wrap + if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + return true; + } + } + return false; +} + +// Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled +bool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, + const size_t start_field_idx, const size_t count, + mi_bitmap_pred_fun_t pred_fun, void* pred_arg, + mi_bitmap_index_t* bitmap_idx) { + size_t idx = start_field_idx; + for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) { + if (idx >= bitmap_fields) idx = 0; // wrap + if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + if (pred_fun == NULL || pred_fun(*bitmap_idx, pred_arg)) { + return true; + } + // predicate returned false, unclaim and look further + _mi_bitmap_unclaim(bitmap, bitmap_fields, count, *bitmap_idx); + } + } + return false; +} + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + // mi_assert_internal((bitmap[idx] & mask) == mask); + const size_t prev = mi_atomic_and_acq_rel(&bitmap[idx], ~mask); + return ((prev & mask) == mask); +} + + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0); + size_t prev = mi_atomic_or_acq_rel(&bitmap[idx], mask); + if (any_zero != NULL) { *any_zero = ((prev & mask) != mask); } + return ((prev & mask) == 0); +} + +// Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one. +static bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + const size_t field = mi_atomic_load_relaxed(&bitmap[idx]); + if (any_ones != NULL) { *any_ones = ((field & mask) != 0); } + return ((field & mask) == mask); +} + +// Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically. +// Returns `true` if successful when all previous `count` bits were 0. +bool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + size_t expected = mi_atomic_load_relaxed(&bitmap[idx]); + do { + if ((expected & mask) != 0) return false; + } + while (!mi_atomic_cas_strong_acq_rel(&bitmap[idx], &expected, expected | mask)); + mi_assert_internal((expected & mask) == 0); + return true; +} + + +bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL); +} + +bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + bool any_ones; + mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones); + return any_ones; +} + + +//-------------------------------------------------------------------------- +// the `_across` functions work on bitmaps where sequences can cross over +// between the fields. This is used in arena allocation +//-------------------------------------------------------------------------- + +// Try to atomically claim a sequence of `count` bits starting from the field +// at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success. +// Only needs to consider crossing into the next fields (see `mi_bitmap_try_find_from_claim_across`) +static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx) +{ + mi_assert_internal(bitmap_idx != NULL); + + // check initial trailing zeros + mi_bitmap_field_t* field = &bitmap[idx]; + size_t map = mi_atomic_load_relaxed(field); + const size_t initial = mi_clz(map); // count of initial zeros starting at idx + mi_assert_internal(initial <= MI_BITMAP_FIELD_BITS); + if (initial == 0) return false; + if (initial >= count) return _mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx); // no need to cross fields (this case won't happen for us) + if (_mi_divide_up(count - initial, MI_BITMAP_FIELD_BITS) >= (bitmap_fields - idx)) return false; // not enough entries + + // scan ahead + size_t found = initial; + size_t mask = 0; // mask bits for the final field + while(found < count) { + field++; + map = mi_atomic_load_relaxed(field); + const size_t mask_bits = (found + MI_BITMAP_FIELD_BITS <= count ? MI_BITMAP_FIELD_BITS : (count - found)); + mi_assert_internal(mask_bits > 0 && mask_bits <= MI_BITMAP_FIELD_BITS); + mask = mi_bitmap_mask_(mask_bits, 0); + if ((map & mask) != 0) return false; // some part is already claimed + found += mask_bits; + } + mi_assert_internal(field < &bitmap[bitmap_fields]); + + // we found a range of contiguous zeros up to the final field; mask contains mask in the final field + // now try to claim the range atomically + mi_bitmap_field_t* const final_field = field; + const size_t final_mask = mask; + mi_bitmap_field_t* const initial_field = &bitmap[idx]; + const size_t initial_idx = MI_BITMAP_FIELD_BITS - initial; + const size_t initial_mask = mi_bitmap_mask_(initial, initial_idx); + + // initial field + size_t newmap; + field = initial_field; + map = mi_atomic_load_relaxed(field); + do { + newmap = (map | initial_mask); + if ((map & initial_mask) != 0) { goto rollback; }; + } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)); + + // intermediate fields + while (++field < final_field) { + newmap = MI_BITMAP_FIELD_FULL; + map = 0; + if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { goto rollback; } + } + + // final field + mi_assert_internal(field == final_field); + map = mi_atomic_load_relaxed(field); + do { + newmap = (map | final_mask); + if ((map & final_mask) != 0) { goto rollback; } + } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)); + + // claimed! + *bitmap_idx = mi_bitmap_index_create(idx, initial_idx); + return true; + +rollback: + // roll back intermediate fields + // (we just failed to claim `field` so decrement first) + while (--field > initial_field) { + newmap = 0; + map = MI_BITMAP_FIELD_FULL; + mi_assert_internal(mi_atomic_load_relaxed(field) == map); + mi_atomic_store_release(field, newmap); + } + if (field == initial_field) { // (if we failed on the initial field, `field + 1 == initial_field`) + map = mi_atomic_load_relaxed(field); + do { + mi_assert_internal((map & initial_mask) == initial_mask); + newmap = (map & ~initial_mask); + } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)); + } + // retry? (we make a recursive call instead of goto to be able to use const declarations) + if (retries <= 2) { + return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx); + } + else { + return false; + } +} + + +// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success. +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) { + mi_assert_internal(count > 0); + if (count <= 2) { + // we don't bother with crossover fields for small counts + return _mi_bitmap_try_find_from_claim(bitmap, bitmap_fields, start_field_idx, count, bitmap_idx); + } + + // visit the fields + size_t idx = start_field_idx; + for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) { + if (idx >= bitmap_fields) { idx = 0; } // wrap + // first try to claim inside a field + if (count <= MI_BITMAP_FIELD_BITS) { + if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + return true; + } + } + // if that fails, then try to claim across fields + if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx)) { + return true; + } + } + return false; +} + +// Helper for masks across fields; returns the mid count, post_mask may be 0 +static size_t mi_bitmap_mask_across(mi_bitmap_index_t bitmap_idx, size_t bitmap_fields, size_t count, size_t* pre_mask, size_t* mid_mask, size_t* post_mask) { + MI_UNUSED(bitmap_fields); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + if mi_likely(bitidx + count <= MI_BITMAP_FIELD_BITS) { + *pre_mask = mi_bitmap_mask_(count, bitidx); + *mid_mask = 0; + *post_mask = 0; + mi_assert_internal(mi_bitmap_index_field(bitmap_idx) < bitmap_fields); + return 0; + } + else { + const size_t pre_bits = MI_BITMAP_FIELD_BITS - bitidx; + mi_assert_internal(pre_bits < count); + *pre_mask = mi_bitmap_mask_(pre_bits, bitidx); + count -= pre_bits; + const size_t mid_count = (count / MI_BITMAP_FIELD_BITS); + *mid_mask = MI_BITMAP_FIELD_FULL; + count %= MI_BITMAP_FIELD_BITS; + *post_mask = (count==0 ? 0 : mi_bitmap_mask_(count, 0)); + mi_assert_internal(mi_bitmap_index_field(bitmap_idx) + mid_count + (count==0 ? 0 : 1) < bitmap_fields); + return mid_count; + } +} + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + size_t idx = mi_bitmap_index_field(bitmap_idx); + size_t pre_mask; + size_t mid_mask; + size_t post_mask; + size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask); + bool all_one = true; + mi_bitmap_field_t* field = &bitmap[idx]; + size_t prev = mi_atomic_and_acq_rel(field++, ~pre_mask); // clear first part + if ((prev & pre_mask) != pre_mask) all_one = false; + while(mid_count-- > 0) { + prev = mi_atomic_and_acq_rel(field++, ~mid_mask); // clear mid part + if ((prev & mid_mask) != mid_mask) all_one = false; + } + if (post_mask!=0) { + prev = mi_atomic_and_acq_rel(field, ~post_mask); // clear end part + if ((prev & post_mask) != post_mask) all_one = false; + } + return all_one; +} + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero) { + size_t idx = mi_bitmap_index_field(bitmap_idx); + size_t pre_mask; + size_t mid_mask; + size_t post_mask; + size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask); + bool all_zero = true; + bool any_zero = false; + _Atomic(size_t)*field = &bitmap[idx]; + size_t prev = mi_atomic_or_acq_rel(field++, pre_mask); + if ((prev & pre_mask) != 0) all_zero = false; + if ((prev & pre_mask) != pre_mask) any_zero = true; + while (mid_count-- > 0) { + prev = mi_atomic_or_acq_rel(field++, mid_mask); + if ((prev & mid_mask) != 0) all_zero = false; + if ((prev & mid_mask) != mid_mask) any_zero = true; + } + if (post_mask!=0) { + prev = mi_atomic_or_acq_rel(field, post_mask); + if ((prev & post_mask) != 0) all_zero = false; + if ((prev & post_mask) != post_mask) any_zero = true; + } + if (pany_zero != NULL) { *pany_zero = any_zero; } + return all_zero; +} + + +// Returns `true` if all `count` bits were 1. +// `any_ones` is `true` if there was at least one bit set to one. +static bool mi_bitmap_is_claimedx_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_ones) { + size_t idx = mi_bitmap_index_field(bitmap_idx); + size_t pre_mask; + size_t mid_mask; + size_t post_mask; + size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask); + bool all_ones = true; + bool any_ones = false; + mi_bitmap_field_t* field = &bitmap[idx]; + size_t prev = mi_atomic_load_relaxed(field++); + if ((prev & pre_mask) != pre_mask) all_ones = false; + if ((prev & pre_mask) != 0) any_ones = true; + while (mid_count-- > 0) { + prev = mi_atomic_load_relaxed(field++); + if ((prev & mid_mask) != mid_mask) all_ones = false; + if ((prev & mid_mask) != 0) any_ones = true; + } + if (post_mask!=0) { + prev = mi_atomic_load_relaxed(field); + if ((prev & post_mask) != post_mask) all_ones = false; + if ((prev & post_mask) != 0) any_ones = true; + } + if (pany_ones != NULL) { *pany_ones = any_ones; } + return all_ones; +} + +bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + return mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, NULL); +} + +bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + bool any_ones; + mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, &any_ones); + return any_ones; +} diff --git a/lib/Utils.Memory/mimalloc/src/bitmap.h b/lib/Utils.Memory/mimalloc/src/bitmap.h new file mode 100644 index 0000000..0a765c7 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/bitmap.h @@ -0,0 +1,115 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +Concurrent bitmap that can set/reset sequences of bits atomically, +represeted as an array of fields where each field is a machine word (`size_t`) + +There are two api's; the standard one cannot have sequences that cross +between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS). +(this is used in region allocation) + +The `_across` postfixed functions do allow sequences that can cross over +between the fields. (This is used in arena allocation) +---------------------------------------------------------------------------- */ +#pragma once +#ifndef MI_BITMAP_H +#define MI_BITMAP_H + +/* ----------------------------------------------------------- + Bitmap definition +----------------------------------------------------------- */ + +#define MI_BITMAP_FIELD_BITS (8*MI_SIZE_SIZE) +#define MI_BITMAP_FIELD_FULL (~((size_t)0)) // all bits set + +// An atomic bitmap of `size_t` fields +typedef _Atomic(size_t) mi_bitmap_field_t; +typedef mi_bitmap_field_t* mi_bitmap_t; + +// A bitmap index is the index of the bit in a bitmap. +typedef size_t mi_bitmap_index_t; + +// Create a bit index. +static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) { + mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS); + return (idx*MI_BITMAP_FIELD_BITS) + bitidx; +} + +// Create a bit index. +static inline mi_bitmap_index_t mi_bitmap_index_create_from_bit(size_t full_bitidx) { + return mi_bitmap_index_create(full_bitidx / MI_BITMAP_FIELD_BITS, full_bitidx % MI_BITMAP_FIELD_BITS); +} + +// Get the field index from a bit index. +static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) { + return (bitmap_idx / MI_BITMAP_FIELD_BITS); +} + +// Get the bit index in a bitmap field +static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) { + return (bitmap_idx % MI_BITMAP_FIELD_BITS); +} + +// Get the full bit index +static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) { + return bitmap_idx; +} + +/* ----------------------------------------------------------- + Claim a bit sequence atomically +----------------------------------------------------------- */ + +// Try to atomically claim a sequence of `count` bits in a single +// field at `idx` in `bitmap`. Returns `true` on success. +bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx); + +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields. +bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx); + +// Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled +typedef bool (mi_cdecl *mi_bitmap_pred_fun_t)(mi_bitmap_index_t bitmap_idx, void* pred_arg); +bool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_pred_fun_t pred_fun, void* pred_arg, mi_bitmap_index_t* bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +// Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically. +// Returns `true` if successful when all previous `count` bits were 0. +bool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero); + +bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); +bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + + +//-------------------------------------------------------------------------- +// the `_across` functions work on bitmaps where sequences can cross over +// between the fields. This is used in arena allocation +//-------------------------------------------------------------------------- + +// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success. +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero); + +bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); +bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +#endif diff --git a/lib/Utils.Memory/mimalloc/src/heap.c b/lib/Utils.Memory/mimalloc/src/heap.c new file mode 100644 index 0000000..58520dd --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/heap.c @@ -0,0 +1,626 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" // mi_prim_get_default_heap + +#include <string.h> // memset, memcpy + +#if defined(_MSC_VER) && (_MSC_VER < 1920) +#pragma warning(disable:4204) // non-constant aggregate initializer +#endif + +/* ----------------------------------------------------------- + Helpers +----------------------------------------------------------- */ + +// return `true` if ok, `false` to break +typedef bool (heap_page_visitor_fun)(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2); + +// Visit all pages in a heap; returns `false` if break was called. +static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void* arg1, void* arg2) +{ + if (heap==NULL || heap->page_count==0) return 0; + + // visit all pages + #if MI_DEBUG>1 + size_t total = heap->page_count; + size_t count = 0; + #endif + + for (size_t i = 0; i <= MI_BIN_FULL; i++) { + mi_page_queue_t* pq = &heap->pages[i]; + mi_page_t* page = pq->first; + while(page != NULL) { + mi_page_t* next = page->next; // save next in case the page gets removed from the queue + mi_assert_internal(mi_page_heap(page) == heap); + #if MI_DEBUG>1 + count++; + #endif + if (!fn(heap, pq, page, arg1, arg2)) return false; + page = next; // and continue + } + } + mi_assert_internal(count == total); + return true; +} + + +#if MI_DEBUG>=2 +static bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + MI_UNUSED(arg1); + MI_UNUSED(arg2); + MI_UNUSED(pq); + mi_assert_internal(mi_page_heap(page) == heap); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_internal(segment->thread_id == heap->thread_id); + mi_assert_expensive(_mi_page_is_valid(page)); + return true; +} +#endif +#if MI_DEBUG>=3 +static bool mi_heap_is_valid(mi_heap_t* heap) { + mi_assert_internal(heap!=NULL); + mi_heap_visit_pages(heap, &mi_heap_page_is_valid, NULL, NULL); + return true; +} +#endif + + + + +/* ----------------------------------------------------------- + "Collect" pages by migrating `local_free` and `thread_free` + lists and freeing empty pages. This is done when a thread + stops (and in that case abandons pages if there are still + blocks alive) +----------------------------------------------------------- */ + +typedef enum mi_collect_e { + MI_NORMAL, + MI_FORCE, + MI_ABANDON +} mi_collect_t; + + +static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) { + MI_UNUSED(arg2); + MI_UNUSED(heap); + mi_assert_internal(mi_heap_page_is_valid(heap, pq, page, NULL, NULL)); + mi_collect_t collect = *((mi_collect_t*)arg_collect); + _mi_page_free_collect(page, collect >= MI_FORCE); + if (mi_page_all_free(page)) { + // no more used blocks, free the page. + // note: this will free retired pages as well. + _mi_page_free(page, pq, collect >= MI_FORCE); + } + else if (collect == MI_ABANDON) { + // still used blocks but the thread is done; abandon the page + _mi_page_abandon(page, pq); + } + return true; // don't break +} + +static bool mi_heap_page_never_delayed_free(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + MI_UNUSED(arg1); + MI_UNUSED(arg2); + MI_UNUSED(heap); + MI_UNUSED(pq); + _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); + return true; // don't break +} + +static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect) +{ + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + + const bool force = collect >= MI_FORCE; + _mi_deferred_free(heap, force); + + // note: never reclaim on collect but leave it to threads that need storage to reclaim + const bool force_main = + #ifdef NDEBUG + collect == MI_FORCE + #else + collect >= MI_FORCE + #endif + && _mi_is_main_thread() && mi_heap_is_backing(heap) && !heap->no_reclaim; + + if (force_main) { + // the main thread is abandoned (end-of-program), try to reclaim all abandoned segments. + // if all memory is freed by now, all segments should be freed. + _mi_abandoned_reclaim_all(heap, &heap->tld->segments); + } + + // if abandoning, mark all pages to no longer add to delayed_free + if (collect == MI_ABANDON) { + mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, NULL, NULL); + } + + // free all current thread delayed blocks. + // (if abandoning, after this there are no more thread-delayed references into the pages.) + _mi_heap_delayed_free_all(heap); + + // collect retired pages + _mi_heap_collect_retired(heap, force); + + // collect all pages owned by this thread + mi_heap_visit_pages(heap, &mi_heap_page_collect, &collect, NULL); + mi_assert_internal( collect != MI_ABANDON || mi_atomic_load_ptr_acquire(mi_block_t,&heap->thread_delayed_free) == NULL ); + + // collect abandoned segments (in particular, purge expired parts of segments in the abandoned segment list) + // note: forced purge can be quite expensive if many threads are created/destroyed so we do not force on abandonment + _mi_abandoned_collect(heap, collect == MI_FORCE /* force? */, &heap->tld->segments); + + // collect segment local caches + if (force) { + _mi_segment_thread_collect(&heap->tld->segments); + } + + // collect regions on program-exit (or shared library unload) + if (force && _mi_is_main_thread() && mi_heap_is_backing(heap)) { + _mi_thread_data_collect(); // collect thread data cache + _mi_arena_collect(true /* force purge */, &heap->tld->stats); + } +} + +void _mi_heap_collect_abandon(mi_heap_t* heap) { + mi_heap_collect_ex(heap, MI_ABANDON); +} + +void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept { + mi_heap_collect_ex(heap, (force ? MI_FORCE : MI_NORMAL)); +} + +void mi_collect(bool force) mi_attr_noexcept { + mi_heap_collect(mi_prim_get_default_heap(), force); +} + + +/* ----------------------------------------------------------- + Heap new +----------------------------------------------------------- */ + +mi_heap_t* mi_heap_get_default(void) { + mi_thread_init(); + return mi_prim_get_default_heap(); +} + +static bool mi_heap_is_default(const mi_heap_t* heap) { + return (heap == mi_prim_get_default_heap()); +} + + +mi_heap_t* mi_heap_get_backing(void) { + mi_heap_t* heap = mi_heap_get_default(); + mi_assert_internal(heap!=NULL); + mi_heap_t* bheap = heap->tld->heap_backing; + mi_assert_internal(bheap!=NULL); + mi_assert_internal(bheap->thread_id == _mi_thread_id()); + return bheap; +} + +mi_decl_nodiscard mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id) { + mi_heap_t* bheap = mi_heap_get_backing(); + mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t); // todo: OS allocate in secure mode? + if (heap == NULL) return NULL; + _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(mi_heap_t)); + heap->tld = bheap->tld; + heap->thread_id = _mi_thread_id(); + heap->arena_id = arena_id; + _mi_random_split(&bheap->random, &heap->random); + heap->cookie = _mi_heap_random_next(heap) | 1; + heap->keys[0] = _mi_heap_random_next(heap); + heap->keys[1] = _mi_heap_random_next(heap); + heap->no_reclaim = true; // don't reclaim abandoned pages or otherwise destroy is unsafe + // push on the thread local heaps list + heap->next = heap->tld->heaps; + heap->tld->heaps = heap; + return heap; +} + +mi_decl_nodiscard mi_heap_t* mi_heap_new(void) { + return mi_heap_new_in_arena(_mi_arena_id_none()); +} + +bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid) { + return _mi_arena_memid_is_suitable(memid, heap->arena_id); +} + +uintptr_t _mi_heap_random_next(mi_heap_t* heap) { + return _mi_random_next(&heap->random); +} + +// zero out the page queues +static void mi_heap_reset_pages(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + mi_assert_internal(mi_heap_is_initialized(heap)); + // TODO: copy full empty heap instead? + memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct)); + _mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages)); + heap->thread_delayed_free = NULL; + heap->page_count = 0; +} + +// called from `mi_heap_destroy` and `mi_heap_delete` to free the internal heap resources. +static void mi_heap_free(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert_internal(mi_heap_is_initialized(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + if (mi_heap_is_backing(heap)) return; // dont free the backing heap + + // reset default + if (mi_heap_is_default(heap)) { + _mi_heap_set_default_direct(heap->tld->heap_backing); + } + + // remove ourselves from the thread local heaps list + // linear search but we expect the number of heaps to be relatively small + mi_heap_t* prev = NULL; + mi_heap_t* curr = heap->tld->heaps; + while (curr != heap && curr != NULL) { + prev = curr; + curr = curr->next; + } + mi_assert_internal(curr == heap); + if (curr == heap) { + if (prev != NULL) { prev->next = heap->next; } + else { heap->tld->heaps = heap->next; } + } + mi_assert_internal(heap->tld->heaps != NULL); + + // and free the used memory + mi_free(heap); +} + + +/* ----------------------------------------------------------- + Heap destroy +----------------------------------------------------------- */ + +static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + MI_UNUSED(arg1); + MI_UNUSED(arg2); + MI_UNUSED(heap); + MI_UNUSED(pq); + + // ensure no more thread_delayed_free will be added + _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); + + // stats + const size_t bsize = mi_page_block_size(page); + if (bsize > MI_MEDIUM_OBJ_SIZE_MAX) { + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); + } + } +#if (MI_STAT) + _mi_page_free_collect(page, false); // update used count + const size_t inuse = page->used; + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, normal, bsize * inuse); +#if (MI_STAT>1) + mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], inuse); +#endif + } + mi_heap_stat_decrease(heap, malloc, bsize * inuse); // todo: off for aligned blocks... +#endif + + /// pretend it is all free now + mi_assert_internal(mi_page_thread_free(page) == NULL); + page->used = 0; + + // and free the page + // mi_page_free(page,false); + page->next = NULL; + page->prev = NULL; + _mi_segment_page_free(page,false /* no force? */, &heap->tld->segments); + + return true; // keep going +} + +void _mi_heap_destroy_pages(mi_heap_t* heap) { + mi_heap_visit_pages(heap, &_mi_heap_page_destroy, NULL, NULL); + mi_heap_reset_pages(heap); +} + +#if MI_TRACK_HEAP_DESTROY +static bool mi_cdecl mi_heap_track_block_free(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) { + MI_UNUSED(heap); MI_UNUSED(area); MI_UNUSED(arg); MI_UNUSED(block_size); + mi_track_free_size(block,mi_usable_size(block)); + return true; +} +#endif + +void mi_heap_destroy(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + mi_assert(heap->no_reclaim); + mi_assert_expensive(mi_heap_is_valid(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + if (!heap->no_reclaim) { + // don't free in case it may contain reclaimed pages + mi_heap_delete(heap); + } + else { + // track all blocks as freed + #if MI_TRACK_HEAP_DESTROY + mi_heap_visit_blocks(heap, true, mi_heap_track_block_free, NULL); + #endif + // free all pages + _mi_heap_destroy_pages(heap); + mi_heap_free(heap); + } +} + +// forcefully destroy all heaps in the current thread +void _mi_heap_unsafe_destroy_all(void) { + mi_heap_t* bheap = mi_heap_get_backing(); + mi_heap_t* curr = bheap->tld->heaps; + while (curr != NULL) { + mi_heap_t* next = curr->next; + if (curr->no_reclaim) { + mi_heap_destroy(curr); + } + else { + _mi_heap_destroy_pages(curr); + } + curr = next; + } +} + +/* ----------------------------------------------------------- + Safe Heap delete +----------------------------------------------------------- */ + +// Transfer the pages from one heap to the other +static void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) { + mi_assert_internal(heap!=NULL); + if (from==NULL || from->page_count == 0) return; + + // reduce the size of the delayed frees + _mi_heap_delayed_free_partial(from); + + // transfer all pages by appending the queues; this will set a new heap field + // so threads may do delayed frees in either heap for a while. + // note: appending waits for each page to not be in the `MI_DELAYED_FREEING` state + // so after this only the new heap will get delayed frees + for (size_t i = 0; i <= MI_BIN_FULL; i++) { + mi_page_queue_t* pq = &heap->pages[i]; + mi_page_queue_t* append = &from->pages[i]; + size_t pcount = _mi_page_queue_append(heap, pq, append); + heap->page_count += pcount; + from->page_count -= pcount; + } + mi_assert_internal(from->page_count == 0); + + // and do outstanding delayed frees in the `from` heap + // note: be careful here as the `heap` field in all those pages no longer point to `from`, + // turns out to be ok as `_mi_heap_delayed_free` only visits the list and calls a + // the regular `_mi_free_delayed_block` which is safe. + _mi_heap_delayed_free_all(from); + #if !defined(_MSC_VER) || (_MSC_VER > 1900) // somehow the following line gives an error in VS2015, issue #353 + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_block_t,&from->thread_delayed_free) == NULL); + #endif + + // and reset the `from` heap + mi_heap_reset_pages(from); +} + +// Safe delete a heap without freeing any still allocated blocks in that heap. +void mi_heap_delete(mi_heap_t* heap) +{ + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + mi_assert_expensive(mi_heap_is_valid(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + + if (!mi_heap_is_backing(heap)) { + // tranfer still used pages to the backing heap + mi_heap_absorb(heap->tld->heap_backing, heap); + } + else { + // the backing heap abandons its pages + _mi_heap_collect_abandon(heap); + } + mi_assert_internal(heap->page_count==0); + mi_heap_free(heap); +} + +mi_heap_t* mi_heap_set_default(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return NULL; + mi_assert_expensive(mi_heap_is_valid(heap)); + mi_heap_t* old = mi_prim_get_default_heap(); + _mi_heap_set_default_direct(heap); + return old; +} + + + + +/* ----------------------------------------------------------- + Analysis +----------------------------------------------------------- */ + +// static since it is not thread safe to access heaps from other threads. +static mi_heap_t* mi_heap_of_block(const void* p) { + if (p == NULL) return NULL; + mi_segment_t* segment = _mi_ptr_segment(p); + bool valid = (_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(valid); + if mi_unlikely(!valid) return NULL; + return mi_page_heap(_mi_segment_page_of(segment,p)); +} + +bool mi_heap_contains_block(mi_heap_t* heap, const void* p) { + mi_assert(heap != NULL); + if (heap==NULL || !mi_heap_is_initialized(heap)) return false; + return (heap == mi_heap_of_block(p)); +} + + +static bool mi_heap_page_check_owned(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* p, void* vfound) { + MI_UNUSED(heap); + MI_UNUSED(pq); + bool* found = (bool*)vfound; + mi_segment_t* segment = _mi_page_segment(page); + void* start = _mi_page_start(segment, page, NULL); + void* end = (uint8_t*)start + (page->capacity * mi_page_block_size(page)); + *found = (p >= start && p < end); + return (!*found); // continue if not found +} + +bool mi_heap_check_owned(mi_heap_t* heap, const void* p) { + mi_assert(heap != NULL); + if (heap==NULL || !mi_heap_is_initialized(heap)) return false; + if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false; // only aligned pointers + bool found = false; + mi_heap_visit_pages(heap, &mi_heap_page_check_owned, (void*)p, &found); + return found; +} + +bool mi_check_owned(const void* p) { + return mi_heap_check_owned(mi_prim_get_default_heap(), p); +} + +/* ----------------------------------------------------------- + Visit all heap blocks and areas + Todo: enable visiting abandoned pages, and + enable visiting all blocks of all heaps across threads +----------------------------------------------------------- */ + +// Separate struct to keep `mi_page_t` out of the public interface +typedef struct mi_heap_area_ex_s { + mi_heap_area_t area; + mi_page_t* page; +} mi_heap_area_ex_t; + +static bool mi_heap_area_visit_blocks(const mi_heap_area_ex_t* xarea, mi_block_visit_fun* visitor, void* arg) { + mi_assert(xarea != NULL); + if (xarea==NULL) return true; + const mi_heap_area_t* area = &xarea->area; + mi_page_t* page = xarea->page; + mi_assert(page != NULL); + if (page == NULL) return true; + + _mi_page_free_collect(page,true); + mi_assert_internal(page->local_free == NULL); + if (page->used == 0) return true; + + const size_t bsize = mi_page_block_size(page); + const size_t ubsize = mi_page_usable_block_size(page); // without padding + size_t psize; + uint8_t* pstart = _mi_page_start(_mi_page_segment(page), page, &psize); + + if (page->capacity == 1) { + // optimize page with one block + mi_assert_internal(page->used == 1 && page->free == NULL); + return visitor(mi_page_heap(page), area, pstart, ubsize, arg); + } + + // create a bitmap of free blocks. + #define MI_MAX_BLOCKS (MI_SMALL_PAGE_SIZE / sizeof(void*)) + uintptr_t free_map[MI_MAX_BLOCKS / sizeof(uintptr_t)]; + memset(free_map, 0, sizeof(free_map)); + + #if MI_DEBUG>1 + size_t free_count = 0; + #endif + for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) { + #if MI_DEBUG>1 + free_count++; + #endif + mi_assert_internal((uint8_t*)block >= pstart && (uint8_t*)block < (pstart + psize)); + size_t offset = (uint8_t*)block - pstart; + mi_assert_internal(offset % bsize == 0); + size_t blockidx = offset / bsize; // Todo: avoid division? + mi_assert_internal( blockidx < MI_MAX_BLOCKS); + size_t bitidx = (blockidx / sizeof(uintptr_t)); + size_t bit = blockidx - (bitidx * sizeof(uintptr_t)); + free_map[bitidx] |= ((uintptr_t)1 << bit); + } + mi_assert_internal(page->capacity == (free_count + page->used)); + + // walk through all blocks skipping the free ones + #if MI_DEBUG>1 + size_t used_count = 0; + #endif + for (size_t i = 0; i < page->capacity; i++) { + size_t bitidx = (i / sizeof(uintptr_t)); + size_t bit = i - (bitidx * sizeof(uintptr_t)); + uintptr_t m = free_map[bitidx]; + if (bit == 0 && m == UINTPTR_MAX) { + i += (sizeof(uintptr_t) - 1); // skip a run of free blocks + } + else if ((m & ((uintptr_t)1 << bit)) == 0) { + #if MI_DEBUG>1 + used_count++; + #endif + uint8_t* block = pstart + (i * bsize); + if (!visitor(mi_page_heap(page), area, block, ubsize, arg)) return false; + } + } + mi_assert_internal(page->used == used_count); + return true; +} + +typedef bool (mi_heap_area_visit_fun)(const mi_heap_t* heap, const mi_heap_area_ex_t* area, void* arg); + + +static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) { + MI_UNUSED(heap); + MI_UNUSED(pq); + mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun; + mi_heap_area_ex_t xarea; + const size_t bsize = mi_page_block_size(page); + const size_t ubsize = mi_page_usable_block_size(page); + xarea.page = page; + xarea.area.reserved = page->reserved * bsize; + xarea.area.committed = page->capacity * bsize; + xarea.area.blocks = _mi_page_start(_mi_page_segment(page), page, NULL); + xarea.area.used = page->used; // number of blocks in use (#553) + xarea.area.block_size = ubsize; + xarea.area.full_block_size = bsize; + return fun(heap, &xarea, arg); +} + +// Visit all heap pages as areas +static bool mi_heap_visit_areas(const mi_heap_t* heap, mi_heap_area_visit_fun* visitor, void* arg) { + if (visitor == NULL) return false; + return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, (void*)(visitor), arg); // note: function pointer to void* :-{ +} + +// Just to pass arguments +typedef struct mi_visit_blocks_args_s { + bool visit_blocks; + mi_block_visit_fun* visitor; + void* arg; +} mi_visit_blocks_args_t; + +static bool mi_heap_area_visitor(const mi_heap_t* heap, const mi_heap_area_ex_t* xarea, void* arg) { + mi_visit_blocks_args_t* args = (mi_visit_blocks_args_t*)arg; + if (!args->visitor(heap, &xarea->area, NULL, xarea->area.block_size, args->arg)) return false; + if (args->visit_blocks) { + return mi_heap_area_visit_blocks(xarea, args->visitor, args->arg); + } + else { + return true; + } +} + +// Visit all blocks in a heap +bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) { + mi_visit_blocks_args_t args = { visit_blocks, visitor, arg }; + return mi_heap_visit_areas(heap, &mi_heap_area_visitor, &args); +} diff --git a/lib/Utils.Memory/mimalloc/src/init.c b/lib/Utils.Memory/mimalloc/src/init.c new file mode 100644 index 0000000..b1db14c --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/init.c @@ -0,0 +1,709 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2022, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/prim.h" + +#include <string.h> // memcpy, memset +#include <stdlib.h> // atexit + + +// Empty page used to initialize the small free pages array +const mi_page_t _mi_page_empty = { + 0, false, false, false, + 0, // capacity + 0, // reserved capacity + { 0 }, // flags + false, // is_zero + 0, // retire_expire + NULL, // free + 0, // used + 0, // xblock_size + NULL, // local_free + #if (MI_PADDING || MI_ENCODE_FREELIST) + { 0, 0 }, + #endif + MI_ATOMIC_VAR_INIT(0), // xthread_free + MI_ATOMIC_VAR_INIT(0), // xheap + NULL, NULL + #if MI_INTPTR_SIZE==8 + , { 0 } // padding + #endif +}; + +#define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty) + +#if (MI_SMALL_WSIZE_MAX==128) +#if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8) +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } +#elif (MI_PADDING>0) +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } +#else +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() } +#endif +#else +#error "define right initialization sizes corresponding to MI_SMALL_WSIZE_MAX" +#endif + +// Empty page queues for every bin +#define QNULL(sz) { NULL, NULL, (sz)*sizeof(uintptr_t) } +#define MI_PAGE_QUEUES_EMPTY \ + { QNULL(1), \ + QNULL( 1), QNULL( 2), QNULL( 3), QNULL( 4), QNULL( 5), QNULL( 6), QNULL( 7), QNULL( 8), /* 8 */ \ + QNULL( 10), QNULL( 12), QNULL( 14), QNULL( 16), QNULL( 20), QNULL( 24), QNULL( 28), QNULL( 32), /* 16 */ \ + QNULL( 40), QNULL( 48), QNULL( 56), QNULL( 64), QNULL( 80), QNULL( 96), QNULL( 112), QNULL( 128), /* 24 */ \ + QNULL( 160), QNULL( 192), QNULL( 224), QNULL( 256), QNULL( 320), QNULL( 384), QNULL( 448), QNULL( 512), /* 32 */ \ + QNULL( 640), QNULL( 768), QNULL( 896), QNULL( 1024), QNULL( 1280), QNULL( 1536), QNULL( 1792), QNULL( 2048), /* 40 */ \ + QNULL( 2560), QNULL( 3072), QNULL( 3584), QNULL( 4096), QNULL( 5120), QNULL( 6144), QNULL( 7168), QNULL( 8192), /* 48 */ \ + QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \ + QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \ + QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \ + QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \ + QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 2) /* Full queue */ } + +#define MI_STAT_COUNT_NULL() {0,0,0,0} + +// Empty statistics +#if MI_STAT>1 +#define MI_STAT_COUNT_END_NULL() , { MI_STAT_COUNT_NULL(), MI_INIT32(MI_STAT_COUNT_NULL) } +#else +#define MI_STAT_COUNT_END_NULL() +#endif + +#define MI_STATS_NULL \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \ + MI_STAT_COUNT_END_NULL() + + +// Empty slice span queues for every bin +#define SQNULL(sz) { NULL, NULL, sz } +#define MI_SEGMENT_SPAN_QUEUES_EMPTY \ + { SQNULL(1), \ + SQNULL( 1), SQNULL( 2), SQNULL( 3), SQNULL( 4), SQNULL( 5), SQNULL( 6), SQNULL( 7), SQNULL( 10), /* 8 */ \ + SQNULL( 12), SQNULL( 14), SQNULL( 16), SQNULL( 20), SQNULL( 24), SQNULL( 28), SQNULL( 32), SQNULL( 40), /* 16 */ \ + SQNULL( 48), SQNULL( 56), SQNULL( 64), SQNULL( 80), SQNULL( 96), SQNULL( 112), SQNULL( 128), SQNULL( 160), /* 24 */ \ + SQNULL( 192), SQNULL( 224), SQNULL( 256), SQNULL( 320), SQNULL( 384), SQNULL( 448), SQNULL( 512), SQNULL( 640), /* 32 */ \ + SQNULL( 768), SQNULL( 896), SQNULL( 1024) /* 35 */ } + + +// -------------------------------------------------------- +// Statically allocate an empty heap as the initial +// thread local value for the default heap, +// and statically allocate the backing heap for the main +// thread so it can function without doing any allocation +// itself (as accessing a thread local for the first time +// may lead to allocation itself on some platforms) +// -------------------------------------------------------- + +mi_decl_cache_align const mi_heap_t _mi_heap_empty = { + NULL, + MI_SMALL_PAGES_EMPTY, + MI_PAGE_QUEUES_EMPTY, + MI_ATOMIC_VAR_INIT(NULL), + 0, // tid + 0, // cookie + 0, // arena id + { 0, 0 }, // keys + { {0}, {0}, 0, true }, // random + 0, // page count + MI_BIN_FULL, 0, // page retired min/max + NULL, // next + false +}; + +#define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats))) +#define tld_empty_os ((mi_os_tld_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,os))) + +mi_decl_cache_align static const mi_tld_t tld_empty = { + 0, + false, + NULL, NULL, + { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, tld_empty_stats, tld_empty_os }, // segments + { 0, tld_empty_stats }, // os + { MI_STATS_NULL } // stats +}; + +mi_threadid_t _mi_thread_id(void) mi_attr_noexcept { + return _mi_prim_thread_id(); +} + +// the thread-local default heap for allocation +mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty; + +extern mi_heap_t _mi_heap_main; + +static mi_tld_t tld_main = { + 0, false, + &_mi_heap_main, & _mi_heap_main, + { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, &tld_main.stats, &tld_main.os }, // segments + { 0, &tld_main.stats }, // os + { MI_STATS_NULL } // stats +}; + +mi_heap_t _mi_heap_main = { + &tld_main, + MI_SMALL_PAGES_EMPTY, + MI_PAGE_QUEUES_EMPTY, + MI_ATOMIC_VAR_INIT(NULL), + 0, // thread id + 0, // initial cookie + 0, // arena id + { 0, 0 }, // the key of the main heap can be fixed (unlike page keys that need to be secure!) + { {0x846ca68b}, {0}, 0, true }, // random + 0, // page count + MI_BIN_FULL, 0, // page retired min/max + NULL, // next heap + false // can reclaim +}; + +bool _mi_process_is_initialized = false; // set to `true` in `mi_process_init`. + +mi_stats_t _mi_stats_main = { MI_STATS_NULL }; + + +static void mi_heap_main_init(void) { + if (_mi_heap_main.cookie == 0) { + _mi_heap_main.thread_id = _mi_thread_id(); + _mi_heap_main.cookie = 1; + #if defined(_WIN32) && !defined(MI_SHARED_LIB) + _mi_random_init_weak(&_mi_heap_main.random); // prevent allocation failure during bcrypt dll initialization with static linking + #else + _mi_random_init(&_mi_heap_main.random); + #endif + _mi_heap_main.cookie = _mi_heap_random_next(&_mi_heap_main); + _mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main); + _mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main); + } +} + +mi_heap_t* _mi_heap_main_get(void) { + mi_heap_main_init(); + return &_mi_heap_main; +} + + +/* ----------------------------------------------------------- + Initialization and freeing of the thread local heaps +----------------------------------------------------------- */ + +// note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size). +typedef struct mi_thread_data_s { + mi_heap_t heap; // must come first due to cast in `_mi_heap_done` + mi_tld_t tld; + mi_memid_t memid; +} mi_thread_data_t; + + +// Thread meta-data is allocated directly from the OS. For +// some programs that do not use thread pools and allocate and +// destroy many OS threads, this may causes too much overhead +// per thread so we maintain a small cache of recently freed metadata. + +#define TD_CACHE_SIZE (16) +static _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE]; + +static mi_thread_data_t* mi_thread_data_zalloc(void) { + // try to find thread metadata in the cache + bool is_zero = false; + mi_thread_data_t* td = NULL; + for (int i = 0; i < TD_CACHE_SIZE; i++) { + td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); + if (td != NULL) { + // found cached allocation, try use it + td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL); + if (td != NULL) { + break; + } + } + } + + // if that fails, allocate as meta data + if (td == NULL) { + mi_memid_t memid; + td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid, &_mi_stats_main); + if (td == NULL) { + // if this fails, try once more. (issue #257) + td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid, &_mi_stats_main); + if (td == NULL) { + // really out of memory + _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t)); + } + } + if (td != NULL) { + td->memid = memid; + is_zero = memid.initially_zero; + } + } + + if (td != NULL && !is_zero) { + _mi_memzero_aligned(td, sizeof(*td)); + } + return td; +} + +static void mi_thread_data_free( mi_thread_data_t* tdfree ) { + // try to add the thread metadata to the cache + for (int i = 0; i < TD_CACHE_SIZE; i++) { + mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); + if (td == NULL) { + mi_thread_data_t* expected = NULL; + if (mi_atomic_cas_ptr_weak_acq_rel(mi_thread_data_t, &td_cache[i], &expected, tdfree)) { + return; + } + } + } + // if that fails, just free it directly + _mi_os_free(tdfree, sizeof(mi_thread_data_t), tdfree->memid, &_mi_stats_main); +} + +void _mi_thread_data_collect(void) { + // free all thread metadata from the cache + for (int i = 0; i < TD_CACHE_SIZE; i++) { + mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); + if (td != NULL) { + td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL); + if (td != NULL) { + _mi_os_free(td, sizeof(mi_thread_data_t), td->memid, &_mi_stats_main); + } + } + } +} + +// Initialize the thread local default heap, called from `mi_thread_init` +static bool _mi_heap_init(void) { + if (mi_heap_is_initialized(mi_prim_get_default_heap())) return true; + if (_mi_is_main_thread()) { + // mi_assert_internal(_mi_heap_main.thread_id != 0); // can happen on freeBSD where alloc is called before any initialization + // the main heap is statically allocated + mi_heap_main_init(); + _mi_heap_set_default_direct(&_mi_heap_main); + //mi_assert_internal(_mi_heap_default->tld->heap_backing == mi_prim_get_default_heap()); + } + else { + // use `_mi_os_alloc` to allocate directly from the OS + mi_thread_data_t* td = mi_thread_data_zalloc(); + if (td == NULL) return false; + + mi_tld_t* tld = &td->tld; + mi_heap_t* heap = &td->heap; + _mi_memcpy_aligned(tld, &tld_empty, sizeof(*tld)); + _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(*heap)); + heap->thread_id = _mi_thread_id(); + _mi_random_init(&heap->random); + heap->cookie = _mi_heap_random_next(heap) | 1; + heap->keys[0] = _mi_heap_random_next(heap); + heap->keys[1] = _mi_heap_random_next(heap); + heap->tld = tld; + tld->heap_backing = heap; + tld->heaps = heap; + tld->segments.stats = &tld->stats; + tld->segments.os = &tld->os; + tld->os.stats = &tld->stats; + _mi_heap_set_default_direct(heap); + } + return false; +} + +// Free the thread local default heap (called from `mi_thread_done`) +static bool _mi_heap_done(mi_heap_t* heap) { + if (!mi_heap_is_initialized(heap)) return true; + + // reset default heap + _mi_heap_set_default_direct(_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty); + + // switch to backing heap + heap = heap->tld->heap_backing; + if (!mi_heap_is_initialized(heap)) return false; + + // delete all non-backing heaps in this thread + mi_heap_t* curr = heap->tld->heaps; + while (curr != NULL) { + mi_heap_t* next = curr->next; // save `next` as `curr` will be freed + if (curr != heap) { + mi_assert_internal(!mi_heap_is_backing(curr)); + mi_heap_delete(curr); + } + curr = next; + } + mi_assert_internal(heap->tld->heaps == heap && heap->next == NULL); + mi_assert_internal(mi_heap_is_backing(heap)); + + // collect if not the main thread + if (heap != &_mi_heap_main) { + _mi_heap_collect_abandon(heap); + } + + // merge stats + _mi_stats_done(&heap->tld->stats); + + // free if not the main thread + if (heap != &_mi_heap_main) { + // the following assertion does not always hold for huge segments as those are always treated + // as abondened: one may allocate it in one thread, but deallocate in another in which case + // the count can be too large or negative. todo: perhaps not count huge segments? see issue #363 + // mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id()); + mi_thread_data_free((mi_thread_data_t*)heap); + } + else { + #if 0 + // never free the main thread even in debug mode; if a dll is linked statically with mimalloc, + // there may still be delete/free calls after the mi_fls_done is called. Issue #207 + _mi_heap_destroy_pages(heap); + mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main); + #endif + } + return false; +} + + + +// -------------------------------------------------------- +// Try to run `mi_thread_done()` automatically so any memory +// owned by the thread but not yet released can be abandoned +// and re-owned by another thread. +// +// 1. windows dynamic library: +// call from DllMain on DLL_THREAD_DETACH +// 2. windows static library: +// use `FlsAlloc` to call a destructor when the thread is done +// 3. unix, pthreads: +// use a pthread key to call a destructor when a pthread is done +// +// In the last two cases we also need to call `mi_process_init` +// to set up the thread local keys. +// -------------------------------------------------------- + +// Set up handlers so `mi_thread_done` is called automatically +static void mi_process_setup_auto_thread_done(void) { + static bool tls_initialized = false; // fine if it races + if (tls_initialized) return; + tls_initialized = true; + _mi_prim_thread_init_auto_done(); + _mi_heap_set_default_direct(&_mi_heap_main); +} + + +bool _mi_is_main_thread(void) { + return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id()); +} + +static _Atomic(size_t) thread_count = MI_ATOMIC_VAR_INIT(1); + +size_t _mi_current_thread_count(void) { + return mi_atomic_load_relaxed(&thread_count); +} + +// This is called from the `mi_malloc_generic` +void mi_thread_init(void) mi_attr_noexcept +{ + // ensure our process has started already + mi_process_init(); + + // initialize the thread local default heap + // (this will call `_mi_heap_set_default_direct` and thus set the + // fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called) + if (_mi_heap_init()) return; // returns true if already initialized + + _mi_stat_increase(&_mi_stats_main.threads, 1); + mi_atomic_increment_relaxed(&thread_count); + //_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id()); +} + +void mi_thread_done(void) mi_attr_noexcept { + _mi_thread_done(NULL); +} + +void _mi_thread_done(mi_heap_t* heap) +{ + // calling with NULL implies using the default heap + if (heap == NULL) { + heap = mi_prim_get_default_heap(); + if (heap == NULL) return; + } + + // prevent re-entrancy through heap_done/heap_set_default_direct (issue #699) + if (!mi_heap_is_initialized(heap)) { + return; + } + + // adjust stats + mi_atomic_decrement_relaxed(&thread_count); + _mi_stat_decrease(&_mi_stats_main.threads, 1); + + // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps... + if (heap->thread_id != _mi_thread_id()) return; + + // abandon the thread local heap + if (_mi_heap_done(heap)) return; // returns true if already ran +} + +void _mi_heap_set_default_direct(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + #if defined(MI_TLS_SLOT) + mi_prim_tls_slot_set(MI_TLS_SLOT,heap); + #elif defined(MI_TLS_PTHREAD_SLOT_OFS) + *mi_tls_pthread_heap_slot() = heap; + #elif defined(MI_TLS_PTHREAD) + // we use _mi_heap_default_key + #else + _mi_heap_default = heap; + #endif + + // ensure the default heap is passed to `_mi_thread_done` + // setting to a non-NULL value also ensures `mi_thread_done` is called. + _mi_prim_thread_associate_default_heap(heap); +} + + +// -------------------------------------------------------- +// Run functions on process init/done, and thread init/done +// -------------------------------------------------------- +static void mi_cdecl mi_process_done(void); + +static bool os_preloading = true; // true until this module is initialized +static bool mi_redirected = false; // true if malloc redirects to mi_malloc + +// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false. +bool mi_decl_noinline _mi_preloading(void) { + return os_preloading; +} + +mi_decl_nodiscard bool mi_is_redirected(void) mi_attr_noexcept { + return mi_redirected; +} + +// Communicate with the redirection module on Windows +#if defined(_WIN32) && defined(MI_SHARED_LIB) && !defined(MI_WIN_NOREDIRECT) +#ifdef __cplusplus +extern "C" { +#endif +mi_decl_export void _mi_redirect_entry(DWORD reason) { + // called on redirection; careful as this may be called before DllMain + if (reason == DLL_PROCESS_ATTACH) { + mi_redirected = true; + } + else if (reason == DLL_PROCESS_DETACH) { + mi_redirected = false; + } + else if (reason == DLL_THREAD_DETACH) { + mi_thread_done(); + } +} +__declspec(dllimport) bool mi_cdecl mi_allocator_init(const char** message); +__declspec(dllimport) void mi_cdecl mi_allocator_done(void); +#ifdef __cplusplus +} +#endif +#else +static bool mi_allocator_init(const char** message) { + if (message != NULL) *message = NULL; + return true; +} +static void mi_allocator_done(void) { + // nothing to do +} +#endif + +// Called once by the process loader +static void mi_process_load(void) { + mi_heap_main_init(); + #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD) + volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true; + if (dummy == NULL) return; // use dummy or otherwise the access may get optimized away (issue #697) + #endif + os_preloading = false; + mi_assert_internal(_mi_is_main_thread()); + #if !(defined(_WIN32) && defined(MI_SHARED_LIB)) // use Dll process detach (see below) instead of atexit (issue #521) + atexit(&mi_process_done); + #endif + _mi_options_init(); + mi_process_setup_auto_thread_done(); + mi_process_init(); + if (mi_redirected) _mi_verbose_message("malloc is redirected.\n"); + + // show message from the redirector (if present) + const char* msg = NULL; + mi_allocator_init(&msg); + if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) { + _mi_fputs(NULL,NULL,NULL,msg); + } + + // reseed random + _mi_random_reinit_if_weak(&_mi_heap_main.random); +} + +#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) +#include <intrin.h> +mi_decl_cache_align bool _mi_cpu_has_fsrm = false; + +static void mi_detect_cpu_features(void) { + // FSRM for fast rep movsb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017)) + int32_t cpu_info[4]; + __cpuid(cpu_info, 7); + _mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features> +} +#else +static void mi_detect_cpu_features(void) { + // nothing +} +#endif + +// Initialize the process; called by thread_init or the process loader +void mi_process_init(void) mi_attr_noexcept { + // ensure we are called once + static mi_atomic_once_t process_init; + #if _MSC_VER < 1920 + mi_heap_main_init(); // vs2017 can dynamically re-initialize _mi_heap_main + #endif + if (!mi_atomic_once(&process_init)) return; + _mi_process_is_initialized = true; + _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id()); + mi_process_setup_auto_thread_done(); + + mi_detect_cpu_features(); + _mi_os_init(); + mi_heap_main_init(); + #if MI_DEBUG + _mi_verbose_message("debug level : %d\n", MI_DEBUG); + #endif + _mi_verbose_message("secure level: %d\n", MI_SECURE); + _mi_verbose_message("mem tracking: %s\n", MI_TRACK_TOOL); + #if MI_TSAN + _mi_verbose_message("thread santizer enabled\n"); + #endif + mi_thread_init(); + + #if defined(_WIN32) + // On windows, when building as a static lib the FLS cleanup happens to early for the main thread. + // To avoid this, set the FLS value for the main thread to NULL so the fls cleanup + // will not call _mi_thread_done on the (still executing) main thread. See issue #508. + _mi_prim_thread_associate_default_heap(NULL); + #endif + + mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) + mi_track_init(); + + if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { + size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024); + long reserve_at = mi_option_get(mi_option_reserve_huge_os_pages_at); + if (reserve_at != -1) { + mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500); + } else { + mi_reserve_huge_os_pages_interleave(pages, 0, pages*500); + } + } + if (mi_option_is_enabled(mi_option_reserve_os_memory)) { + long ksize = mi_option_get(mi_option_reserve_os_memory); + if (ksize > 0) { + mi_reserve_os_memory((size_t)ksize*MI_KiB, true /* commit? */, true /* allow large pages? */); + } + } +} + +// Called when the process is done (through `at_exit`) +static void mi_cdecl mi_process_done(void) { + // only shutdown if we were initialized + if (!_mi_process_is_initialized) return; + // ensure we are called once + static bool process_done = false; + if (process_done) return; + process_done = true; + + // release any thread specific resources and ensure _mi_thread_done is called on all but the main thread + _mi_prim_thread_done_auto_done(); + + #ifndef MI_SKIP_COLLECT_ON_EXIT + #if (MI_DEBUG || !defined(MI_SHARED_LIB)) + // free all memory if possible on process exit. This is not needed for a stand-alone process + // but should be done if mimalloc is statically linked into another shared library which + // is repeatedly loaded/unloaded, see issue #281. + mi_collect(true /* force */ ); + #endif + #endif + + // Forcefully release all retained memory; this can be dangerous in general if overriding regular malloc/free + // since after process_done there might still be other code running that calls `free` (like at_exit routines, + // or C-runtime termination code. + if (mi_option_is_enabled(mi_option_destroy_on_exit)) { + mi_collect(true /* force */); + _mi_heap_unsafe_destroy_all(); // forcefully release all memory held by all heaps (of this thread only!) + _mi_arena_unsafe_destroy_all(& _mi_heap_main_get()->tld->stats); + } + + if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) { + mi_stats_print(NULL); + } + mi_allocator_done(); + _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id); + os_preloading = true; // don't call the C runtime anymore +} + + + +#if defined(_WIN32) && defined(MI_SHARED_LIB) + // Windows DLL: easy to hook into process_init and thread_done + __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { + MI_UNUSED(reserved); + MI_UNUSED(inst); + if (reason==DLL_PROCESS_ATTACH) { + mi_process_load(); + } + else if (reason==DLL_PROCESS_DETACH) { + mi_process_done(); + } + else if (reason==DLL_THREAD_DETACH) { + if (!mi_is_redirected()) { + mi_thread_done(); + } + } + return TRUE; + } + +#elif defined(_MSC_VER) + // MSVC: use data section magic for static libraries + // See <https://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm> + static int _mi_process_init(void) { + mi_process_load(); + return 0; + } + typedef int(*_mi_crt_callback_t)(void); + #if defined(_M_X64) || defined(_M_ARM64) + __pragma(comment(linker, "/include:" "_mi_msvc_initu")) + #pragma section(".CRT$XIU", long, read) + #else + __pragma(comment(linker, "/include:" "__mi_msvc_initu")) + #endif + #pragma data_seg(".CRT$XIU") + mi_decl_externc _mi_crt_callback_t _mi_msvc_initu[] = { &_mi_process_init }; + #pragma data_seg() + +#elif defined(__cplusplus) + // C++: use static initialization to detect process start + static bool _mi_process_init(void) { + mi_process_load(); + return (_mi_heap_main.thread_id != 0); + } + static bool mi_initialized = _mi_process_init(); + +#elif defined(__GNUC__) || defined(__clang__) + // GCC,Clang: use the constructor attribute + static void __attribute__((constructor)) _mi_process_init(void) { + mi_process_load(); + } + +#else +#pragma message("define a way to call mi_process_load on your platform") +#endif diff --git a/lib/Utils.Memory/mimalloc/src/options.c b/lib/Utils.Memory/mimalloc/src/options.c new file mode 100644 index 0000000..345b560 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/options.c @@ -0,0 +1,571 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" // mi_prim_out_stderr + +#include <stdio.h> // FILE +#include <stdlib.h> // abort +#include <stdarg.h> + + +static long mi_max_error_count = 16; // stop outputting errors after this (use < 0 for no limit) +static long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit) + +static void mi_add_stderr_output(void); + +int mi_version(void) mi_attr_noexcept { + return MI_MALLOC_VERSION; +} + + +// -------------------------------------------------------- +// Options +// These can be accessed by multiple threads and may be +// concurrently initialized, but an initializing data race +// is ok since they resolve to the same value. +// -------------------------------------------------------- +typedef enum mi_init_e { + UNINIT, // not yet initialized + DEFAULTED, // not found in the environment, use default value + INITIALIZED // found in environment or set explicitly +} mi_init_t; + +typedef struct mi_option_desc_s { + long value; // the value + mi_init_t init; // is it initialized yet? (from the environment) + mi_option_t option; // for debugging: the option index should match the option + const char* name; // option name without `mimalloc_` prefix + const char* legacy_name; // potential legacy option name +} mi_option_desc_t; + +#define MI_OPTION(opt) mi_option_##opt, #opt, NULL +#define MI_OPTION_LEGACY(opt,legacy) mi_option_##opt, #opt, #legacy + +static mi_option_desc_t options[_mi_option_last] = +{ + // stable options + #if MI_DEBUG || defined(MI_SHOW_ERRORS) + { 1, UNINIT, MI_OPTION(show_errors) }, + #else + { 0, UNINIT, MI_OPTION(show_errors) }, + #endif + { 0, UNINIT, MI_OPTION(show_stats) }, + { 0, UNINIT, MI_OPTION(verbose) }, + + // the following options are experimental and not all combinations make sense. + { 1, UNINIT, MI_OPTION(eager_commit) }, // commit per segment directly (4MiB) (but see also `eager_commit_delay`) + { 2, UNINIT, MI_OPTION_LEGACY(arena_eager_commit,eager_region_commit) }, // eager commit arena's? 2 is used to enable this only on an OS that has overcommit (i.e. linux) + { 1, UNINIT, MI_OPTION_LEGACY(purge_decommits,reset_decommits) }, // purge decommits memory (instead of reset) (note: on linux this uses MADV_DONTNEED for decommit) + { 0, UNINIT, MI_OPTION_LEGACY(allow_large_os_pages,large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's + { 0, UNINIT, MI_OPTION(reserve_huge_os_pages) }, // per 1GiB huge pages + {-1, UNINIT, MI_OPTION(reserve_huge_os_pages_at) }, // reserve huge pages at node N + { 0, UNINIT, MI_OPTION(reserve_os_memory) }, + { 0, UNINIT, MI_OPTION(deprecated_segment_cache) }, // cache N segments per thread + { 0, UNINIT, MI_OPTION(deprecated_page_reset) }, // reset page memory on free + { 0, UNINIT, MI_OPTION_LEGACY(abandoned_page_purge,abandoned_page_reset) }, // reset free page memory when a thread terminates + { 0, UNINIT, MI_OPTION(deprecated_segment_reset) }, // reset segment memory on free (needs eager commit) +#if defined(__NetBSD__) + { 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed +#else + { 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed (but per page in the segment on demand) +#endif + { 10, UNINIT, MI_OPTION_LEGACY(purge_delay,reset_delay) }, // purge delay in milli-seconds + { 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes. + { 0, UNINIT, MI_OPTION(limit_os_alloc) }, // 1 = do not use OS memory for allocation (but only reserved arenas) + { 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose + { 16, UNINIT, MI_OPTION(max_errors) }, // maximum errors that are output + { 16, UNINIT, MI_OPTION(max_warnings) }, // maximum warnings that are output + { 8, UNINIT, MI_OPTION(max_segment_reclaim)}, // max. number of segment reclaims from the abandoned segments per try. + { 0, UNINIT, MI_OPTION(destroy_on_exit)}, // release all OS memory on process exit; careful with dangling pointer or after-exit frees! + #if (MI_INTPTR_SIZE>4) + { 1024L * 1024L, UNINIT, MI_OPTION(arena_reserve) }, // reserve memory N KiB at a time + #else + { 128L * 1024L, UNINIT, MI_OPTION(arena_reserve) }, + #endif + { 10, UNINIT, MI_OPTION(arena_purge_mult) }, // purge delay multiplier for arena's + { 1, UNINIT, MI_OPTION_LEGACY(purge_extend_delay, decommit_extend_delay) }, +}; + +static void mi_option_init(mi_option_desc_t* desc); + +void _mi_options_init(void) { + // called on process load; should not be called before the CRT is initialized! + // (e.g. do not call this from process_init as that may run before CRT initialization) + mi_add_stderr_output(); // now it safe to use stderr for output + for(int i = 0; i < _mi_option_last; i++ ) { + mi_option_t option = (mi_option_t)i; + long l = mi_option_get(option); MI_UNUSED(l); // initialize + // if (option != mi_option_verbose) + { + mi_option_desc_t* desc = &options[option]; + _mi_verbose_message("option '%s': %ld\n", desc->name, desc->value); + } + } + mi_max_error_count = mi_option_get(mi_option_max_errors); + mi_max_warning_count = mi_option_get(mi_option_max_warnings); +} + +mi_decl_nodiscard long mi_option_get(mi_option_t option) { + mi_assert(option >= 0 && option < _mi_option_last); + if (option < 0 || option >= _mi_option_last) return 0; + mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option + if mi_unlikely(desc->init == UNINIT) { + mi_option_init(desc); + } + return desc->value; +} + +mi_decl_nodiscard long mi_option_get_clamp(mi_option_t option, long min, long max) { + long x = mi_option_get(option); + return (x < min ? min : (x > max ? max : x)); +} + +mi_decl_nodiscard size_t mi_option_get_size(mi_option_t option) { + mi_assert_internal(option == mi_option_reserve_os_memory || option == mi_option_arena_reserve); + long x = mi_option_get(option); + return (x < 0 ? 0 : (size_t)x * MI_KiB); +} + +void mi_option_set(mi_option_t option, long value) { + mi_assert(option >= 0 && option < _mi_option_last); + if (option < 0 || option >= _mi_option_last) return; + mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option + desc->value = value; + desc->init = INITIALIZED; +} + +void mi_option_set_default(mi_option_t option, long value) { + mi_assert(option >= 0 && option < _mi_option_last); + if (option < 0 || option >= _mi_option_last) return; + mi_option_desc_t* desc = &options[option]; + if (desc->init != INITIALIZED) { + desc->value = value; + } +} + +mi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option) { + return (mi_option_get(option) != 0); +} + +void mi_option_set_enabled(mi_option_t option, bool enable) { + mi_option_set(option, (enable ? 1 : 0)); +} + +void mi_option_set_enabled_default(mi_option_t option, bool enable) { + mi_option_set_default(option, (enable ? 1 : 0)); +} + +void mi_option_enable(mi_option_t option) { + mi_option_set_enabled(option,true); +} + +void mi_option_disable(mi_option_t option) { + mi_option_set_enabled(option,false); +} + +static void mi_cdecl mi_out_stderr(const char* msg, void* arg) { + MI_UNUSED(arg); + if (msg != NULL && msg[0] != 0) { + _mi_prim_out_stderr(msg); + } +} + +// Since an output function can be registered earliest in the `main` +// function we also buffer output that happens earlier. When +// an output function is registered it is called immediately with +// the output up to that point. +#ifndef MI_MAX_DELAY_OUTPUT +#define MI_MAX_DELAY_OUTPUT ((size_t)(32*1024)) +#endif +static char out_buf[MI_MAX_DELAY_OUTPUT+1]; +static _Atomic(size_t) out_len; + +static void mi_cdecl mi_out_buf(const char* msg, void* arg) { + MI_UNUSED(arg); + if (msg==NULL) return; + if (mi_atomic_load_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return; + size_t n = _mi_strlen(msg); + if (n==0) return; + // claim space + size_t start = mi_atomic_add_acq_rel(&out_len, n); + if (start >= MI_MAX_DELAY_OUTPUT) return; + // check bound + if (start+n >= MI_MAX_DELAY_OUTPUT) { + n = MI_MAX_DELAY_OUTPUT-start-1; + } + _mi_memcpy(&out_buf[start], msg, n); +} + +static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) { + if (out==NULL) return; + // claim (if `no_more_buf == true`, no more output will be added after this point) + size_t count = mi_atomic_add_acq_rel(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1)); + // and output the current contents + if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT; + out_buf[count] = 0; + out(out_buf,arg); + if (!no_more_buf) { + out_buf[count] = '\n'; // if continue with the buffer, insert a newline + } +} + + +// Once this module is loaded, switch to this routine +// which outputs to stderr and the delayed output buffer. +static void mi_cdecl mi_out_buf_stderr(const char* msg, void* arg) { + mi_out_stderr(msg,arg); + mi_out_buf(msg,arg); +} + + + +// -------------------------------------------------------- +// Default output handler +// -------------------------------------------------------- + +// Should be atomic but gives errors on many platforms as generally we cannot cast a function pointer to a uintptr_t. +// For now, don't register output from multiple threads. +static mi_output_fun* volatile mi_out_default; // = NULL +static _Atomic(void*) mi_out_arg; // = NULL + +static mi_output_fun* mi_out_get_default(void** parg) { + if (parg != NULL) { *parg = mi_atomic_load_ptr_acquire(void,&mi_out_arg); } + mi_output_fun* out = mi_out_default; + return (out == NULL ? &mi_out_buf : out); +} + +void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer + mi_atomic_store_ptr_release(void,&mi_out_arg, arg); + if (out!=NULL) mi_out_buf_flush(out,true,arg); // output all the delayed output now +} + +// add stderr to the delayed output after the module is loaded +static void mi_add_stderr_output(void) { + mi_assert_internal(mi_out_default == NULL); + mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr + mi_out_default = &mi_out_buf_stderr; // and add stderr to the delayed output +} + +// -------------------------------------------------------- +// Messages, all end up calling `_mi_fputs`. +// -------------------------------------------------------- +static _Atomic(size_t) error_count; // = 0; // when >= max_error_count stop emitting errors +static _Atomic(size_t) warning_count; // = 0; // when >= max_warning_count stop emitting warnings + +// When overriding malloc, we may recurse into mi_vfprintf if an allocation +// inside the C runtime causes another message. +// In some cases (like on macOS) the loader already allocates which +// calls into mimalloc; if we then access thread locals (like `recurse`) +// this may crash as the access may call _tlv_bootstrap that tries to +// (recursively) invoke malloc again to allocate space for the thread local +// variables on demand. This is why we use a _mi_preloading test on such +// platforms. However, C code generator may move the initial thread local address +// load before the `if` and we therefore split it out in a separate funcion. +static mi_decl_thread bool recurse = false; + +static mi_decl_noinline bool mi_recurse_enter_prim(void) { + if (recurse) return false; + recurse = true; + return true; +} + +static mi_decl_noinline void mi_recurse_exit_prim(void) { + recurse = false; +} + +static bool mi_recurse_enter(void) { + #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD) + if (_mi_preloading()) return false; + #endif + return mi_recurse_enter_prim(); +} + +static void mi_recurse_exit(void) { + #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD) + if (_mi_preloading()) return; + #endif + mi_recurse_exit_prim(); +} + +void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) { + if (out==NULL || (void*)out==(void*)stdout || (void*)out==(void*)stderr) { // TODO: use mi_out_stderr for stderr? + if (!mi_recurse_enter()) return; + out = mi_out_get_default(&arg); + if (prefix != NULL) out(prefix, arg); + out(message, arg); + mi_recurse_exit(); + } + else { + if (prefix != NULL) out(prefix, arg); + out(message, arg); + } +} + +// Define our own limited `fprintf` that avoids memory allocation. +// We do this using `snprintf` with a limited buffer. +static void mi_vfprintf( mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args ) { + char buf[512]; + if (fmt==NULL) return; + if (!mi_recurse_enter()) return; + vsnprintf(buf,sizeof(buf)-1,fmt,args); + mi_recurse_exit(); + _mi_fputs(out,arg,prefix,buf); +} + +void _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) { + va_list args; + va_start(args,fmt); + mi_vfprintf(out,arg,NULL,fmt,args); + va_end(args); +} + +static void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) { + if (prefix != NULL && _mi_strnlen(prefix,33) <= 32 && !_mi_is_main_thread()) { + char tprefix[64]; + snprintf(tprefix, sizeof(tprefix), "%sthread 0x%llx: ", prefix, (unsigned long long)_mi_thread_id()); + mi_vfprintf(out, arg, tprefix, fmt, args); + } + else { + mi_vfprintf(out, arg, prefix, fmt, args); + } +} + +void _mi_trace_message(const char* fmt, ...) { + if (mi_option_get(mi_option_verbose) <= 1) return; // only with verbose level 2 or higher + va_list args; + va_start(args, fmt); + mi_vfprintf_thread(NULL, NULL, "mimalloc: ", fmt, args); + va_end(args); +} + +void _mi_verbose_message(const char* fmt, ...) { + if (!mi_option_is_enabled(mi_option_verbose)) return; + va_list args; + va_start(args,fmt); + mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); + va_end(args); +} + +static void mi_show_error_message(const char* fmt, va_list args) { + if (!mi_option_is_enabled(mi_option_verbose)) { + if (!mi_option_is_enabled(mi_option_show_errors)) return; + if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; + } + mi_vfprintf_thread(NULL, NULL, "mimalloc: error: ", fmt, args); +} + +void _mi_warning_message(const char* fmt, ...) { + if (!mi_option_is_enabled(mi_option_verbose)) { + if (!mi_option_is_enabled(mi_option_show_errors)) return; + if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; + } + va_list args; + va_start(args,fmt); + mi_vfprintf_thread(NULL, NULL, "mimalloc: warning: ", fmt, args); + va_end(args); +} + + +#if MI_DEBUG +void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) { + _mi_fprintf(NULL, NULL, "mimalloc: assertion failed: at \"%s\":%u, %s\n assertion: \"%s\"\n", fname, line, (func==NULL?"":func), assertion); + abort(); +} +#endif + +// -------------------------------------------------------- +// Errors +// -------------------------------------------------------- + +static mi_error_fun* volatile mi_error_handler; // = NULL +static _Atomic(void*) mi_error_arg; // = NULL + +static void mi_error_default(int err) { + MI_UNUSED(err); +#if (MI_DEBUG>0) + if (err==EFAULT) { + #ifdef _MSC_VER + __debugbreak(); + #endif + abort(); + } +#endif +#if (MI_SECURE>0) + if (err==EFAULT) { // abort on serious errors in secure mode (corrupted meta-data) + abort(); + } +#endif +#if defined(MI_XMALLOC) + if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode + abort(); + } +#endif +} + +void mi_register_error(mi_error_fun* fun, void* arg) { + mi_error_handler = fun; // can be NULL + mi_atomic_store_ptr_release(void,&mi_error_arg, arg); +} + +void _mi_error_message(int err, const char* fmt, ...) { + // show detailed error message + va_list args; + va_start(args, fmt); + mi_show_error_message(fmt, args); + va_end(args); + // and call the error handler which may abort (or return normally) + if (mi_error_handler != NULL) { + mi_error_handler(err, mi_atomic_load_ptr_acquire(void,&mi_error_arg)); + } + else { + mi_error_default(err); + } +} + +// -------------------------------------------------------- +// Initialize options by checking the environment +// -------------------------------------------------------- +char _mi_toupper(char c) { + if (c >= 'a' && c <= 'z') return (c - 'a' + 'A'); + else return c; +} + +int _mi_strnicmp(const char* s, const char* t, size_t n) { + if (n == 0) return 0; + for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) { + if (_mi_toupper(*s) != _mi_toupper(*t)) break; + } + return (n == 0 ? 0 : *s - *t); +} + +void _mi_strlcpy(char* dest, const char* src, size_t dest_size) { + if (dest==NULL || src==NULL || dest_size == 0) return; + // copy until end of src, or when dest is (almost) full + while (*src != 0 && dest_size > 1) { + *dest++ = *src++; + dest_size--; + } + // always zero terminate + *dest = 0; +} + +void _mi_strlcat(char* dest, const char* src, size_t dest_size) { + if (dest==NULL || src==NULL || dest_size == 0) return; + // find end of string in the dest buffer + while (*dest != 0 && dest_size > 1) { + dest++; + dest_size--; + } + // and catenate + _mi_strlcpy(dest, src, dest_size); +} + +size_t _mi_strlen(const char* s) { + if (s==NULL) return 0; + size_t len = 0; + while(s[len] != 0) { len++; } + return len; +} + +size_t _mi_strnlen(const char* s, size_t max_len) { + if (s==NULL) return 0; + size_t len = 0; + while(s[len] != 0 && len < max_len) { len++; } + return len; +} + +#ifdef MI_NO_GETENV +static bool mi_getenv(const char* name, char* result, size_t result_size) { + MI_UNUSED(name); + MI_UNUSED(result); + MI_UNUSED(result_size); + return false; +} +#else +static bool mi_getenv(const char* name, char* result, size_t result_size) { + if (name==NULL || result == NULL || result_size < 64) return false; + return _mi_prim_getenv(name,result,result_size); +} +#endif + +// TODO: implement ourselves to reduce dependencies on the C runtime +#include <stdlib.h> // strtol +#include <string.h> // strstr + + +static void mi_option_init(mi_option_desc_t* desc) { + // Read option value from the environment + char s[64 + 1]; + char buf[64+1]; + _mi_strlcpy(buf, "mimalloc_", sizeof(buf)); + _mi_strlcat(buf, desc->name, sizeof(buf)); + bool found = mi_getenv(buf, s, sizeof(s)); + if (!found && desc->legacy_name != NULL) { + _mi_strlcpy(buf, "mimalloc_", sizeof(buf)); + _mi_strlcat(buf, desc->legacy_name, sizeof(buf)); + found = mi_getenv(buf, s, sizeof(s)); + if (found) { + _mi_warning_message("environment option \"mimalloc_%s\" is deprecated -- use \"mimalloc_%s\" instead.\n", desc->legacy_name, desc->name); + } + } + + if (found) { + size_t len = _mi_strnlen(s, sizeof(buf) - 1); + for (size_t i = 0; i < len; i++) { + buf[i] = _mi_toupper(s[i]); + } + buf[len] = 0; + if (buf[0] == 0 || strstr("1;TRUE;YES;ON", buf) != NULL) { + desc->value = 1; + desc->init = INITIALIZED; + } + else if (strstr("0;FALSE;NO;OFF", buf) != NULL) { + desc->value = 0; + desc->init = INITIALIZED; + } + else { + char* end = buf; + long value = strtol(buf, &end, 10); + if (desc->option == mi_option_reserve_os_memory || desc->option == mi_option_arena_reserve) { + // this option is interpreted in KiB to prevent overflow of `long` + if (*end == 'K') { end++; } + else if (*end == 'M') { value *= MI_KiB; end++; } + else if (*end == 'G') { value *= MI_MiB; end++; } + else { value = (value + MI_KiB - 1) / MI_KiB; } + if (end[0] == 'I' && end[1] == 'B') { end += 2; } + else if (*end == 'B') { end++; } + } + if (*end == 0) { + desc->value = value; + desc->init = INITIALIZED; + } + else { + // set `init` first to avoid recursion through _mi_warning_message on mimalloc_verbose. + desc->init = DEFAULTED; + if (desc->option == mi_option_verbose && desc->value == 0) { + // if the 'mimalloc_verbose' env var has a bogus value we'd never know + // (since the value defaults to 'off') so in that case briefly enable verbose + desc->value = 1; + _mi_warning_message("environment option mimalloc_%s has an invalid value.\n", desc->name); + desc->value = 0; + } + else { + _mi_warning_message("environment option mimalloc_%s has an invalid value.\n", desc->name); + } + } + } + mi_assert_internal(desc->init != UNINIT); + } + else if (!_mi_preloading()) { + desc->init = DEFAULTED; + } +} diff --git a/lib/Utils.Memory/mimalloc/src/os.c b/lib/Utils.Memory/mimalloc/src/os.c new file mode 100644 index 0000000..b4f02ba --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/os.c @@ -0,0 +1,689 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + + +/* ----------------------------------------------------------- + Initialization. + On windows initializes support for aligned allocation and + large OS pages (if MIMALLOC_LARGE_OS_PAGES is true). +----------------------------------------------------------- */ + +static mi_os_mem_config_t mi_os_mem_config = { + 4096, // page size + 0, // large page size (usually 2MiB) + 4096, // allocation granularity + true, // has overcommit? (if true we use MAP_NORESERVE on mmap systems) + false, // must free whole? (on mmap systems we can free anywhere in a mapped range, but on Windows we must free the entire span) + true // has virtual reserve? (if true we can reserve virtual address space without using commit or physical memory) +}; + +bool _mi_os_has_overcommit(void) { + return mi_os_mem_config.has_overcommit; +} + +bool _mi_os_has_virtual_reserve(void) { + return mi_os_mem_config.has_virtual_reserve; +} + + +// OS (small) page size +size_t _mi_os_page_size(void) { + return mi_os_mem_config.page_size; +} + +// if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB) +size_t _mi_os_large_page_size(void) { + return (mi_os_mem_config.large_page_size != 0 ? mi_os_mem_config.large_page_size : _mi_os_page_size()); +} + +bool _mi_os_use_large_page(size_t size, size_t alignment) { + // if we have access, check the size and alignment requirements + if (mi_os_mem_config.large_page_size == 0 || !mi_option_is_enabled(mi_option_allow_large_os_pages)) return false; + return ((size % mi_os_mem_config.large_page_size) == 0 && (alignment % mi_os_mem_config.large_page_size) == 0); +} + +// round to a good OS allocation size (bounded by max 12.5% waste) +size_t _mi_os_good_alloc_size(size_t size) { + size_t align_size; + if (size < 512*MI_KiB) align_size = _mi_os_page_size(); + else if (size < 2*MI_MiB) align_size = 64*MI_KiB; + else if (size < 8*MI_MiB) align_size = 256*MI_KiB; + else if (size < 32*MI_MiB) align_size = 1*MI_MiB; + else align_size = 4*MI_MiB; + if mi_unlikely(size >= (SIZE_MAX - align_size)) return size; // possible overflow? + return _mi_align_up(size, align_size); +} + +void _mi_os_init(void) { + _mi_prim_mem_init(&mi_os_mem_config); +} + + +/* ----------------------------------------------------------- + Util +-------------------------------------------------------------- */ +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats); + +static void* mi_align_up_ptr(void* p, size_t alignment) { + return (void*)_mi_align_up((uintptr_t)p, alignment); +} + +static void* mi_align_down_ptr(void* p, size_t alignment) { + return (void*)_mi_align_down((uintptr_t)p, alignment); +} + + +/* ----------------------------------------------------------- + aligned hinting +-------------------------------------------------------------- */ + +// On 64-bit systems, we can do efficient aligned allocation by using +// the 2TiB to 30TiB area to allocate those. +#if (MI_INTPTR_SIZE >= 8) +static mi_decl_cache_align _Atomic(uintptr_t)aligned_base; + +// Return a MI_SEGMENT_SIZE aligned address that is probably available. +// If this returns NULL, the OS will determine the address but on some OS's that may not be +// properly aligned which can be more costly as it needs to be adjusted afterwards. +// For a size > 1GiB this always returns NULL in order to guarantee good ASLR randomization; +// (otherwise an initial large allocation of say 2TiB has a 50% chance to include (known) addresses +// in the middle of the 2TiB - 6TiB address range (see issue #372)) + +#define MI_HINT_BASE ((uintptr_t)2 << 40) // 2TiB start +#define MI_HINT_AREA ((uintptr_t)4 << 40) // upto 6TiB (since before win8 there is "only" 8TiB available to processes) +#define MI_HINT_MAX ((uintptr_t)30 << 40) // wrap after 30TiB (area after 32TiB is used for huge OS pages) + +void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) +{ + if (try_alignment <= 1 || try_alignment > MI_SEGMENT_SIZE) return NULL; + size = _mi_align_up(size, MI_SEGMENT_SIZE); + if (size > 1*MI_GiB) return NULL; // guarantee the chance of fixed valid address is at most 1/(MI_HINT_AREA / 1<<30) = 1/4096. + #if (MI_SECURE>0) + size += MI_SEGMENT_SIZE; // put in `MI_SEGMENT_SIZE` virtual gaps between hinted blocks; this splits VLA's but increases guarded areas. + #endif + + uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size); + if (hint == 0 || hint > MI_HINT_MAX) { // wrap or initialize + uintptr_t init = MI_HINT_BASE; + #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of aligned allocations unless in debug mode + uintptr_t r = _mi_heap_random_next(mi_prim_get_default_heap()); + init = init + ((MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)) % MI_HINT_AREA); // (randomly 20 bits)*4MiB == 0 to 4TiB + #endif + uintptr_t expected = hint + size; + mi_atomic_cas_strong_acq_rel(&aligned_base, &expected, init); + hint = mi_atomic_add_acq_rel(&aligned_base, size); // this may still give 0 or > MI_HINT_MAX but that is ok, it is a hint after all + } + if (hint%try_alignment != 0) return NULL; + return (void*)hint; +} +#else +void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) { + MI_UNUSED(try_alignment); MI_UNUSED(size); + return NULL; +} +#endif + + +/* ----------------------------------------------------------- + Free memory +-------------------------------------------------------------- */ + +static void mi_os_free_huge_os_pages(void* p, size_t size, mi_stats_t* stats); + +static void mi_os_prim_free(void* addr, size_t size, bool still_committed, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + mi_assert_internal((size % _mi_os_page_size()) == 0); + if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr) + int err = _mi_prim_free(addr, size); + if (err != 0) { + _mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr); + } + mi_stats_t* stats = &_mi_stats_main; + if (still_committed) { _mi_stat_decrease(&stats->committed, size); } + _mi_stat_decrease(&stats->reserved, size); +} + +void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* tld_stats) { + if (mi_memkind_is_os(memid.memkind)) { + size_t csize = _mi_os_good_alloc_size(size); + void* base = addr; + // different base? (due to alignment) + if (memid.mem.os.base != NULL) { + mi_assert(memid.mem.os.base <= addr); + mi_assert((uint8_t*)memid.mem.os.base + memid.mem.os.alignment >= (uint8_t*)addr); + base = memid.mem.os.base; + csize += ((uint8_t*)addr - (uint8_t*)memid.mem.os.base); + } + // free it + if (memid.memkind == MI_MEM_OS_HUGE) { + mi_assert(memid.is_pinned); + mi_os_free_huge_os_pages(base, csize, tld_stats); + } + else { + mi_os_prim_free(base, csize, still_committed, tld_stats); + } + } + else { + // nothing to do + mi_assert(memid.memkind < MI_MEM_OS); + } +} + +void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* tld_stats) { + _mi_os_free_ex(p, size, true, memid, tld_stats); +} + + +/* ----------------------------------------------------------- + Primitive allocation from the OS. +-------------------------------------------------------------- */ + +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +static void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, mi_stats_t* stats) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(is_zero != NULL); + mi_assert_internal(is_large != NULL); + if (size == 0) return NULL; + if (!commit) { allow_large = false; } + if (try_alignment == 0) { try_alignment = 1; } // avoid 0 to ensure there will be no divide by zero when aligning + + *is_zero = false; + void* p = NULL; + int err = _mi_prim_alloc(size, try_alignment, commit, allow_large, is_large, is_zero, &p); + if (err != 0) { + _mi_warning_message("unable to allocate OS memory (error: %d (0x%x), size: 0x%zx bytes, align: 0x%zx, commit: %d, allow large: %d)\n", err, err, size, try_alignment, commit, allow_large); + } + mi_stat_counter_increase(stats->mmap_calls, 1); + if (p != NULL) { + _mi_stat_increase(&stats->reserved, size); + if (commit) { + _mi_stat_increase(&stats->committed, size); + // seems needed for asan (or `mimalloc-test-api` fails) + #ifdef MI_TRACK_ASAN + if (*is_zero) { mi_track_mem_defined(p,size); } + else { mi_track_mem_undefined(p,size); } + #endif + } + } + return p; +} + + +// Primitive aligned allocation from the OS. +// This function guarantees the allocated memory is aligned. +static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** base, mi_stats_t* stats) { + mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0)); + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(is_large != NULL); + mi_assert_internal(is_zero != NULL); + mi_assert_internal(base != NULL); + if (!commit) allow_large = false; + if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL; + size = _mi_align_up(size, _mi_os_page_size()); + + // try first with a hint (this will be aligned directly on Win 10+ or BSD) + void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero, stats); + if (p == NULL) return NULL; + + // aligned already? + if (((uintptr_t)p % alignment) == 0) { + *base = p; + } + else { + // if not aligned, free it, overallocate, and unmap around it + _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\n", size, p, alignment, commit); + mi_os_prim_free(p, size, commit, stats); + if (size >= (SIZE_MAX - alignment)) return NULL; // overflow + const size_t over_size = size + alignment; + + if (mi_os_mem_config.must_free_whole) { // win32 virtualAlloc cannot free parts of an allocate block + // over-allocate uncommitted (virtual) memory + p = mi_os_prim_alloc(over_size, 1 /*alignment*/, false /* commit? */, false /* allow_large */, is_large, is_zero, stats); + if (p == NULL) return NULL; + + // set p to the aligned part in the full region + // note: this is dangerous on Windows as VirtualFree needs the actual base pointer + // this is handled though by having the `base` field in the memid's + *base = p; // remember the base + p = mi_align_up_ptr(p, alignment); + + // explicitly commit only the aligned part + if (commit) { + _mi_os_commit(p, size, NULL, stats); + } + } + else { // mmap can free inside an allocation + // overallocate... + p = mi_os_prim_alloc(over_size, 1, commit, false, is_large, is_zero, stats); + if (p == NULL) return NULL; + + // and selectively unmap parts around the over-allocated area. (noop on sbrk) + void* aligned_p = mi_align_up_ptr(p, alignment); + size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p; + size_t mid_size = _mi_align_up(size, _mi_os_page_size()); + size_t post_size = over_size - pre_size - mid_size; + mi_assert_internal(pre_size < over_size&& post_size < over_size&& mid_size >= size); + if (pre_size > 0) { mi_os_prim_free(p, pre_size, commit, stats); } + if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); } + // we can return the aligned pointer on `mmap` (and sbrk) systems + p = aligned_p; + *base = aligned_p; // since we freed the pre part, `*base == p`. + } + } + + mi_assert_internal(p == NULL || (p != NULL && *base != NULL && ((uintptr_t)p % alignment) == 0)); + return p; +} + + +/* ----------------------------------------------------------- + OS API: alloc and alloc_aligned +----------------------------------------------------------- */ + +void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + *memid = _mi_memid_none(); + mi_stats_t* stats = &_mi_stats_main; + if (size == 0) return NULL; + size = _mi_os_good_alloc_size(size); + bool os_is_large = false; + bool os_is_zero = false; + void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero, stats); + if (p != NULL) { + *memid = _mi_memid_create_os(true, os_is_zero, os_is_large); + } + return p; +} + +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats) +{ + MI_UNUSED(&_mi_os_get_aligned_hint); // suppress unused warnings + MI_UNUSED(tld_stats); + *memid = _mi_memid_none(); + if (size == 0) return NULL; + size = _mi_os_good_alloc_size(size); + alignment = _mi_align_up(alignment, _mi_os_page_size()); + + bool os_is_large = false; + bool os_is_zero = false; + void* os_base = NULL; + void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base, &_mi_stats_main /*tld->stats*/ ); + if (p != NULL) { + *memid = _mi_memid_create_os(commit, os_is_zero, os_is_large); + memid->mem.os.base = os_base; + memid->mem.os.alignment = alignment; + } + return p; +} + +/* ----------------------------------------------------------- + OS aligned allocation with an offset. This is used + for large alignments > MI_ALIGNMENT_MAX. We use a large mimalloc + page where the object can be aligned at an offset from the start of the segment. + As we may need to overallocate, we need to free such pointers using `mi_free_aligned` + to use the actual start of the memory region. +----------------------------------------------------------- */ + +void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats) { + mi_assert(offset <= MI_SEGMENT_SIZE); + mi_assert(offset <= size); + mi_assert((alignment % _mi_os_page_size()) == 0); + *memid = _mi_memid_none(); + if (offset > MI_SEGMENT_SIZE) return NULL; + if (offset == 0) { + // regular aligned allocation + return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld_stats); + } + else { + // overallocate to align at an offset + const size_t extra = _mi_align_up(offset, alignment) - offset; + const size_t oversize = size + extra; + void* const start = _mi_os_alloc_aligned(oversize, alignment, commit, allow_large, memid, tld_stats); + if (start == NULL) return NULL; + + void* const p = (uint8_t*)start + extra; + mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment)); + // decommit the overallocation at the start + if (commit && extra > _mi_os_page_size()) { + _mi_os_decommit(start, extra, tld_stats); + } + return p; + } +} + +/* ----------------------------------------------------------- + OS memory API: reset, commit, decommit, protect, unprotect. +----------------------------------------------------------- */ + +// OS page align within a given area, either conservative (pages inside the area only), +// or not (straddling pages outside the area is possible) +static void* mi_os_page_align_areax(bool conservative, void* addr, size_t size, size_t* newsize) { + mi_assert(addr != NULL && size > 0); + if (newsize != NULL) *newsize = 0; + if (size == 0 || addr == NULL) return NULL; + + // page align conservatively within the range + void* start = (conservative ? mi_align_up_ptr(addr, _mi_os_page_size()) + : mi_align_down_ptr(addr, _mi_os_page_size())); + void* end = (conservative ? mi_align_down_ptr((uint8_t*)addr + size, _mi_os_page_size()) + : mi_align_up_ptr((uint8_t*)addr + size, _mi_os_page_size())); + ptrdiff_t diff = (uint8_t*)end - (uint8_t*)start; + if (diff <= 0) return NULL; + + mi_assert_internal((conservative && (size_t)diff <= size) || (!conservative && (size_t)diff >= size)); + if (newsize != NULL) *newsize = (size_t)diff; + return start; +} + +static void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t* newsize) { + return mi_os_page_align_areax(true, addr, size, newsize); +} + +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + mi_stats_t* stats = &_mi_stats_main; + if (is_zero != NULL) { *is_zero = false; } + _mi_stat_increase(&stats->committed, size); // use size for precise commit vs. decommit + _mi_stat_counter_increase(&stats->commit_calls, 1); + + // page align range + size_t csize; + void* start = mi_os_page_align_areax(false /* conservative? */, addr, size, &csize); + if (csize == 0) return true; + + // commit + bool os_is_zero = false; + int err = _mi_prim_commit(start, csize, &os_is_zero); + if (err != 0) { + _mi_warning_message("cannot commit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); + return false; + } + if (os_is_zero && is_zero != NULL) { + *is_zero = true; + mi_assert_expensive(mi_mem_is_zero(start, csize)); + } + // note: the following seems required for asan (otherwise `mimalloc-test-stress` fails) + #ifdef MI_TRACK_ASAN + if (os_is_zero) { mi_track_mem_defined(start,csize); } + else { mi_track_mem_undefined(start,csize); } + #endif + return true; +} + +static bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + mi_stats_t* stats = &_mi_stats_main; + mi_assert_internal(needs_recommit!=NULL); + _mi_stat_decrease(&stats->committed, size); + + // page align + size_t csize; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return true; + + // decommit + *needs_recommit = true; + int err = _mi_prim_decommit(start,csize,needs_recommit); + if (err != 0) { + _mi_warning_message("cannot decommit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); + } + mi_assert_internal(err == 0); + return (err == 0); +} + +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* tld_stats) { + bool needs_recommit; + return mi_os_decommit_ex(addr, size, &needs_recommit, tld_stats); +} + + +// Signal to the OS that the address range is no longer in use +// but may be used later again. This will release physical memory +// pages and reduce swapping while keeping the memory committed. +// We page align to a conservative area inside the range to reset. +bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) { + // page align conservatively within the range + size_t csize; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr) + _mi_stat_increase(&stats->reset, csize); + _mi_stat_counter_increase(&stats->reset_calls, 1); + + #if (MI_DEBUG>1) && !MI_SECURE && !MI_TRACK_ENABLED // && !MI_TSAN + memset(start, 0, csize); // pretend it is eagerly reset + #endif + + int err = _mi_prim_reset(start, csize); + if (err != 0) { + _mi_warning_message("cannot reset OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); + } + return (err == 0); +} + + +// either resets or decommits memory, returns true if the memory needs +// to be recommitted if it is to be re-used later on. +bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats) +{ + if (mi_option_get(mi_option_purge_delay) < 0) return false; // is purging allowed? + _mi_stat_counter_increase(&stats->purge_calls, 1); + _mi_stat_increase(&stats->purged, size); + + if (mi_option_is_enabled(mi_option_purge_decommits) && // should decommit? + !_mi_preloading()) // don't decommit during preloading (unsafe) + { + bool needs_recommit = true; + mi_os_decommit_ex(p, size, &needs_recommit, stats); + return needs_recommit; + } + else { + if (allow_reset) { // this can sometimes be not allowed if the range is not fully committed + _mi_os_reset(p, size, stats); + } + return false; // needs no recommit + } +} + +// either resets or decommits memory, returns true if the memory needs +// to be recommitted if it is to be re-used later on. +bool _mi_os_purge(void* p, size_t size, mi_stats_t * stats) { + return _mi_os_purge_ex(p, size, true, stats); +} + +// Protect a region in memory to be not accessible. +static bool mi_os_protectx(void* addr, size_t size, bool protect) { + // page align conservatively within the range + size_t csize = 0; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return false; + /* + if (_mi_os_is_huge_reserved(addr)) { + _mi_warning_message("cannot mprotect memory allocated in huge OS pages\n"); + } + */ + int err = _mi_prim_protect(start,csize,protect); + if (err != 0) { + _mi_warning_message("cannot %s OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", (protect ? "protect" : "unprotect"), err, err, start, csize); + } + return (err == 0); +} + +bool _mi_os_protect(void* addr, size_t size) { + return mi_os_protectx(addr, size, true); +} + +bool _mi_os_unprotect(void* addr, size_t size) { + return mi_os_protectx(addr, size, false); +} + + + +/* ---------------------------------------------------------------------------- +Support for allocating huge OS pages (1Gib) that are reserved up-front +and possibly associated with a specific NUMA node. (use `numa_node>=0`) +-----------------------------------------------------------------------------*/ +#define MI_HUGE_OS_PAGE_SIZE (MI_GiB) + + +#if (MI_INTPTR_SIZE >= 8) +// To ensure proper alignment, use our own area for huge OS pages +static mi_decl_cache_align _Atomic(uintptr_t) mi_huge_start; // = 0 + +// Claim an aligned address range for huge pages +static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { + if (total_size != NULL) *total_size = 0; + const size_t size = pages * MI_HUGE_OS_PAGE_SIZE; + + uintptr_t start = 0; + uintptr_t end = 0; + uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start); + do { + start = huge_start; + if (start == 0) { + // Initialize the start address after the 32TiB area + start = ((uintptr_t)32 << 40); // 32TiB virtual start address + #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of huge pages unless in debug mode + uintptr_t r = _mi_heap_random_next(mi_prim_get_default_heap()); + start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF)); // (randomly 12bits)*1GiB == between 0 to 4TiB + #endif + } + end = start + size; + mi_assert_internal(end % MI_SEGMENT_SIZE == 0); + } while (!mi_atomic_cas_strong_acq_rel(&mi_huge_start, &huge_start, end)); + + if (total_size != NULL) *total_size = size; + return (uint8_t*)start; +} +#else +static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { + MI_UNUSED(pages); + if (total_size != NULL) *total_size = 0; + return NULL; +} +#endif + +// Allocate MI_SEGMENT_SIZE aligned huge pages +void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_msecs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid) { + *memid = _mi_memid_none(); + if (psize != NULL) *psize = 0; + if (pages_reserved != NULL) *pages_reserved = 0; + size_t size = 0; + uint8_t* start = mi_os_claim_huge_pages(pages, &size); + if (start == NULL) return NULL; // or 32-bit systems + + // Allocate one page at the time but try to place them contiguously + // We allocate one page at the time to be able to abort if it takes too long + // or to at least allocate as many as available on the system. + mi_msecs_t start_t = _mi_clock_start(); + size_t page = 0; + bool all_zero = true; + while (page < pages) { + // allocate a page + bool is_zero = false; + void* addr = start + (page * MI_HUGE_OS_PAGE_SIZE); + void* p = NULL; + int err = _mi_prim_alloc_huge_os_pages(addr, MI_HUGE_OS_PAGE_SIZE, numa_node, &is_zero, &p); + if (!is_zero) { all_zero = false; } + if (err != 0) { + _mi_warning_message("unable to allocate huge OS page (error: %d (0x%x), address: %p, size: %zx bytes)\n", err, err, addr, MI_HUGE_OS_PAGE_SIZE); + break; + } + + // Did we succeed at a contiguous address? + if (p != addr) { + // no success, issue a warning and break + if (p != NULL) { + _mi_warning_message("could not allocate contiguous huge OS page %zu at %p\n", page, addr); + mi_os_prim_free(p, MI_HUGE_OS_PAGE_SIZE, true, &_mi_stats_main); + } + break; + } + + // success, record it + page++; // increase before timeout check (see issue #711) + _mi_stat_increase(&_mi_stats_main.committed, MI_HUGE_OS_PAGE_SIZE); + _mi_stat_increase(&_mi_stats_main.reserved, MI_HUGE_OS_PAGE_SIZE); + + // check for timeout + if (max_msecs > 0) { + mi_msecs_t elapsed = _mi_clock_end(start_t); + if (page >= 1) { + mi_msecs_t estimate = ((elapsed / (page+1)) * pages); + if (estimate > 2*max_msecs) { // seems like we are going to timeout, break + elapsed = max_msecs + 1; + } + } + if (elapsed > max_msecs) { + _mi_warning_message("huge OS page allocation timed out (after allocating %zu page(s))\n", page); + break; + } + } + } + mi_assert_internal(page*MI_HUGE_OS_PAGE_SIZE <= size); + if (pages_reserved != NULL) { *pages_reserved = page; } + if (psize != NULL) { *psize = page * MI_HUGE_OS_PAGE_SIZE; } + if (page != 0) { + mi_assert(start != NULL); + *memid = _mi_memid_create_os(true /* is committed */, all_zero, true /* is_large */); + memid->memkind = MI_MEM_OS_HUGE; + mi_assert(memid->is_pinned); + #ifdef MI_TRACK_ASAN + if (all_zero) { mi_track_mem_defined(start,size); } + #endif + } + return (page == 0 ? NULL : start); +} + +// free every huge page in a range individually (as we allocated per page) +// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems. +static void mi_os_free_huge_os_pages(void* p, size_t size, mi_stats_t* stats) { + if (p==NULL || size==0) return; + uint8_t* base = (uint8_t*)p; + while (size >= MI_HUGE_OS_PAGE_SIZE) { + mi_os_prim_free(base, MI_HUGE_OS_PAGE_SIZE, true, stats); + size -= MI_HUGE_OS_PAGE_SIZE; + base += MI_HUGE_OS_PAGE_SIZE; + } +} + +/* ---------------------------------------------------------------------------- +Support NUMA aware allocation +-----------------------------------------------------------------------------*/ + +_Atomic(size_t) _mi_numa_node_count; // = 0 // cache the node count + +size_t _mi_os_numa_node_count_get(void) { + size_t count = mi_atomic_load_acquire(&_mi_numa_node_count); + if (count <= 0) { + long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly? + if (ncount > 0) { + count = (size_t)ncount; + } + else { + count = _mi_prim_numa_node_count(); // or detect dynamically + if (count == 0) count = 1; + } + mi_atomic_store_release(&_mi_numa_node_count, count); // save it + _mi_verbose_message("using %zd numa regions\n", count); + } + return count; +} + +int _mi_os_numa_node_get(mi_os_tld_t* tld) { + MI_UNUSED(tld); + size_t numa_count = _mi_os_numa_node_count(); + if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0 + // never more than the node count and >= 0 + size_t numa_node = _mi_prim_numa_node(); + if (numa_node >= numa_count) { numa_node = numa_node % numa_count; } + return (int)numa_node; +} diff --git a/lib/Utils.Memory/mimalloc/src/page-queue.c b/lib/Utils.Memory/mimalloc/src/page-queue.c new file mode 100644 index 0000000..cb54b37 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/page-queue.c @@ -0,0 +1,332 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + Definition of page queues for each block size +----------------------------------------------------------- */ + +#ifndef MI_IN_PAGE_C +#error "this file should be included from 'page.c'" +#endif + +/* ----------------------------------------------------------- + Minimal alignment in machine words (i.e. `sizeof(void*)`) +----------------------------------------------------------- */ + +#if (MI_MAX_ALIGN_SIZE > 4*MI_INTPTR_SIZE) + #error "define alignment for more than 4x word size for this platform" +#elif (MI_MAX_ALIGN_SIZE > 2*MI_INTPTR_SIZE) + #define MI_ALIGN4W // 4 machine words minimal alignment +#elif (MI_MAX_ALIGN_SIZE > MI_INTPTR_SIZE) + #define MI_ALIGN2W // 2 machine words minimal alignment +#else + // ok, default alignment is 1 word +#endif + + +/* ----------------------------------------------------------- + Queue query +----------------------------------------------------------- */ + + +static inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) { + return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+sizeof(uintptr_t))); +} + +static inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) { + return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+(2*sizeof(uintptr_t)))); +} + +static inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) { + return (pq->block_size > MI_MEDIUM_OBJ_SIZE_MAX); +} + +/* ----------------------------------------------------------- + Bins +----------------------------------------------------------- */ + +// Return the bin for a given field size. +// Returns MI_BIN_HUGE if the size is too large. +// We use `wsize` for the size in "machine word sizes", +// i.e. byte size == `wsize*sizeof(void*)`. +static inline uint8_t mi_bin(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } + #if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } + #elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } + #else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } + #endif + else if (wsize > MI_MEDIUM_OBJ_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { + #if defined(MI_ALIGN4W) + if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes + #endif + wsize--; + // find the highest bit + uint8_t b = (uint8_t)mi_bsr(wsize); // note: wsize != 0 + // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). + // - adjust with 3 because we use do not round the first 8 sizes + // which each get an exact bin + bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; + mi_assert_internal(bin < MI_BIN_HUGE); + } + mi_assert_internal(bin > 0 && bin <= MI_BIN_HUGE); + return bin; +} + + + +/* ----------------------------------------------------------- + Queue of pages with free blocks +----------------------------------------------------------- */ + +uint8_t _mi_bin(size_t size) { + return mi_bin(size); +} + +size_t _mi_bin_size(uint8_t bin) { + return _mi_heap_empty.pages[bin].block_size; +} + +// Good size for allocation +size_t mi_good_size(size_t size) mi_attr_noexcept { + if (size <= MI_MEDIUM_OBJ_SIZE_MAX) { + return _mi_bin_size(mi_bin(size)); + } + else { + return _mi_align_up(size,_mi_os_page_size()); + } +} + +#if (MI_DEBUG>1) +static bool mi_page_queue_contains(mi_page_queue_t* queue, const mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_page_t* list = queue->first; + while (list != NULL) { + mi_assert_internal(list->next == NULL || list->next->prev == list); + mi_assert_internal(list->prev == NULL || list->prev->next == list); + if (list == page) break; + list = list->next; + } + return (list == page); +} + +#endif + +#if (MI_DEBUG>1) +static bool mi_heap_contains_queue(const mi_heap_t* heap, const mi_page_queue_t* pq) { + return (pq >= &heap->pages[0] && pq <= &heap->pages[MI_BIN_FULL]); +} +#endif + +static mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) { + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : mi_bin(page->xblock_size)); + mi_heap_t* heap = mi_page_heap(page); + mi_assert_internal(heap != NULL && bin <= MI_BIN_FULL); + mi_page_queue_t* pq = &heap->pages[bin]; + mi_assert_internal(bin >= MI_BIN_HUGE || page->xblock_size == pq->block_size); + mi_assert_expensive(mi_page_queue_contains(pq, page)); + return pq; +} + +static mi_page_queue_t* mi_heap_page_queue_of(mi_heap_t* heap, const mi_page_t* page) { + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : mi_bin(page->xblock_size)); + mi_assert_internal(bin <= MI_BIN_FULL); + mi_page_queue_t* pq = &heap->pages[bin]; + mi_assert_internal(mi_page_is_in_full(page) || page->xblock_size == pq->block_size); + return pq; +} + +// The current small page array is for efficiency and for each +// small size (up to 256) it points directly to the page for that +// size without having to compute the bin. This means when the +// current free page queue is updated for a small bin, we need to update a +// range of entries in `_mi_page_small_free`. +static inline void mi_heap_queue_first_update(mi_heap_t* heap, const mi_page_queue_t* pq) { + mi_assert_internal(mi_heap_contains_queue(heap,pq)); + size_t size = pq->block_size; + if (size > MI_SMALL_SIZE_MAX) return; + + mi_page_t* page = pq->first; + if (pq->first == NULL) page = (mi_page_t*)&_mi_page_empty; + + // find index in the right direct page array + size_t start; + size_t idx = _mi_wsize_from_size(size); + mi_page_t** pages_free = heap->pages_free_direct; + + if (pages_free[idx] == page) return; // already set + + // find start slot + if (idx<=1) { + start = 0; + } + else { + // find previous size; due to minimal alignment upto 3 previous bins may need to be skipped + uint8_t bin = mi_bin(size); + const mi_page_queue_t* prev = pq - 1; + while( bin == mi_bin(prev->block_size) && prev > &heap->pages[0]) { + prev--; + } + start = 1 + _mi_wsize_from_size(prev->block_size); + if (start > idx) start = idx; + } + + // set size range to the right page + mi_assert(start <= idx); + for (size_t sz = start; sz <= idx; sz++) { + pages_free[sz] = page; + } +} + +/* +static bool mi_page_queue_is_empty(mi_page_queue_t* queue) { + return (queue->first == NULL); +} +*/ + +static void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(mi_page_queue_contains(queue, page)); + mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_MEDIUM_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); + mi_heap_t* heap = mi_page_heap(page); + + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == queue->last) queue->last = page->prev; + if (page == queue->first) { + queue->first = page->next; + // update first + mi_assert_internal(mi_heap_contains_queue(heap, queue)); + mi_heap_queue_first_update(heap,queue); + } + heap->page_count--; + page->next = NULL; + page->prev = NULL; + // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), NULL); + mi_page_set_in_full(page,false); +} + + +static void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) { + mi_assert_internal(mi_page_heap(page) == heap); + mi_assert_internal(!mi_page_queue_contains(queue, page)); + #if MI_HUGE_PAGE_ABANDON + mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + #endif + mi_assert_internal(page->xblock_size == queue->block_size || + (page->xblock_size > MI_MEDIUM_OBJ_SIZE_MAX) || + (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); + + mi_page_set_in_full(page, mi_page_queue_is_full(queue)); + // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), heap); + page->next = queue->first; + page->prev = NULL; + if (queue->first != NULL) { + mi_assert_internal(queue->first->prev == NULL); + queue->first->prev = page; + queue->first = page; + } + else { + queue->first = queue->last = page; + } + + // update direct + mi_heap_queue_first_update(heap, queue); + heap->page_count++; +} + + +static void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(mi_page_queue_contains(from, page)); + mi_assert_expensive(!mi_page_queue_contains(to, page)); + + mi_assert_internal((page->xblock_size == to->block_size && page->xblock_size == from->block_size) || + (page->xblock_size == to->block_size && mi_page_queue_is_full(from)) || + (page->xblock_size == from->block_size && mi_page_queue_is_full(to)) || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(to)) || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_full(to))); + + mi_heap_t* heap = mi_page_heap(page); + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == from->last) from->last = page->prev; + if (page == from->first) { + from->first = page->next; + // update first + mi_assert_internal(mi_heap_contains_queue(heap, from)); + mi_heap_queue_first_update(heap, from); + } + + page->prev = to->last; + page->next = NULL; + if (to->last != NULL) { + mi_assert_internal(heap == mi_page_heap(to->last)); + to->last->next = page; + to->last = page; + } + else { + to->first = page; + to->last = page; + mi_heap_queue_first_update(heap, to); + } + + mi_page_set_in_full(page, mi_page_queue_is_full(to)); +} + +// Only called from `mi_heap_absorb`. +size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append) { + mi_assert_internal(mi_heap_contains_queue(heap,pq)); + mi_assert_internal(pq->block_size == append->block_size); + + if (append->first==NULL) return 0; + + // set append pages to new heap and count + size_t count = 0; + for (mi_page_t* page = append->first; page != NULL; page = page->next) { + // inline `mi_page_set_heap` to avoid wrong assertion during absorption; + // in this case it is ok to be delayed freeing since both "to" and "from" heap are still alive. + mi_atomic_store_release(&page->xheap, (uintptr_t)heap); + // set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a + // side effect that it spins until any DELAYED_FREEING is finished. This ensures + // that after appending only the new heap will be used for delayed free operations. + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false); + count++; + } + + if (pq->last==NULL) { + // take over afresh + mi_assert_internal(pq->first==NULL); + pq->first = append->first; + pq->last = append->last; + mi_heap_queue_first_update(heap, pq); + } + else { + // append to end + mi_assert_internal(pq->last!=NULL); + mi_assert_internal(append->first!=NULL); + pq->last->next = append->first; + append->first->prev = pq->last; + pq->last = append->last; + } + return count; +} diff --git a/lib/Utils.Memory/mimalloc/src/page.c b/lib/Utils.Memory/mimalloc/src/page.c new file mode 100644 index 0000000..8ac0a71 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/page.c @@ -0,0 +1,939 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + The core of the allocator. Every segment contains + pages of a certain block size. The main function + exported is `mi_malloc_generic`. +----------------------------------------------------------- */ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +/* ----------------------------------------------------------- + Definition of page queues for each block size +----------------------------------------------------------- */ + +#define MI_IN_PAGE_C +#include "page-queue.c" +#undef MI_IN_PAGE_C + + +/* ----------------------------------------------------------- + Page helpers +----------------------------------------------------------- */ + +// Index a block in a page +static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) { + MI_UNUSED(page); + mi_assert_internal(page != NULL); + mi_assert_internal(i <= page->reserved); + return (mi_block_t*)((uint8_t*)page_start + (i * block_size)); +} + +static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld); +static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld); + +#if (MI_DEBUG>=3) +static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) { + size_t count = 0; + while (head != NULL) { + mi_assert_internal(page == _mi_ptr_page(head)); + count++; + head = mi_block_next(page, head); + } + return count; +} + +/* +// Start of the page available memory +static inline uint8_t* mi_page_area(const mi_page_t* page) { + return _mi_page_start(_mi_page_segment(page), page, NULL); +} +*/ + +static bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) { + size_t psize; + uint8_t* page_area = _mi_page_start(_mi_page_segment(page), page, &psize); + mi_block_t* start = (mi_block_t*)page_area; + mi_block_t* end = (mi_block_t*)(page_area + psize); + while(p != NULL) { + if (p < start || p >= end) return false; + p = mi_block_next(page, p); + } +#if MI_DEBUG>3 // generally too expensive to check this + if (page->free_is_zero) { + const size_t ubsize = mi_page_usable_block_size(page); + for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page, block)) { + mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t))); + } + } +#endif + return true; +} + +static bool mi_page_is_valid_init(mi_page_t* page) { + mi_assert_internal(page->xblock_size > 0); + mi_assert_internal(page->used <= page->capacity); + mi_assert_internal(page->capacity <= page->reserved); + + mi_segment_t* segment = _mi_page_segment(page); + uint8_t* start = _mi_page_start(segment,page,NULL); + mi_assert_internal(start == _mi_segment_page_start(segment,page,NULL)); + //const size_t bsize = mi_page_block_size(page); + //mi_assert_internal(start + page->capacity*page->block_size == page->top); + + mi_assert_internal(mi_page_list_is_valid(page,page->free)); + mi_assert_internal(mi_page_list_is_valid(page,page->local_free)); + + #if MI_DEBUG>3 // generally too expensive to check this + if (page->free_is_zero) { + const size_t ubsize = mi_page_usable_block_size(page); + for(mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) { + mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t))); + } + } + #endif + + #if !MI_TRACK_ENABLED && !MI_TSAN + mi_block_t* tfree = mi_page_thread_free(page); + mi_assert_internal(mi_page_list_is_valid(page, tfree)); + //size_t tfree_count = mi_page_list_count(page, tfree); + //mi_assert_internal(tfree_count <= page->thread_freed + 1); + #endif + + size_t free_count = mi_page_list_count(page, page->free) + mi_page_list_count(page, page->local_free); + mi_assert_internal(page->used + free_count == page->capacity); + + return true; +} + +extern bool _mi_process_is_initialized; // has mi_process_init been called? + +bool _mi_page_is_valid(mi_page_t* page) { + mi_assert_internal(mi_page_is_valid_init(page)); + #if MI_SECURE + mi_assert_internal(page->keys[0] != 0); + #endif + if (mi_page_heap(page)!=NULL) { + mi_segment_t* segment = _mi_page_segment(page); + + mi_assert_internal(!_mi_process_is_initialized || segment->thread_id==0 || segment->thread_id == mi_page_heap(page)->thread_id); + #if MI_HUGE_PAGE_ABANDON + if (segment->kind != MI_SEGMENT_HUGE) + #endif + { + mi_page_queue_t* pq = mi_page_queue_of(page); + mi_assert_internal(mi_page_queue_contains(pq, page)); + mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_MEDIUM_OBJ_SIZE_MAX || mi_page_is_in_full(page)); + mi_assert_internal(mi_heap_contains_queue(mi_page_heap(page),pq)); + } + } + return true; +} +#endif + +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { + while (!_mi_page_try_use_delayed_free(page, delay, override_never)) { + mi_atomic_yield(); + } +} + +bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { + mi_thread_free_t tfreex; + mi_delayed_t old_delay; + mi_thread_free_t tfree; + size_t yield_count = 0; + do { + tfree = mi_atomic_load_acquire(&page->xthread_free); // note: must acquire as we can break/repeat this loop and not do a CAS; + tfreex = mi_tf_set_delayed(tfree, delay); + old_delay = mi_tf_delayed(tfree); + if mi_unlikely(old_delay == MI_DELAYED_FREEING) { + if (yield_count >= 4) return false; // give up after 4 tries + yield_count++; + mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done. + // tfree = mi_tf_set_delayed(tfree, MI_NO_DELAYED_FREE); // will cause CAS to busy fail + } + else if (delay == old_delay) { + break; // avoid atomic operation if already equal + } + else if (!override_never && old_delay == MI_NEVER_DELAYED_FREE) { + break; // leave never-delayed flag set + } + } while ((old_delay == MI_DELAYED_FREEING) || + !mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); + + return true; // success +} + +/* ----------------------------------------------------------- + Page collect the `local_free` and `thread_free` lists +----------------------------------------------------------- */ + +// Collect the local `thread_free` list using an atomic exchange. +// Note: The exchange must be done atomically as this is used right after +// moving to the full list in `mi_page_collect_ex` and we need to +// ensure that there was no race where the page became unfull just before the move. +static void _mi_page_thread_free_collect(mi_page_t* page) +{ + mi_block_t* head; + mi_thread_free_t tfreex; + mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free); + do { + head = mi_tf_block(tfree); + tfreex = mi_tf_set_block(tfree,NULL); + } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tfree, tfreex)); + + // return if the list is empty + if (head == NULL) return; + + // find the tail -- also to get a proper count (without data races) + uint32_t max_count = page->capacity; // cannot collect more than capacity + uint32_t count = 1; + mi_block_t* tail = head; + mi_block_t* next; + while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) { + count++; + tail = next; + } + // if `count > max_count` there was a memory corruption (possibly infinite list due to double multi-threaded free) + if (count > max_count) { + _mi_error_message(EFAULT, "corrupted thread-free list\n"); + return; // the thread-free items cannot be freed + } + + // and append the current local free list + mi_block_set_next(page,tail, page->local_free); + page->local_free = head; + + // update counts now + page->used -= count; +} + +void _mi_page_free_collect(mi_page_t* page, bool force) { + mi_assert_internal(page!=NULL); + + // collect the thread free list + if (force || mi_page_thread_free(page) != NULL) { // quick test to avoid an atomic operation + _mi_page_thread_free_collect(page); + } + + // and the local free list + if (page->local_free != NULL) { + if mi_likely(page->free == NULL) { + // usual case + page->free = page->local_free; + page->local_free = NULL; + page->free_is_zero = false; + } + else if (force) { + // append -- only on shutdown (force) as this is a linear operation + mi_block_t* tail = page->local_free; + mi_block_t* next; + while ((next = mi_block_next(page, tail)) != NULL) { + tail = next; + } + mi_block_set_next(page, tail, page->free); + page->free = page->local_free; + page->local_free = NULL; + page->free_is_zero = false; + } + } + + mi_assert_internal(!force || page->local_free == NULL); +} + + + +/* ----------------------------------------------------------- + Page fresh and retire +----------------------------------------------------------- */ + +// called from segments when reclaiming abandoned pages +void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page) { + mi_assert_expensive(mi_page_is_valid_init(page)); + + mi_assert_internal(mi_page_heap(page) == heap); + mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE); + #if MI_HUGE_PAGE_ABANDON + mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + #endif + + // TODO: push on full queue immediately if it is full? + mi_page_queue_t* pq = mi_page_queue(heap, mi_page_block_size(page)); + mi_page_queue_push(heap, pq, page); + mi_assert_expensive(_mi_page_is_valid(page)); +} + +// allocate a fresh page from a segment +static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size_t block_size, size_t page_alignment) { + #if !MI_HUGE_PAGE_ABANDON + mi_assert_internal(pq != NULL); + mi_assert_internal(mi_heap_contains_queue(heap, pq)); + mi_assert_internal(page_alignment > 0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || block_size == pq->block_size); + #endif + mi_page_t* page = _mi_segment_page_alloc(heap, block_size, page_alignment, &heap->tld->segments, &heap->tld->os); + if (page == NULL) { + // this may be out-of-memory, or an abandoned page was reclaimed (and in our queue) + return NULL; + } + mi_assert_internal(page_alignment >0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || _mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + mi_assert_internal(pq!=NULL || page->xblock_size != 0); + mi_assert_internal(pq!=NULL || mi_page_block_size(page) >= block_size); + // a fresh page was found, initialize it + const size_t full_block_size = ((pq == NULL || mi_page_queue_is_huge(pq)) ? mi_page_block_size(page) : block_size); // see also: mi_segment_huge_page_alloc + mi_assert_internal(full_block_size >= block_size); + mi_page_init(heap, page, full_block_size, heap->tld); + mi_heap_stat_increase(heap, pages, 1); + if (pq != NULL) { mi_page_queue_push(heap, pq, page); } + mi_assert_expensive(_mi_page_is_valid(page)); + return page; +} + +// Get a fresh page to use +static mi_page_t* mi_page_fresh(mi_heap_t* heap, mi_page_queue_t* pq) { + mi_assert_internal(mi_heap_contains_queue(heap, pq)); + mi_page_t* page = mi_page_fresh_alloc(heap, pq, pq->block_size, 0); + if (page==NULL) return NULL; + mi_assert_internal(pq->block_size==mi_page_block_size(page)); + mi_assert_internal(pq==mi_page_queue(heap, mi_page_block_size(page))); + return page; +} + +/* ----------------------------------------------------------- + Do any delayed frees + (put there by other threads if they deallocated in a full page) +----------------------------------------------------------- */ +void _mi_heap_delayed_free_all(mi_heap_t* heap) { + while (!_mi_heap_delayed_free_partial(heap)) { + mi_atomic_yield(); + } +} + +// returns true if all delayed frees were processed +bool _mi_heap_delayed_free_partial(mi_heap_t* heap) { + // take over the list (note: no atomic exchange since it is often NULL) + mi_block_t* block = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); + while (block != NULL && !mi_atomic_cas_ptr_weak_acq_rel(mi_block_t, &heap->thread_delayed_free, &block, NULL)) { /* nothing */ }; + bool all_freed = true; + + // and free them all + while(block != NULL) { + mi_block_t* next = mi_block_nextx(heap,block, heap->keys); + // use internal free instead of regular one to keep stats etc correct + if (!_mi_free_delayed_block(block)) { + // we might already start delayed freeing while another thread has not yet + // reset the delayed_freeing flag; in that case delay it further by reinserting the current block + // into the delayed free list + all_freed = false; + mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); + do { + mi_block_set_nextx(heap, block, dfree, heap->keys); + } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block)); + } + block = next; + } + return all_freed; +} + +/* ----------------------------------------------------------- + Unfull, abandon, free and retire +----------------------------------------------------------- */ + +// Move a page from the full list back to a regular list +void _mi_page_unfull(mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(mi_page_is_in_full(page)); + if (!mi_page_is_in_full(page)) return; + + mi_heap_t* heap = mi_page_heap(page); + mi_page_queue_t* pqfull = &heap->pages[MI_BIN_FULL]; + mi_page_set_in_full(page, false); // to get the right queue + mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page); + mi_page_set_in_full(page, true); + mi_page_queue_enqueue_from(pq, pqfull, page); +} + +static void mi_page_to_full(mi_page_t* page, mi_page_queue_t* pq) { + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(!mi_page_immediate_available(page)); + mi_assert_internal(!mi_page_is_in_full(page)); + + if (mi_page_is_in_full(page)) return; + mi_page_queue_enqueue_from(&mi_page_heap(page)->pages[MI_BIN_FULL], pq, page); + _mi_page_free_collect(page,false); // try to collect right away in case another thread freed just before MI_USE_DELAYED_FREE was set +} + + +// Abandon a page with used blocks at the end of a thread. +// Note: only call if it is ensured that no references exist from +// the `page->heap->thread_delayed_free` into this page. +// Currently only called through `mi_heap_collect_ex` which ensures this. +void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(mi_page_heap(page) != NULL); + + mi_heap_t* pheap = mi_page_heap(page); + + // remove from our page list + mi_segments_tld_t* segments_tld = &pheap->tld->segments; + mi_page_queue_remove(pq, page); + + // page is no longer associated with our heap + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_page_set_heap(page, NULL); + +#if (MI_DEBUG>1) && !MI_TRACK_ENABLED + // check there are no references left.. + for (mi_block_t* block = (mi_block_t*)pheap->thread_delayed_free; block != NULL; block = mi_block_nextx(pheap, block, pheap->keys)) { + mi_assert_internal(_mi_ptr_page(block) != page); + } +#endif + + // and abandon it + mi_assert_internal(mi_page_heap(page) == NULL); + _mi_segment_page_abandon(page,segments_tld); +} + + +// Free a page with no more free blocks +void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(mi_page_all_free(page)); + mi_assert_internal(mi_page_thread_free_flag(page)!=MI_DELAYED_FREEING); + + // no more aligned blocks in here + mi_page_set_has_aligned(page, false); + + mi_heap_t* heap = mi_page_heap(page); + + // remove from the page list + // (no need to do _mi_heap_delayed_free first as all blocks are already free) + mi_segments_tld_t* segments_tld = &heap->tld->segments; + mi_page_queue_remove(pq, page); + + // and free it + mi_page_set_heap(page,NULL); + _mi_segment_page_free(page, force, segments_tld); +} + +// Retire parameters +#define MI_MAX_RETIRE_SIZE (MI_MEDIUM_OBJ_SIZE_MAX) +#define MI_RETIRE_CYCLES (16) + +// Retire a page with no more used blocks +// Important to not retire too quickly though as new +// allocations might coming. +// Note: called from `mi_free` and benchmarks often +// trigger this due to freeing everything and then +// allocating again so careful when changing this. +void _mi_page_retire(mi_page_t* page) mi_attr_noexcept { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(mi_page_all_free(page)); + + mi_page_set_has_aligned(page, false); + + // don't retire too often.. + // (or we end up retiring and re-allocating most of the time) + // NOTE: refine this more: we should not retire if this + // is the only page left with free blocks. It is not clear + // how to check this efficiently though... + // for now, we don't retire if it is the only page left of this size class. + mi_page_queue_t* pq = mi_page_queue_of(page); + if mi_likely(page->xblock_size <= MI_MAX_RETIRE_SIZE && !mi_page_queue_is_special(pq)) { // not too large && not full or huge queue? + if (pq->last==page && pq->first==page) { // the only page in the queue? + mi_stat_counter_increase(_mi_stats_main.page_no_retire,1); + page->retire_expire = 1 + (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4); + mi_heap_t* heap = mi_page_heap(page); + mi_assert_internal(pq >= heap->pages); + const size_t index = pq - heap->pages; + mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE); + if (index < heap->page_retired_min) heap->page_retired_min = index; + if (index > heap->page_retired_max) heap->page_retired_max = index; + mi_assert_internal(mi_page_all_free(page)); + return; // dont't free after all + } + } + _mi_page_free(page, pq, false); +} + +// free retired pages: we don't need to look at the entire queues +// since we only retire pages that are at the head position in a queue. +void _mi_heap_collect_retired(mi_heap_t* heap, bool force) { + size_t min = MI_BIN_FULL; + size_t max = 0; + for(size_t bin = heap->page_retired_min; bin <= heap->page_retired_max; bin++) { + mi_page_queue_t* pq = &heap->pages[bin]; + mi_page_t* page = pq->first; + if (page != NULL && page->retire_expire != 0) { + if (mi_page_all_free(page)) { + page->retire_expire--; + if (force || page->retire_expire == 0) { + _mi_page_free(pq->first, pq, force); + } + else { + // keep retired, update min/max + if (bin < min) min = bin; + if (bin > max) max = bin; + } + } + else { + page->retire_expire = 0; + } + } + } + heap->page_retired_min = min; + heap->page_retired_max = max; +} + + +/* ----------------------------------------------------------- + Initialize the initial free list in a page. + In secure mode we initialize a randomized list by + alternating between slices. +----------------------------------------------------------- */ + +#define MI_MAX_SLICE_SHIFT (6) // at most 64 slices +#define MI_MAX_SLICES (1UL << MI_MAX_SLICE_SHIFT) +#define MI_MIN_SLICES (2) + +static void mi_page_free_list_extend_secure(mi_heap_t* const heap, mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) { + MI_UNUSED(stats); + #if (MI_SECURE<=2) + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->local_free == NULL); + #endif + mi_assert_internal(page->capacity + extend <= page->reserved); + mi_assert_internal(bsize == mi_page_block_size(page)); + void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL); + + // initialize a randomized free list + // set up `slice_count` slices to alternate between + size_t shift = MI_MAX_SLICE_SHIFT; + while ((extend >> shift) == 0) { + shift--; + } + const size_t slice_count = (size_t)1U << shift; + const size_t slice_extend = extend / slice_count; + mi_assert_internal(slice_extend >= 1); + mi_block_t* blocks[MI_MAX_SLICES]; // current start of the slice + size_t counts[MI_MAX_SLICES]; // available objects in the slice + for (size_t i = 0; i < slice_count; i++) { + blocks[i] = mi_page_block_at(page, page_area, bsize, page->capacity + i*slice_extend); + counts[i] = slice_extend; + } + counts[slice_count-1] += (extend % slice_count); // final slice holds the modulus too (todo: distribute evenly?) + + // and initialize the free list by randomly threading through them + // set up first element + const uintptr_t r = _mi_heap_random_next(heap); + size_t current = r % slice_count; + counts[current]--; + mi_block_t* const free_start = blocks[current]; + // and iterate through the rest; use `random_shuffle` for performance + uintptr_t rnd = _mi_random_shuffle(r|1); // ensure not 0 + for (size_t i = 1; i < extend; i++) { + // call random_shuffle only every INTPTR_SIZE rounds + const size_t round = i%MI_INTPTR_SIZE; + if (round == 0) rnd = _mi_random_shuffle(rnd); + // select a random next slice index + size_t next = ((rnd >> 8*round) & (slice_count-1)); + while (counts[next]==0) { // ensure it still has space + next++; + if (next==slice_count) next = 0; + } + // and link the current block to it + counts[next]--; + mi_block_t* const block = blocks[current]; + blocks[current] = (mi_block_t*)((uint8_t*)block + bsize); // bump to the following block + mi_block_set_next(page, block, blocks[next]); // and set next; note: we may have `current == next` + current = next; + } + // prepend to the free list (usually NULL) + mi_block_set_next(page, blocks[current], page->free); // end of the list + page->free = free_start; +} + +static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) +{ + MI_UNUSED(stats); + #if (MI_SECURE <= 2) + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->local_free == NULL); + #endif + mi_assert_internal(page->capacity + extend <= page->reserved); + mi_assert_internal(bsize == mi_page_block_size(page)); + void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL ); + + mi_block_t* const start = mi_page_block_at(page, page_area, bsize, page->capacity); + + // initialize a sequential free list + mi_block_t* const last = mi_page_block_at(page, page_area, bsize, page->capacity + extend - 1); + mi_block_t* block = start; + while(block <= last) { + mi_block_t* next = (mi_block_t*)((uint8_t*)block + bsize); + mi_block_set_next(page,block,next); + block = next; + } + // prepend to free list (usually `NULL`) + mi_block_set_next(page, last, page->free); + page->free = start; +} + +/* ----------------------------------------------------------- + Page initialize and extend the capacity +----------------------------------------------------------- */ + +#define MI_MAX_EXTEND_SIZE (4*1024) // heuristic, one OS page seems to work well. +#if (MI_SECURE>0) +#define MI_MIN_EXTEND (8*MI_SECURE) // extend at least by this many +#else +#define MI_MIN_EXTEND (4) +#endif + +// Extend the capacity (up to reserved) by initializing a free list +// We do at most `MI_MAX_EXTEND` to avoid touching too much memory +// Note: we also experimented with "bump" allocation on the first +// allocations but this did not speed up any benchmark (due to an +// extra test in malloc? or cache effects?) +static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) { + MI_UNUSED(tld); + mi_assert_expensive(mi_page_is_valid_init(page)); + #if (MI_SECURE<=2) + mi_assert(page->free == NULL); + mi_assert(page->local_free == NULL); + if (page->free != NULL) return; + #endif + if (page->capacity >= page->reserved) return; + + size_t page_size; + _mi_page_start(_mi_page_segment(page), page, &page_size); + mi_stat_counter_increase(tld->stats.pages_extended, 1); + + // calculate the extend count + const size_t bsize = (page->xblock_size < MI_HUGE_BLOCK_SIZE ? page->xblock_size : page_size); + size_t extend = page->reserved - page->capacity; + mi_assert_internal(extend > 0); + + size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/(uint32_t)bsize); + if (max_extend < MI_MIN_EXTEND) { max_extend = MI_MIN_EXTEND; } + mi_assert_internal(max_extend > 0); + + if (extend > max_extend) { + // ensure we don't touch memory beyond the page to reduce page commit. + // the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%. + extend = max_extend; + } + + mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved); + mi_assert_internal(extend < (1UL<<16)); + + // and append the extend the free list + if (extend < MI_MIN_SLICES || MI_SECURE==0) { //!mi_option_is_enabled(mi_option_secure)) { + mi_page_free_list_extend(page, bsize, extend, &tld->stats ); + } + else { + mi_page_free_list_extend_secure(heap, page, bsize, extend, &tld->stats); + } + // enable the new free list + page->capacity += (uint16_t)extend; + mi_stat_increase(tld->stats.page_committed, extend * bsize); + mi_assert_expensive(mi_page_is_valid_init(page)); +} + +// Initialize a fresh page +static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi_tld_t* tld) { + mi_assert(page != NULL); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert(segment != NULL); + mi_assert_internal(block_size > 0); + // set fields + mi_page_set_heap(page, heap); + page->xblock_size = (block_size < MI_HUGE_BLOCK_SIZE ? (uint32_t)block_size : MI_HUGE_BLOCK_SIZE); // initialize before _mi_segment_page_start + size_t page_size; + const void* page_start = _mi_segment_page_start(segment, page, &page_size); + MI_UNUSED(page_start); + mi_track_mem_noaccess(page_start,page_size); + mi_assert_internal(mi_page_block_size(page) <= page_size); + mi_assert_internal(page_size <= page->slice_count*MI_SEGMENT_SLICE_SIZE); + mi_assert_internal(page_size / block_size < (1L<<16)); + page->reserved = (uint16_t)(page_size / block_size); + mi_assert_internal(page->reserved > 0); + #if (MI_PADDING || MI_ENCODE_FREELIST) + page->keys[0] = _mi_heap_random_next(heap); + page->keys[1] = _mi_heap_random_next(heap); + #endif + page->free_is_zero = page->is_zero_init; + #if MI_DEBUG>2 + if (page->is_zero_init) { + mi_track_mem_defined(page_start, page_size); + mi_assert_expensive(mi_mem_is_zero(page_start, page_size)); + } + #endif + + mi_assert_internal(page->is_committed); + mi_assert_internal(page->capacity == 0); + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->used == 0); + mi_assert_internal(page->xthread_free == 0); + mi_assert_internal(page->next == NULL); + mi_assert_internal(page->prev == NULL); + mi_assert_internal(page->retire_expire == 0); + mi_assert_internal(!mi_page_has_aligned(page)); + #if (MI_PADDING || MI_ENCODE_FREELIST) + mi_assert_internal(page->keys[0] != 0); + mi_assert_internal(page->keys[1] != 0); + #endif + mi_assert_expensive(mi_page_is_valid_init(page)); + + // initialize an initial free list + mi_page_extend_free(heap,page,tld); + mi_assert(mi_page_immediate_available(page)); +} + + +/* ----------------------------------------------------------- + Find pages with free blocks +-------------------------------------------------------------*/ + +// Find a page with free blocks of `page->block_size`. +static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* pq, bool first_try) +{ + // search through the pages in "next fit" order + #if MI_STAT + size_t count = 0; + #endif + mi_page_t* page = pq->first; + while (page != NULL) + { + mi_page_t* next = page->next; // remember next + #if MI_STAT + count++; + #endif + + // 0. collect freed blocks by us and other threads + _mi_page_free_collect(page, false); + + // 1. if the page contains free blocks, we are done + if (mi_page_immediate_available(page)) { + break; // pick this one + } + + // 2. Try to extend + if (page->capacity < page->reserved) { + mi_page_extend_free(heap, page, heap->tld); + mi_assert_internal(mi_page_immediate_available(page)); + break; + } + + // 3. If the page is completely full, move it to the `mi_pages_full` + // queue so we don't visit long-lived pages too often. + mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page)); + mi_page_to_full(page, pq); + + page = next; + } // for each page + + mi_heap_stat_counter_increase(heap, searches, count); + + if (page == NULL) { + _mi_heap_collect_retired(heap, false); // perhaps make a page available? + page = mi_page_fresh(heap, pq); + if (page == NULL && first_try) { + // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again + page = mi_page_queue_find_free_ex(heap, pq, false); + } + } + else { + mi_assert(pq->first == page); + page->retire_expire = 0; + } + mi_assert_internal(page == NULL || mi_page_immediate_available(page)); + return page; +} + + + +// Find a page with free blocks of `size`. +static inline mi_page_t* mi_find_free_page(mi_heap_t* heap, size_t size) { + mi_page_queue_t* pq = mi_page_queue(heap,size); + mi_page_t* page = pq->first; + if (page != NULL) { + #if (MI_SECURE>=3) // in secure mode, we extend half the time to increase randomness + if (page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) { + mi_page_extend_free(heap, page, heap->tld); + mi_assert_internal(mi_page_immediate_available(page)); + } + else + #endif + { + _mi_page_free_collect(page,false); + } + + if (mi_page_immediate_available(page)) { + page->retire_expire = 0; + return page; // fast path + } + } + return mi_page_queue_find_free_ex(heap, pq, true); +} + + +/* ----------------------------------------------------------- + Users can register a deferred free function called + when the `free` list is empty. Since the `local_free` + is separate this is deterministically called after + a certain number of allocations. +----------------------------------------------------------- */ + +static mi_deferred_free_fun* volatile deferred_free = NULL; +static _Atomic(void*) deferred_arg; // = NULL + +void _mi_deferred_free(mi_heap_t* heap, bool force) { + heap->tld->heartbeat++; + if (deferred_free != NULL && !heap->tld->recurse) { + heap->tld->recurse = true; + deferred_free(force, heap->tld->heartbeat, mi_atomic_load_ptr_relaxed(void,&deferred_arg)); + heap->tld->recurse = false; + } +} + +void mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept { + deferred_free = fn; + mi_atomic_store_ptr_release(void,&deferred_arg, arg); +} + + +/* ----------------------------------------------------------- + General allocation +----------------------------------------------------------- */ + +// Large and huge page allocation. +// Huge pages are allocated directly without being in a queue. +// Because huge pages contain just one block, and the segment contains +// just that page, we always treat them as abandoned and any thread +// that frees the block can free the whole page and segment directly. +// Huge pages are also use if the requested alignment is very large (> MI_ALIGNMENT_MAX). +static mi_page_t* mi_large_huge_page_alloc(mi_heap_t* heap, size_t size, size_t page_alignment) { + size_t block_size = _mi_os_good_alloc_size(size); + mi_assert_internal(mi_bin(block_size) == MI_BIN_HUGE || page_alignment > 0); + bool is_huge = (block_size > MI_LARGE_OBJ_SIZE_MAX || page_alignment > 0); + #if MI_HUGE_PAGE_ABANDON + mi_page_queue_t* pq = (is_huge ? NULL : mi_page_queue(heap, block_size)); + #else + mi_page_queue_t* pq = mi_page_queue(heap, is_huge ? MI_HUGE_BLOCK_SIZE : block_size); // not block_size as that can be low if the page_alignment > 0 + mi_assert_internal(!is_huge || mi_page_queue_is_huge(pq)); + #endif + mi_page_t* page = mi_page_fresh_alloc(heap, pq, block_size, page_alignment); + if (page != NULL) { + mi_assert_internal(mi_page_immediate_available(page)); + + if (is_huge) { + mi_assert_internal(_mi_page_segment(page)->kind == MI_SEGMENT_HUGE); + mi_assert_internal(_mi_page_segment(page)->used==1); + #if MI_HUGE_PAGE_ABANDON + mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue + mi_page_set_heap(page, NULL); + #endif + } + else { + mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + } + + const size_t bsize = mi_page_usable_block_size(page); // note: not `mi_page_block_size` to account for padding + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_increase(heap, large, bsize); + mi_heap_stat_counter_increase(heap, large_count, 1); + } + else { + mi_heap_stat_increase(heap, huge, bsize); + mi_heap_stat_counter_increase(heap, huge_count, 1); + } + } + return page; +} + + +// Allocate a page +// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. +static mi_page_t* mi_find_page(mi_heap_t* heap, size_t size, size_t huge_alignment) mi_attr_noexcept { + // huge allocation? + const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` + if mi_unlikely(req_size > (MI_MEDIUM_OBJ_SIZE_MAX - MI_PADDING_SIZE) || huge_alignment > 0) { + if mi_unlikely(req_size > PTRDIFF_MAX) { // we don't allocate more than PTRDIFF_MAX (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>) + _mi_error_message(EOVERFLOW, "allocation request is too large (%zu bytes)\n", req_size); + return NULL; + } + else { + return mi_large_huge_page_alloc(heap,size,huge_alignment); + } + } + else { + // otherwise find a page with free blocks in our size segregated queues + #if MI_PADDING + mi_assert_internal(size >= MI_PADDING_SIZE); + #endif + return mi_find_free_page(heap, size); + } +} + +// Generic allocation routine if the fast path (`alloc.c:mi_page_malloc`) does not succeed. +// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. +// The `huge_alignment` is normally 0 but is set to a multiple of MI_SEGMENT_SIZE for +// very large requested alignments in which case we use a huge segment. +void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept +{ + mi_assert_internal(heap != NULL); + + // initialize if necessary + if mi_unlikely(!mi_heap_is_initialized(heap)) { + heap = mi_heap_get_default(); // calls mi_thread_init + if mi_unlikely(!mi_heap_is_initialized(heap)) { return NULL; } + } + mi_assert_internal(mi_heap_is_initialized(heap)); + + // call potential deferred free routines + _mi_deferred_free(heap, false); + + // free delayed frees from other threads (but skip contended ones) + _mi_heap_delayed_free_partial(heap); + + // find (or allocate) a page of the right size + mi_page_t* page = mi_find_page(heap, size, huge_alignment); + if mi_unlikely(page == NULL) { // first time out of memory, try to collect and retry the allocation once more + mi_heap_collect(heap, true /* force */); + page = mi_find_page(heap, size, huge_alignment); + } + + if mi_unlikely(page == NULL) { // out of memory + const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` + _mi_error_message(ENOMEM, "unable to allocate memory (%zu bytes)\n", req_size); + return NULL; + } + + mi_assert_internal(mi_page_immediate_available(page)); + mi_assert_internal(mi_page_block_size(page) >= size); + + // and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc) + if mi_unlikely(zero && page->xblock_size == 0) { + // note: we cannot call _mi_page_malloc with zeroing for huge blocks; we zero it afterwards in that case. + void* p = _mi_page_malloc(heap, page, size, false); + mi_assert_internal(p != NULL); + _mi_memzero_aligned(p, mi_page_usable_block_size(page)); + return p; + } + else { + return _mi_page_malloc(heap, page, size, zero); + } +} diff --git a/lib/Utils.Memory/mimalloc/src/prim/osx/alloc-override-zone.c b/lib/Utils.Memory/mimalloc/src/prim/osx/alloc-override-zone.c new file mode 100644 index 0000000..0e0a99d --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/osx/alloc-override-zone.c @@ -0,0 +1,458 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2022, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc/internal.h" + +#if defined(MI_MALLOC_OVERRIDE) + +#if !defined(__APPLE__) +#error "this file should only be included on macOS" +#endif + +/* ------------------------------------------------------ + Override system malloc on macOS + This is done through the malloc zone interface. + It seems to be most robust in combination with interposing + though or otherwise we may get zone errors as there are could + be allocations done by the time we take over the + zone. +------------------------------------------------------ */ + +#include <AvailabilityMacros.h> +#include <malloc/malloc.h> +#include <string.h> // memset +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) +// only available from OSX 10.6 +extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import)); +#endif + +/* ------------------------------------------------------ + malloc zone members +------------------------------------------------------ */ + +static size_t zone_size(malloc_zone_t* zone, const void* p) { + MI_UNUSED(zone); + if (!mi_is_in_heap_region(p)){ return 0; } // not our pointer, bail out + return mi_usable_size(p); +} + +static void* zone_malloc(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); + return mi_malloc(size); +} + +static void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) { + MI_UNUSED(zone); + return mi_calloc(count, size); +} + +static void* zone_valloc(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); + return mi_malloc_aligned(size, _mi_os_page_size()); +} + +static void zone_free(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); + mi_cfree(p); +} + +static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) { + MI_UNUSED(zone); + return mi_realloc(p, newsize); +} + +static void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) { + MI_UNUSED(zone); + return mi_malloc_aligned(size,alignment); +} + +static void zone_destroy(malloc_zone_t* zone) { + MI_UNUSED(zone); + // todo: ignore for now? +} + +static unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) { + size_t i; + for (i = 0; i < count; i++) { + ps[i] = zone_malloc(zone, size); + if (ps[i] == NULL) break; + } + return i; +} + +static void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) { + for(size_t i = 0; i < count; i++) { + zone_free(zone, ps[i]); + ps[i] = NULL; + } +} + +static size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); MI_UNUSED(size); + mi_collect(false); + return 0; +} + +static void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) { + MI_UNUSED(size); + zone_free(zone,p); +} + +static boolean_t zone_claimed_address(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); + return mi_is_in_heap_region(p); +} + + +/* ------------------------------------------------------ + Introspection members +------------------------------------------------------ */ + +static kern_return_t intro_enumerator(task_t task, void* p, + unsigned type_mask, vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + // todo: enumerate all memory + MI_UNUSED(task); MI_UNUSED(p); MI_UNUSED(type_mask); MI_UNUSED(zone_address); + MI_UNUSED(reader); MI_UNUSED(recorder); + return KERN_SUCCESS; +} + +static size_t intro_good_size(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); + return mi_good_size(size); +} + +static boolean_t intro_check(malloc_zone_t* zone) { + MI_UNUSED(zone); + return true; +} + +static void intro_print(malloc_zone_t* zone, boolean_t verbose) { + MI_UNUSED(zone); MI_UNUSED(verbose); + mi_stats_print(NULL); +} + +static void intro_log(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); MI_UNUSED(p); + // todo? +} + +static void intro_force_lock(malloc_zone_t* zone) { + MI_UNUSED(zone); + // todo? +} + +static void intro_force_unlock(malloc_zone_t* zone) { + MI_UNUSED(zone); + // todo? +} + +static void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { + MI_UNUSED(zone); + // todo... + stats->blocks_in_use = 0; + stats->size_in_use = 0; + stats->max_size_in_use = 0; + stats->size_allocated = 0; +} + +static boolean_t intro_zone_locked(malloc_zone_t* zone) { + MI_UNUSED(zone); + return false; +} + + +/* ------------------------------------------------------ + At process start, override the default allocator +------------------------------------------------------ */ + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wc99-extensions" +#endif + +static malloc_introspection_t mi_introspect = { + .enumerator = &intro_enumerator, + .good_size = &intro_good_size, + .check = &intro_check, + .print = &intro_print, + .log = &intro_log, + .force_lock = &intro_force_lock, + .force_unlock = &intro_force_unlock, +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__) + .statistics = &intro_statistics, + .zone_locked = &intro_zone_locked, +#endif +}; + +static malloc_zone_t mi_malloc_zone = { + // note: even with designators, the order is important for C++ compilation + //.reserved1 = NULL, + //.reserved2 = NULL, + .size = &zone_size, + .malloc = &zone_malloc, + .calloc = &zone_calloc, + .valloc = &zone_valloc, + .free = &zone_free, + .realloc = &zone_realloc, + .destroy = &zone_destroy, + .zone_name = "mimalloc", + .batch_malloc = &zone_batch_malloc, + .batch_free = &zone_batch_free, + .introspect = &mi_introspect, +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__) + #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14) + .version = 10, + #else + .version = 9, + #endif + // switch to version 9+ on OSX 10.6 to support memalign. + .memalign = &zone_memalign, + .free_definite_size = &zone_free_definite_size, + .pressure_relief = &zone_pressure_relief, + #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14) + .claimed_address = &zone_claimed_address, + #endif +#else + .version = 4, +#endif +}; + +#ifdef __cplusplus +} +#endif + + +#if defined(MI_OSX_INTERPOSE) && defined(MI_SHARED_LIB_EXPORT) + +// ------------------------------------------------------ +// Override malloc_xxx and malloc_zone_xxx api's to use only +// our mimalloc zone. Since even the loader uses malloc +// on macOS, this ensures that all allocations go through +// mimalloc (as all calls are interposed). +// The main `malloc`, `free`, etc calls are interposed in `alloc-override.c`, +// Here, we also override macOS specific API's like +// `malloc_zone_calloc` etc. see <https://github.com/aosm/libmalloc/blob/master/man/malloc_zone_malloc.3> +// ------------------------------------------------------ + +static inline malloc_zone_t* mi_get_default_zone(void) +{ + static bool init; + if mi_unlikely(!init) { + init = true; + malloc_zone_register(&mi_malloc_zone); // by calling register we avoid a zone error on free (see <http://eatmyrandom.blogspot.com/2010/03/mallocfree-interception-on-mac-os-x.html>) + } + return &mi_malloc_zone; +} + +mi_decl_externc int malloc_jumpstart(uintptr_t cookie); +mi_decl_externc void _malloc_fork_prepare(void); +mi_decl_externc void _malloc_fork_parent(void); +mi_decl_externc void _malloc_fork_child(void); + + +static malloc_zone_t* mi_malloc_create_zone(vm_size_t size, unsigned flags) { + MI_UNUSED(size); MI_UNUSED(flags); + return mi_get_default_zone(); +} + +static malloc_zone_t* mi_malloc_default_zone (void) { + return mi_get_default_zone(); +} + +static malloc_zone_t* mi_malloc_default_purgeable_zone(void) { + return mi_get_default_zone(); +} + +static void mi_malloc_destroy_zone(malloc_zone_t* zone) { + MI_UNUSED(zone); + // nothing. +} + +static kern_return_t mi_malloc_get_all_zones (task_t task, memory_reader_t mr, vm_address_t** addresses, unsigned* count) { + MI_UNUSED(task); MI_UNUSED(mr); + if (addresses != NULL) *addresses = NULL; + if (count != NULL) *count = 0; + return KERN_SUCCESS; +} + +static const char* mi_malloc_get_zone_name(malloc_zone_t* zone) { + return (zone == NULL ? mi_malloc_zone.zone_name : zone->zone_name); +} + +static void mi_malloc_set_zone_name(malloc_zone_t* zone, const char* name) { + MI_UNUSED(zone); MI_UNUSED(name); +} + +static int mi_malloc_jumpstart(uintptr_t cookie) { + MI_UNUSED(cookie); + return 1; // or 0 for no error? +} + +static void mi__malloc_fork_prepare(void) { + // nothing +} +static void mi__malloc_fork_parent(void) { + // nothing +} +static void mi__malloc_fork_child(void) { + // nothing +} + +static void mi_malloc_printf(const char* fmt, ...) { + MI_UNUSED(fmt); +} + +static bool zone_check(malloc_zone_t* zone) { + MI_UNUSED(zone); + return true; +} + +static malloc_zone_t* zone_from_ptr(const void* p) { + MI_UNUSED(p); + return mi_get_default_zone(); +} + +static void zone_log(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); MI_UNUSED(p); +} + +static void zone_print(malloc_zone_t* zone, bool b) { + MI_UNUSED(zone); MI_UNUSED(b); +} + +static void zone_print_ptr_info(void* p) { + MI_UNUSED(p); +} + +static void zone_register(malloc_zone_t* zone) { + MI_UNUSED(zone); +} + +static void zone_unregister(malloc_zone_t* zone) { + MI_UNUSED(zone); +} + +// use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` +// See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73> +struct mi_interpose_s { + const void* replacement; + const void* target; +}; +#define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } +#define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) +#define MI_INTERPOSE_ZONE(fun) MI_INTERPOSE_FUN(malloc_##fun,fun) +__attribute__((used)) static const struct mi_interpose_s _mi_zone_interposes[] __attribute__((section("__DATA, __interpose"))) = +{ + + MI_INTERPOSE_MI(malloc_create_zone), + MI_INTERPOSE_MI(malloc_default_purgeable_zone), + MI_INTERPOSE_MI(malloc_default_zone), + MI_INTERPOSE_MI(malloc_destroy_zone), + MI_INTERPOSE_MI(malloc_get_all_zones), + MI_INTERPOSE_MI(malloc_get_zone_name), + MI_INTERPOSE_MI(malloc_jumpstart), + MI_INTERPOSE_MI(malloc_printf), + MI_INTERPOSE_MI(malloc_set_zone_name), + MI_INTERPOSE_MI(_malloc_fork_child), + MI_INTERPOSE_MI(_malloc_fork_parent), + MI_INTERPOSE_MI(_malloc_fork_prepare), + + MI_INTERPOSE_ZONE(zone_batch_free), + MI_INTERPOSE_ZONE(zone_batch_malloc), + MI_INTERPOSE_ZONE(zone_calloc), + MI_INTERPOSE_ZONE(zone_check), + MI_INTERPOSE_ZONE(zone_free), + MI_INTERPOSE_ZONE(zone_from_ptr), + MI_INTERPOSE_ZONE(zone_log), + MI_INTERPOSE_ZONE(zone_malloc), + MI_INTERPOSE_ZONE(zone_memalign), + MI_INTERPOSE_ZONE(zone_print), + MI_INTERPOSE_ZONE(zone_print_ptr_info), + MI_INTERPOSE_ZONE(zone_realloc), + MI_INTERPOSE_ZONE(zone_register), + MI_INTERPOSE_ZONE(zone_unregister), + MI_INTERPOSE_ZONE(zone_valloc) +}; + + +#else + +// ------------------------------------------------------ +// hook into the zone api's without interposing +// This is the official way of adding an allocator but +// it seems less robust than using interpose. +// ------------------------------------------------------ + +static inline malloc_zone_t* mi_get_default_zone(void) +{ + // The first returned zone is the real default + malloc_zone_t** zones = NULL; + unsigned count = 0; + kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count); + if (ret == KERN_SUCCESS && count > 0) { + return zones[0]; + } + else { + // fallback + return malloc_default_zone(); + } +} + +#if defined(__clang__) +__attribute__((constructor(0))) +#else +__attribute__((constructor)) // seems not supported by g++-11 on the M1 +#endif +static void _mi_macos_override_malloc(void) { + malloc_zone_t* purgeable_zone = NULL; + + #if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) + // force the purgeable zone to exist to avoid strange bugs + if (malloc_default_purgeable_zone) { + purgeable_zone = malloc_default_purgeable_zone(); + } + #endif + + // Register our zone. + // thomcc: I think this is still needed to put us in the zone list. + malloc_zone_register(&mi_malloc_zone); + // Unregister the default zone, this makes our zone the new default + // as that was the last registered. + malloc_zone_t *default_zone = mi_get_default_zone(); + // thomcc: Unsure if the next test is *always* false or just false in the + // cases I've tried. I'm also unsure if the code inside is needed. at all + if (default_zone != &mi_malloc_zone) { + malloc_zone_unregister(default_zone); + + // Reregister the default zone so free and realloc in that zone keep working. + malloc_zone_register(default_zone); + } + + // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs + // earlier than the default zone. + if (purgeable_zone != NULL) { + malloc_zone_unregister(purgeable_zone); + malloc_zone_register(purgeable_zone); + } + +} +#endif // MI_OSX_INTERPOSE + +#endif // MI_MALLOC_OVERRIDE diff --git a/lib/Utils.Memory/mimalloc/src/prim/osx/prim.c b/lib/Utils.Memory/mimalloc/src/prim/osx/prim.c new file mode 100644 index 0000000..8a2f4e8 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/osx/prim.c @@ -0,0 +1,9 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// We use the unix/prim.c with the mmap API on macOSX +#include "../unix/prim.c" diff --git a/lib/Utils.Memory/mimalloc/src/prim/prim.c b/lib/Utils.Memory/mimalloc/src/prim/prim.c new file mode 100644 index 0000000..9a597d8 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/prim.c @@ -0,0 +1,24 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// Select the implementation of the primitives +// depending on the OS. + +#if defined(_WIN32) +#include "windows/prim.c" // VirtualAlloc (Windows) + +#elif defined(__APPLE__) +#include "osx/prim.c" // macOSX (actually defers to mmap in unix/prim.c) + +#elif defined(__wasi__) +#define MI_USE_SBRK +#include "wasi/prim.c" // memory-grow or sbrk (Wasm) + +#else +#include "unix/prim.c" // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.) + +#endif diff --git a/lib/Utils.Memory/mimalloc/src/prim/readme.md b/lib/Utils.Memory/mimalloc/src/prim/readme.md new file mode 100644 index 0000000..380dd3a --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/readme.md @@ -0,0 +1,9 @@ +## Portability Primitives + +This is the portability layer where all primitives needed from the OS are defined. + +- `include/mimalloc/prim.h`: primitive portability API definition. +- `prim.c`: Selects one of `unix/prim.c`, `wasi/prim.c`, or `windows/prim.c` depending on the host platform + (and on macOS, `osx/prim.c` defers to `unix/prim.c`). + +Note: still work in progress, there may still be places in the sources that still depend on OS ifdef's.
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/src/prim/unix/prim.c b/lib/Utils.Memory/mimalloc/src/prim/unix/prim.c new file mode 100644 index 0000000..314281f --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/unix/prim.c @@ -0,0 +1,859 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// This file is included in `src/prim/prim.c` + +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE // ensure mmap flags and syscall are defined +#endif + +#if defined(__sun) +// illumos provides new mman.h api when any of these are defined +// otherwise the old api based on caddr_t which predates the void pointers one. +// stock solaris provides only the former, chose to atomically to discard those +// flags only here rather than project wide tough. +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + +#include <sys/mman.h> // mmap +#include <unistd.h> // sysconf + +#if defined(__linux__) + #include <features.h> + #include <fcntl.h> + #if defined(__GLIBC__) + #include <linux/mman.h> // linux mmap flags + #else + #include <sys/mman.h> + #endif +#elif defined(__APPLE__) + #include <TargetConditionals.h> + #if !TARGET_IOS_IPHONE && !TARGET_IOS_SIMULATOR + #include <mach/vm_statistics.h> + #endif +#elif defined(__FreeBSD__) || defined(__DragonFly__) + #include <sys/param.h> + #if __FreeBSD_version >= 1200000 + #include <sys/cpuset.h> + #include <sys/domainset.h> + #endif + #include <sys/sysctl.h> +#endif + +#if !defined(__HAIKU__) && !defined(__APPLE__) && !defined(__CYGWIN__) + #define MI_HAS_SYSCALL_H + #include <sys/syscall.h> +#endif + +//------------------------------------------------------------------------------------ +// Use syscalls for some primitives to allow for libraries that override open/read/close etc. +// and do allocation themselves; using syscalls prevents recursion when mimalloc is +// still initializing (issue #713) +//------------------------------------------------------------------------------------ + +#if defined(MI_HAS_SYSCALL_H) && defined(SYS_open) && defined(SYS_close) && defined(SYS_read) && defined(SYS_access) + +static int mi_prim_open(const char* fpath, int open_flags) { + return syscall(SYS_open,fpath,open_flags,0); +} +static ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) { + return syscall(SYS_read,fd,buf,bufsize); +} +static int mi_prim_close(int fd) { + return syscall(SYS_close,fd); +} +static int mi_prim_access(const char *fpath, int mode) { + return syscall(SYS_access,fpath,mode); +} + +#elif !defined(__APPLE__) // avoid unused warnings + +static int mi_prim_open(const char* fpath, int open_flags) { + return open(fpath,open_flags); +} +static ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) { + return read(fd,buf,bufsize); +} +static int mi_prim_close(int fd) { + return close(fd); +} +static int mi_prim_access(const char *fpath, int mode) { + return access(fpath,mode); +} + +#endif + + + +//--------------------------------------------- +// init +//--------------------------------------------- + +static bool unix_detect_overcommit(void) { + bool os_overcommit = true; +#if defined(__linux__) + int fd = mi_prim_open("/proc/sys/vm/overcommit_memory", O_RDONLY); + if (fd >= 0) { + char buf[32]; + ssize_t nread = mi_prim_read(fd, &buf, sizeof(buf)); + mi_prim_close(fd); + // <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting> + // 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE) + if (nread >= 1) { + os_overcommit = (buf[0] == '0' || buf[0] == '1'); + } + } +#elif defined(__FreeBSD__) + int val = 0; + size_t olen = sizeof(val); + if (sysctlbyname("vm.overcommit", &val, &olen, NULL, 0) == 0) { + os_overcommit = (val != 0); + } +#else + // default: overcommit is true +#endif + return os_overcommit; +} + +void _mi_prim_mem_init( mi_os_mem_config_t* config ) { + long psize = sysconf(_SC_PAGESIZE); + if (psize > 0) { + config->page_size = (size_t)psize; + config->alloc_granularity = (size_t)psize; + } + config->large_page_size = 2*MI_MiB; // TODO: can we query the OS for this? + config->has_overcommit = unix_detect_overcommit(); + config->must_free_whole = false; // mmap can free in parts + config->has_virtual_reserve = true; // todo: check if this true for NetBSD? (for anonymous mmap with PROT_NONE) +} + + +//--------------------------------------------- +// free +//--------------------------------------------- + +int _mi_prim_free(void* addr, size_t size ) { + bool err = (munmap(addr, size) == -1); + return (err ? errno : 0); +} + + +//--------------------------------------------- +// mmap +//--------------------------------------------- + +static int unix_madvise(void* addr, size_t size, int advice) { + #if defined(__sun) + return madvise((caddr_t)addr, size, advice); // Solaris needs cast (issue #520) + #else + return madvise(addr, size, advice); + #endif +} + +static void* unix_mmap_prim(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) { + MI_UNUSED(try_alignment); + void* p = NULL; + #if defined(MAP_ALIGNED) // BSD + if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { + size_t n = mi_bsr(try_alignment); + if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB + p = mmap(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd, 0); + if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { + int err = errno; + _mi_warning_message("unable to directly request aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\n", err, err, size, try_alignment, addr); + } + if (p!=MAP_FAILED) return p; + // fall back to regular mmap + } + } + #elif defined(MAP_ALIGN) // Solaris + if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { + p = mmap((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd, 0); // addr parameter is the required alignment + if (p!=MAP_FAILED) return p; + // fall back to regular mmap + } + #endif + #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED) + // on 64-bit systems, use the virtual address area after 2TiB for 4MiB aligned allocations + if (addr == NULL) { + void* hint = _mi_os_get_aligned_hint(try_alignment, size); + if (hint != NULL) { + p = mmap(hint, size, protect_flags, flags, fd, 0); + if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { + #if MI_TRACK_ENABLED // asan sometimes does not instrument errno correctly? + int err = 0; + #else + int err = errno; + #endif + _mi_warning_message("unable to directly request hinted aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\n", err, err, size, try_alignment, hint); + } + if (p!=MAP_FAILED) return p; + // fall back to regular mmap + } + } + #endif + // regular mmap + p = mmap(addr, size, protect_flags, flags, fd, 0); + if (p!=MAP_FAILED) return p; + // failed to allocate + return NULL; +} + +static int unix_mmap_fd(void) { + #if defined(VM_MAKE_TAG) + // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99) + int os_tag = (int)mi_option_get(mi_option_os_tag); + if (os_tag < 100 || os_tag > 255) { os_tag = 100; } + return VM_MAKE_TAG(os_tag); + #else + return -1; + #endif +} + +static void* unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) { + #if !defined(MAP_ANONYMOUS) + #define MAP_ANONYMOUS MAP_ANON + #endif + #if !defined(MAP_NORESERVE) + #define MAP_NORESERVE 0 + #endif + void* p = NULL; + const int fd = unix_mmap_fd(); + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + if (_mi_os_has_overcommit()) { + flags |= MAP_NORESERVE; + } + #if defined(PROT_MAX) + protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD + #endif + // huge page allocation + if ((large_only || _mi_os_use_large_page(size, try_alignment)) && allow_large) { + static _Atomic(size_t) large_page_try_ok; // = 0; + size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); + if (!large_only && try_ok > 0) { + // If the OS is not configured for large OS pages, or the user does not have + // enough permission, the `mmap` will always fail (but it might also fail for other reasons). + // Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times + // to avoid too many failing calls to mmap. + mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); + } + else { + int lflags = flags & ~MAP_NORESERVE; // using NORESERVE on huge pages seems to fail on Linux + int lfd = fd; + #ifdef MAP_ALIGNED_SUPER + lflags |= MAP_ALIGNED_SUPER; + #endif + #ifdef MAP_HUGETLB + lflags |= MAP_HUGETLB; + #endif + #ifdef MAP_HUGE_1GB + static bool mi_huge_pages_available = true; + if ((size % MI_GiB) == 0 && mi_huge_pages_available) { + lflags |= MAP_HUGE_1GB; + } + else + #endif + { + #ifdef MAP_HUGE_2MB + lflags |= MAP_HUGE_2MB; + #endif + } + #ifdef VM_FLAGS_SUPERPAGE_SIZE_2MB + lfd |= VM_FLAGS_SUPERPAGE_SIZE_2MB; + #endif + if (large_only || lflags != flags) { + // try large OS page allocation + *is_large = true; + p = unix_mmap_prim(addr, size, try_alignment, protect_flags, lflags, lfd); + #ifdef MAP_HUGE_1GB + if (p == NULL && (lflags & MAP_HUGE_1GB) != 0) { + mi_huge_pages_available = false; // don't try huge 1GiB pages again + _mi_warning_message("unable to allocate huge (1GiB) page, trying large (2MiB) pages instead (errno: %i)\n", errno); + lflags = ((lflags & ~MAP_HUGE_1GB) | MAP_HUGE_2MB); + p = unix_mmap_prim(addr, size, try_alignment, protect_flags, lflags, lfd); + } + #endif + if (large_only) return p; + if (p == NULL) { + mi_atomic_store_release(&large_page_try_ok, (size_t)8); // on error, don't try again for the next N allocations + } + } + } + } + // regular allocation + if (p == NULL) { + *is_large = false; + p = unix_mmap_prim(addr, size, try_alignment, protect_flags, flags, fd); + if (p != NULL) { + #if defined(MADV_HUGEPAGE) + // Many Linux systems don't allow MAP_HUGETLB but they support instead + // transparent huge pages (THP). Generally, it is not required to call `madvise` with MADV_HUGE + // though since properly aligned allocations will already use large pages if available + // in that case -- in particular for our large regions (in `memory.c`). + // However, some systems only allow THP if called with explicit `madvise`, so + // when large OS pages are enabled for mimalloc, we call `madvise` anyways. + if (allow_large && _mi_os_use_large_page(size, try_alignment)) { + if (unix_madvise(p, size, MADV_HUGEPAGE) == 0) { + *is_large = true; // possibly + }; + } + #elif defined(__sun) + if (allow_large && _mi_os_use_large_page(size, try_alignment)) { + struct memcntl_mha cmd = {0}; + cmd.mha_pagesize = large_os_page_size; + cmd.mha_cmd = MHA_MAPSIZE_VA; + if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) { + *is_large = true; + } + } + #endif + } + } + return p; +} + +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(commit || !allow_large); + mi_assert_internal(try_alignment > 0); + + *is_zero = true; + int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE); + *addr = unix_mmap(NULL, size, try_alignment, protect_flags, false, allow_large, is_large); + return (*addr != NULL ? 0 : errno); +} + + +//--------------------------------------------- +// Commit/Reset +//--------------------------------------------- + +static void unix_mprotect_hint(int err) { + #if defined(__linux__) && (MI_SECURE>=2) // guard page around every mimalloc page + if (err == ENOMEM) { + _mi_warning_message("The next warning may be caused by a low memory map limit.\n" + " On Linux this is controlled by the vm.max_map_count -- maybe increase it?\n" + " For example: sudo sysctl -w vm.max_map_count=262144\n"); + } + #else + MI_UNUSED(err); + #endif +} + +int _mi_prim_commit(void* start, size_t size, bool* is_zero) { + // commit: ensure we can access the area + // note: we may think that *is_zero can be true since the memory + // was either from mmap PROT_NONE, or from decommit MADV_DONTNEED, but + // we sometimes call commit on a range with still partially committed + // memory and `mprotect` does not zero the range. + *is_zero = false; + int err = mprotect(start, size, (PROT_READ | PROT_WRITE)); + if (err != 0) { + err = errno; + unix_mprotect_hint(err); + } + return err; +} + +int _mi_prim_decommit(void* start, size_t size, bool* needs_recommit) { + int err = 0; + // decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE) + err = unix_madvise(start, size, MADV_DONTNEED); + #if !MI_DEBUG && !MI_SECURE + *needs_recommit = false; + #else + *needs_recommit = true; + mprotect(start, size, PROT_NONE); + #endif + /* + // decommit: use mmap with MAP_FIXED and PROT_NONE to discard the existing memory (and reduce rss) + *needs_recommit = true; + const int fd = unix_mmap_fd(); + void* p = mmap(start, size, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), fd, 0); + if (p != start) { err = errno; } + */ + return err; +} + +int _mi_prim_reset(void* start, size_t size) { + // We try to use `MADV_FREE` as that is the fastest. A drawback though is that it + // will not reduce the `rss` stats in tools like `top` even though the memory is available + // to other processes. With the default `MIMALLOC_PURGE_DECOMMITS=1` we ensure that by + // default `MADV_DONTNEED` is used though. + #if defined(MADV_FREE) + static _Atomic(size_t) advice = MI_ATOMIC_VAR_INIT(MADV_FREE); + int oadvice = (int)mi_atomic_load_relaxed(&advice); + int err; + while ((err = unix_madvise(start, size, oadvice)) != 0 && errno == EAGAIN) { errno = 0; }; + if (err != 0 && errno == EINVAL && oadvice == MADV_FREE) { + // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on + mi_atomic_store_release(&advice, (size_t)MADV_DONTNEED); + err = unix_madvise(start, size, MADV_DONTNEED); + } + #else + int err = unix_madvise(start, size, MADV_DONTNEED); + #endif + return err; +} + +int _mi_prim_protect(void* start, size_t size, bool protect) { + int err = mprotect(start, size, protect ? PROT_NONE : (PROT_READ | PROT_WRITE)); + if (err != 0) { err = errno; } + unix_mprotect_hint(err); + return err; +} + + + +//--------------------------------------------- +// Huge page allocation +//--------------------------------------------- + +#if (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) && !defined(__CYGWIN__) + +#ifndef MPOL_PREFERRED +#define MPOL_PREFERRED 1 +#endif + +#if defined(MI_HAS_SYSCALL_H) && defined(SYS_mbind) +static long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { + return syscall(SYS_mbind, start, len, mode, nmask, maxnode, flags); +} +#else +static long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { + MI_UNUSED(start); MI_UNUSED(len); MI_UNUSED(mode); MI_UNUSED(nmask); MI_UNUSED(maxnode); MI_UNUSED(flags); + return 0; +} +#endif + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + bool is_large = true; + *is_zero = true; + *addr = unix_mmap(hint_addr, size, MI_SEGMENT_SIZE, PROT_READ | PROT_WRITE, true, true, &is_large); + if (*addr != NULL && numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes + unsigned long numa_mask = (1UL << numa_node); + // TODO: does `mbind` work correctly for huge OS pages? should we + // use `set_mempolicy` before calling mmap instead? + // see: <https://lkml.org/lkml/2017/2/9/875> + long err = mi_prim_mbind(*addr, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0); + if (err != 0) { + err = errno; + _mi_warning_message("failed to bind huge (1GiB) pages to numa node %d (error: %d (0x%x))\n", numa_node, err, err); + } + } + return (*addr != NULL ? 0 : errno); +} + +#else + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node); + *is_zero = false; + *addr = NULL; + return ENOMEM; +} + +#endif + +//--------------------------------------------- +// NUMA nodes +//--------------------------------------------- + +#if defined(__linux__) + +#include <stdio.h> // snprintf + +size_t _mi_prim_numa_node(void) { + #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getcpu) + unsigned long node = 0; + unsigned long ncpu = 0; + long err = syscall(SYS_getcpu, &ncpu, &node, NULL); + if (err != 0) return 0; + return node; + #else + return 0; + #endif +} + +size_t _mi_prim_numa_node_count(void) { + char buf[128]; + unsigned node = 0; + for(node = 0; node < 256; node++) { + // enumerate node entries -- todo: it there a more efficient way to do this? (but ensure there is no allocation) + snprintf(buf, 127, "/sys/devices/system/node/node%u", node + 1); + if (mi_prim_access(buf,R_OK) != 0) break; + } + return (node+1); +} + +#elif defined(__FreeBSD__) && __FreeBSD_version >= 1200000 + +size_t _mi_prim_numa_node(void) { + domainset_t dom; + size_t node; + int policy; + if (cpuset_getdomain(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(dom), &dom, &policy) == -1) return 0ul; + for (node = 0; node < MAXMEMDOM; node++) { + if (DOMAINSET_ISSET(node, &dom)) return node; + } + return 0ul; +} + +size_t _mi_prim_numa_node_count(void) { + size_t ndomains = 0; + size_t len = sizeof(ndomains); + if (sysctlbyname("vm.ndomains", &ndomains, &len, NULL, 0) == -1) return 0ul; + return ndomains; +} + +#elif defined(__DragonFly__) + +size_t _mi_prim_numa_node(void) { + // TODO: DragonFly does not seem to provide any userland means to get this information. + return 0ul; +} + +size_t _mi_prim_numa_node_count(void) { + size_t ncpus = 0, nvirtcoresperphys = 0; + size_t len = sizeof(size_t); + if (sysctlbyname("hw.ncpu", &ncpus, &len, NULL, 0) == -1) return 0ul; + if (sysctlbyname("hw.cpu_topology_ht_ids", &nvirtcoresperphys, &len, NULL, 0) == -1) return 0ul; + return nvirtcoresperphys * ncpus; +} + +#else + +size_t _mi_prim_numa_node(void) { + return 0; +} + +size_t _mi_prim_numa_node_count(void) { + return 1; +} + +#endif + +// ---------------------------------------------------------------- +// Clock +// ---------------------------------------------------------------- + +#include <time.h> + +#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) + +mi_msecs_t _mi_prim_clock_now(void) { + struct timespec t; + #ifdef CLOCK_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, &t); + #else + clock_gettime(CLOCK_REALTIME, &t); + #endif + return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000); +} + +#else + +// low resolution timer +mi_msecs_t _mi_prim_clock_now(void) { + #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0) + return (mi_msecs_t)clock(); + #elif (CLOCKS_PER_SEC < 1000) + return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC); + #else + return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000); + #endif +} + +#endif + + + + +//---------------------------------------------------------------- +// Process info +//---------------------------------------------------------------- + +#if defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__) +#include <stdio.h> +#include <unistd.h> +#include <sys/resource.h> + +#if defined(__APPLE__) +#include <mach/mach.h> +#endif + +#if defined(__HAIKU__) +#include <kernel/OS.h> +#endif + +static mi_msecs_t timeval_secs(const struct timeval* tv) { + return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L); +} + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + struct rusage rusage; + getrusage(RUSAGE_SELF, &rusage); + pinfo->utime = timeval_secs(&rusage.ru_utime); + pinfo->stime = timeval_secs(&rusage.ru_stime); +#if !defined(__HAIKU__) + pinfo->page_faults = rusage.ru_majflt; +#endif +#if defined(__HAIKU__) + // Haiku does not have (yet?) a way to + // get these stats per process + thread_info tid; + area_info mem; + ssize_t c; + get_thread_info(find_thread(0), &tid); + while (get_next_area_info(tid.team, &c, &mem) == B_OK) { + pinfo->peak_rss += mem.ram_size; + } + pinfo->page_faults = 0; +#elif defined(__APPLE__) + pinfo->peak_rss = rusage.ru_maxrss; // macos reports in bytes + #ifdef MACH_TASK_BASIC_INFO + struct mach_task_basic_info info; + mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; + if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { + pinfo->current_rss = (size_t)info.resident_size; + } + #else + struct task_basic_info info; + mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT; + if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { + pinfo->current_rss = (size_t)info.resident_size; + } + #endif +#else + pinfo->peak_rss = rusage.ru_maxrss * 1024; // Linux/BSD report in KiB +#endif + // use defaults for commit +} + +#else + +#ifndef __wasi__ +// WebAssembly instances are not processes +#pragma message("define a way to get process info") +#endif + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + // use defaults + MI_UNUSED(pinfo); +} + +#endif + + +//---------------------------------------------------------------- +// Output +//---------------------------------------------------------------- + +void _mi_prim_out_stderr( const char* msg ) { + fputs(msg,stderr); +} + + +//---------------------------------------------------------------- +// Environment +//---------------------------------------------------------------- + +#if !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0) +// On Posix systemsr use `environ` to access environment variables +// even before the C runtime is initialized. +#if defined(__APPLE__) && defined(__has_include) && __has_include(<crt_externs.h>) +#include <crt_externs.h> +static char** mi_get_environ(void) { + return (*_NSGetEnviron()); +} +#else +extern char** environ; +static char** mi_get_environ(void) { + return environ; +} +#endif +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + if (name==NULL) return false; + const size_t len = _mi_strlen(name); + if (len == 0) return false; + char** env = mi_get_environ(); + if (env == NULL) return false; + // compare up to 10000 entries + for (int i = 0; i < 10000 && env[i] != NULL; i++) { + const char* s = env[i]; + if (_mi_strnicmp(name, s, len) == 0 && s[len] == '=') { // case insensitive + // found it + _mi_strlcpy(result, s + len + 1, result_size); + return true; + } + } + return false; +} +#else +// fallback: use standard C `getenv` but this cannot be used while initializing the C runtime +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + // cannot call getenv() when still initializing the C runtime. + if (_mi_preloading()) return false; + const char* s = getenv(name); + if (s == NULL) { + // we check the upper case name too. + char buf[64+1]; + size_t len = _mi_strnlen(name,sizeof(buf)-1); + for (size_t i = 0; i < len; i++) { + buf[i] = _mi_toupper(name[i]); + } + buf[len] = 0; + s = getenv(buf); + } + if (s == NULL || _mi_strnlen(s,result_size) >= result_size) return false; + _mi_strlcpy(result, s, result_size); + return true; +} +#endif // !MI_USE_ENVIRON + + +//---------------------------------------------------------------- +// Random +//---------------------------------------------------------------- + +#if defined(__APPLE__) + +#include <AvailabilityMacros.h> +#if defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 +#include <CommonCrypto/CommonCryptoError.h> +#include <CommonCrypto/CommonRandom.h> +#endif +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + // We prefere CCRandomGenerateBytes as it returns an error code while arc4random_buf + // may fail silently on macOS. See PR #390, and <https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html> + return (CCRandomGenerateBytes(buf, buf_len) == kCCSuccess); + #else + // fall back on older macOS + arc4random_buf(buf, buf_len); + return true; + #endif +} + +#elif defined(__ANDROID__) || defined(__DragonFly__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__sun) + +#include <stdlib.h> +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + arc4random_buf(buf, buf_len); + return true; +} + +#elif defined(__linux__) || defined(__HAIKU__) + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + // Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h` + // and for the latter the actual `getrandom` call is not always defined. + // (see <https://stackoverflow.com/questions/45237324/why-doesnt-getrandom-compile>) + // We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed. + #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getrandom) + #ifndef GRND_NONBLOCK + #define GRND_NONBLOCK (1) + #endif + static _Atomic(uintptr_t) no_getrandom; // = 0 + if (mi_atomic_load_acquire(&no_getrandom)==0) { + ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK); + if (ret >= 0) return (buf_len == (size_t)ret); + if (errno != ENOSYS) return false; + mi_atomic_store_release(&no_getrandom, (uintptr_t)1); // don't call again, and fall back to /dev/urandom + } + #endif + int flags = O_RDONLY; + #if defined(O_CLOEXEC) + flags |= O_CLOEXEC; + #endif + int fd = mi_prim_open("/dev/urandom", flags); + if (fd < 0) return false; + size_t count = 0; + while(count < buf_len) { + ssize_t ret = mi_prim_read(fd, (char*)buf + count, buf_len - count); + if (ret<=0) { + if (errno!=EAGAIN && errno!=EINTR) break; + } + else { + count += ret; + } + } + mi_prim_close(fd); + return (count==buf_len); +} + +#else + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + return false; +} + +#endif + + +//---------------------------------------------------------------- +// Thread init/done +//---------------------------------------------------------------- + +#if defined(MI_USE_PTHREADS) + +// use pthread local storage keys to detect thread ending +// (and used with MI_TLS_PTHREADS for the default heap) +pthread_key_t _mi_heap_default_key = (pthread_key_t)(-1); + +static void mi_pthread_done(void* value) { + if (value!=NULL) { + _mi_thread_done((mi_heap_t*)value); + } +} + +void _mi_prim_thread_init_auto_done(void) { + mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1)); + pthread_key_create(&_mi_heap_default_key, &mi_pthread_done); +} + +void _mi_prim_thread_done_auto_done(void) { + // nothing to do +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + if (_mi_heap_default_key != (pthread_key_t)(-1)) { // can happen during recursive invocation on freeBSD + pthread_setspecific(_mi_heap_default_key, heap); + } +} + +#else + +void _mi_prim_thread_init_auto_done(void) { + // nothing +} + +void _mi_prim_thread_done_auto_done(void) { + // nothing +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + MI_UNUSED(heap); +} + +#endif diff --git a/lib/Utils.Memory/mimalloc/src/prim/wasi/prim.c b/lib/Utils.Memory/mimalloc/src/prim/wasi/prim.c new file mode 100644 index 0000000..50511f0 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/wasi/prim.c @@ -0,0 +1,275 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// This file is included in `src/prim/prim.c` + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + +//--------------------------------------------- +// Initialize +//--------------------------------------------- + +void _mi_prim_mem_init( mi_os_mem_config_t* config ) { + config->page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB + config->alloc_granularity = 16; + config->has_overcommit = false; + config->must_free_whole = true; + config->has_virtual_reserve = false; +} + +//--------------------------------------------- +// Free +//--------------------------------------------- + +int _mi_prim_free(void* addr, size_t size ) { + MI_UNUSED(addr); MI_UNUSED(size); + // wasi heap cannot be shrunk + return 0; +} + + +//--------------------------------------------- +// Allocation: sbrk or memory_grow +//--------------------------------------------- + +#if defined(MI_USE_SBRK) + static void* mi_memory_grow( size_t size ) { + void* p = sbrk(size); + if (p == (void*)(-1)) return NULL; + #if !defined(__wasi__) // on wasi this is always zero initialized already (?) + memset(p,0,size); + #endif + return p; + } +#elif defined(__wasi__) + static void* mi_memory_grow( size_t size ) { + size_t base = (size > 0 ? __builtin_wasm_memory_grow(0,_mi_divide_up(size, _mi_os_page_size())) + : __builtin_wasm_memory_size(0)); + if (base == SIZE_MAX) return NULL; + return (void*)(base * _mi_os_page_size()); + } +#endif + +#if defined(MI_USE_PTHREADS) +static pthread_mutex_t mi_heap_grow_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +static void* mi_prim_mem_grow(size_t size, size_t try_alignment) { + void* p = NULL; + if (try_alignment <= 1) { + // `sbrk` is not thread safe in general so try to protect it (we could skip this on WASM but leave it in for now) + #if defined(MI_USE_PTHREADS) + pthread_mutex_lock(&mi_heap_grow_mutex); + #endif + p = mi_memory_grow(size); + #if defined(MI_USE_PTHREADS) + pthread_mutex_unlock(&mi_heap_grow_mutex); + #endif + } + else { + void* base = NULL; + size_t alloc_size = 0; + // to allocate aligned use a lock to try to avoid thread interaction + // between getting the current size and actual allocation + // (also, `sbrk` is not thread safe in general) + #if defined(MI_USE_PTHREADS) + pthread_mutex_lock(&mi_heap_grow_mutex); + #endif + { + void* current = mi_memory_grow(0); // get current size + if (current != NULL) { + void* aligned_current = mi_align_up_ptr(current, try_alignment); // and align from there to minimize wasted space + alloc_size = _mi_align_up( ((uint8_t*)aligned_current - (uint8_t*)current) + size, _mi_os_page_size()); + base = mi_memory_grow(alloc_size); + } + } + #if defined(MI_USE_PTHREADS) + pthread_mutex_unlock(&mi_heap_grow_mutex); + #endif + if (base != NULL) { + p = mi_align_up_ptr(base, try_alignment); + if ((uint8_t*)p + size > (uint8_t*)base + alloc_size) { + // another thread used wasm_memory_grow/sbrk in-between and we do not have enough + // space after alignment. Give up (and waste the space as we cannot shrink :-( ) + // (in `mi_os_mem_alloc_aligned` this will fall back to overallocation to align) + p = NULL; + } + } + } + /* + if (p == NULL) { + _mi_warning_message("unable to allocate sbrk/wasm_memory_grow OS memory (%zu bytes, %zu alignment)\n", size, try_alignment); + errno = ENOMEM; + return NULL; + } + */ + mi_assert_internal( p == NULL || try_alignment == 0 || (uintptr_t)p % try_alignment == 0 ); + return p; +} + +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) { + MI_UNUSED(allow_large); MI_UNUSED(commit); + *is_large = false; + *is_zero = false; + *addr = mi_prim_mem_grow(size, try_alignment); + return (*addr != NULL ? 0 : ENOMEM); +} + + +//--------------------------------------------- +// Commit/Reset/Protect +//--------------------------------------------- + +int _mi_prim_commit(void* addr, size_t size, bool* is_zero) { + MI_UNUSED(addr); MI_UNUSED(size); + *is_zero = false; + return 0; +} + +int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) { + MI_UNUSED(addr); MI_UNUSED(size); + *needs_recommit = false; + return 0; +} + +int _mi_prim_reset(void* addr, size_t size) { + MI_UNUSED(addr); MI_UNUSED(size); + return 0; +} + +int _mi_prim_protect(void* addr, size_t size, bool protect) { + MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(protect); + return 0; +} + + +//--------------------------------------------- +// Huge pages and NUMA nodes +//--------------------------------------------- + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node); + *is_zero = true; + *addr = NULL; + return ENOSYS; +} + +size_t _mi_prim_numa_node(void) { + return 0; +} + +size_t _mi_prim_numa_node_count(void) { + return 1; +} + + +//---------------------------------------------------------------- +// Clock +//---------------------------------------------------------------- + +#include <time.h> + +#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) + +mi_msecs_t _mi_prim_clock_now(void) { + struct timespec t; + #ifdef CLOCK_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, &t); + #else + clock_gettime(CLOCK_REALTIME, &t); + #endif + return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000); +} + +#else + +// low resolution timer +mi_msecs_t _mi_prim_clock_now(void) { + #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0) + return (mi_msecs_t)clock(); + #elif (CLOCKS_PER_SEC < 1000) + return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC); + #else + return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000); + #endif +} + +#endif + + +//---------------------------------------------------------------- +// Process info +//---------------------------------------------------------------- + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + // use defaults + MI_UNUSED(pinfo); +} + + +//---------------------------------------------------------------- +// Output +//---------------------------------------------------------------- + +void _mi_prim_out_stderr( const char* msg ) { + fputs(msg,stderr); +} + + +//---------------------------------------------------------------- +// Environment +//---------------------------------------------------------------- + +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + // cannot call getenv() when still initializing the C runtime. + if (_mi_preloading()) return false; + const char* s = getenv(name); + if (s == NULL) { + // we check the upper case name too. + char buf[64+1]; + size_t len = _mi_strnlen(name,sizeof(buf)-1); + for (size_t i = 0; i < len; i++) { + buf[i] = _mi_toupper(name[i]); + } + buf[len] = 0; + s = getenv(buf); + } + if (s == NULL || _mi_strnlen(s,result_size) >= result_size) return false; + _mi_strlcpy(result, s, result_size); + return true; +} + + +//---------------------------------------------------------------- +// Random +//---------------------------------------------------------------- + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + return false; +} + + +//---------------------------------------------------------------- +// Thread init/done +//---------------------------------------------------------------- + +void _mi_prim_thread_init_auto_done(void) { + // nothing +} + +void _mi_prim_thread_done_auto_done(void) { + // nothing +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + MI_UNUSED(heap); +} diff --git a/lib/Utils.Memory/mimalloc/src/prim/windows/etw-mimalloc.wprp b/lib/Utils.Memory/mimalloc/src/prim/windows/etw-mimalloc.wprp new file mode 100644 index 0000000..b00cd7a --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/windows/etw-mimalloc.wprp @@ -0,0 +1,61 @@ +<WindowsPerformanceRecorder Version="1.0"> + <Profiles> + <SystemCollector Id="WPR_initiated_WprApp_WPR_System_Collector" Name="WPR_initiated_WprApp_WPR System Collector"> + <BufferSize Value="1024" /> + <Buffers Value="100" /> + </SystemCollector> + <EventCollector Id="Mimalloc_Collector" Name="Mimalloc Collector"> + <BufferSize Value="1024" /> + <Buffers Value="100" /> + </EventCollector> + <SystemProvider Id="WPR_initiated_WprApp_WPR_System_Collector_Provider"> + <Keywords> + <Keyword Value="Loader" /> + </Keywords> + </SystemProvider> + <EventProvider Id="MimallocEventProvider" Name="138f4dbb-ee04-4899-aa0a-572ad4475779" NonPagedMemory="true" Stack="true"> + <EventFilters FilterIn="true"> + <EventId Value="100" /> + <EventId Value="101" /> + </EventFilters> + </EventProvider> + <Profile Id="CustomHeap.Verbose.File" Name="CustomHeap" Description="RunningProfile:CustomHeap.Verbose.File" LoggingMode="File" DetailLevel="Verbose"> + <ProblemCategories> + <ProblemCategory Value="Resource Analysis" /> + </ProblemCategories> + <Collectors> + <SystemCollectorId Value="WPR_initiated_WprApp_WPR_System_Collector"> + <SystemProviderId Value="WPR_initiated_WprApp_WPR_System_Collector_Provider" /> + </SystemCollectorId> + <EventCollectorId Value="Mimalloc_Collector"> + <EventProviders> + <EventProviderId Value="MimallocEventProvider" > + <Keywords> + <Keyword Value="100"/> + <Keyword Value="101"/> + </Keywords> + </EventProviderId> + </EventProviders> + </EventCollectorId> + </Collectors> + <TraceMergeProperties> + <TraceMergeProperty Id="BaseVerboseTraceMergeProperties" Name="BaseTraceMergeProperties"> + <DeletePreMergedTraceFiles Value="true" /> + <FileCompression Value="false" /> + <InjectOnly Value="false" /> + <SkipMerge Value="false" /> + <CustomEvents> + <CustomEvent Value="ImageId" /> + <CustomEvent Value="BuildInfo" /> + <CustomEvent Value="VolumeMapping" /> + <CustomEvent Value="EventMetadata" /> + <CustomEvent Value="PerfTrackMetadata" /> + <CustomEvent Value="WinSAT" /> + <CustomEvent Value="NetworkInterface" /> + </CustomEvents> + </TraceMergeProperty> + </TraceMergeProperties> + </Profile> + </Profiles> +</WindowsPerformanceRecorder> + diff --git a/lib/Utils.Memory/mimalloc/src/prim/windows/etw.h b/lib/Utils.Memory/mimalloc/src/prim/windows/etw.h new file mode 100644 index 0000000..4e0a092 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/windows/etw.h @@ -0,0 +1,905 @@ +//**********************************************************************` +//* This is an include file generated by Message Compiler. *` +//* *` +//* Copyright (c) Microsoft Corporation. All Rights Reserved. *` +//**********************************************************************` +#pragma once + +//***************************************************************************** +// +// Notes on the ETW event code generated by MC: +// +// - Structures and arrays of structures are treated as an opaque binary blob. +// The caller is responsible for packing the data for the structure into a +// single region of memory, with no padding between values. The macro will +// have an extra parameter for the length of the blob. +// - Arrays of nul-terminated strings must be packed by the caller into a +// single binary blob containing the correct number of strings, with a nul +// after each string. The size of the blob is specified in characters, and +// includes the final nul. +// - Arrays of SID are treated as a single binary blob. The caller is +// responsible for packing the SID values into a single region of memory with +// no padding. +// - The length attribute on the data element in the manifest is significant +// for values with intype win:UnicodeString, win:AnsiString, or win:Binary. +// The length attribute must be specified for win:Binary, and is optional for +// win:UnicodeString and win:AnsiString (if no length is given, the strings +// are assumed to be nul-terminated). For win:UnicodeString, the length is +// measured in characters, not bytes. +// - For an array of win:UnicodeString, win:AnsiString, or win:Binary, the +// length attribute applies to every value in the array, so every value in +// the array must have the same length. The values in the array are provided +// to the macro via a single pointer -- the caller is responsible for packing +// all of the values into a single region of memory with no padding between +// values. +// - Values of type win:CountedUnicodeString, win:CountedAnsiString, and +// win:CountedBinary can be generated and collected on Vista or later. +// However, they may not decode properly without the Windows 10 2018 Fall +// Update. +// - Arrays of type win:CountedUnicodeString, win:CountedAnsiString, and +// win:CountedBinary must be packed by the caller into a single region of +// memory. The format for each item is a UINT16 byte-count followed by that +// many bytes of data. When providing the array to the generated macro, you +// must provide the total size of the packed array data, including the UINT16 +// sizes for each item. In the case of win:CountedUnicodeString, the data +// size is specified in WCHAR (16-bit) units. In the case of +// win:CountedAnsiString and win:CountedBinary, the data size is specified in +// bytes. +// +//***************************************************************************** + +#include <wmistr.h> +#include <evntrace.h> +#include <evntprov.h> + +#ifndef ETW_INLINE + #ifdef _ETW_KM_ + // In kernel mode, save stack space by never inlining templates. + #define ETW_INLINE DECLSPEC_NOINLINE __inline + #else + // In user mode, save code size by inlining templates as appropriate. + #define ETW_INLINE __inline + #endif +#endif // ETW_INLINE + +#if defined(__cplusplus) +extern "C" { +#endif + +// +// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro: +// Define this macro to have the compiler skip the generated functions in this +// header. +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// MCGEN_USE_KERNEL_MODE_APIS macro: +// Controls whether the generated code uses kernel-mode or user-mode APIs. +// - Set to 0 to use Windows user-mode APIs such as EventRegister. +// - Set to 1 to use Windows kernel-mode APIs such as EtwRegister. +// Default is based on whether the _ETW_KM_ macro is defined (i.e. by wdm.h). +// Note that the APIs can also be overridden directly, e.g. by setting the +// MCGEN_EVENTWRITETRANSFER or MCGEN_EVENTREGISTER macros. +// +#ifndef MCGEN_USE_KERNEL_MODE_APIS + #ifdef _ETW_KM_ + #define MCGEN_USE_KERNEL_MODE_APIS 1 + #else + #define MCGEN_USE_KERNEL_MODE_APIS 0 + #endif +#endif // MCGEN_USE_KERNEL_MODE_APIS + +// +// MCGEN_HAVE_EVENTSETINFORMATION macro: +// Controls how McGenEventSetInformation uses the EventSetInformation API. +// - Set to 0 to disable the use of EventSetInformation +// (McGenEventSetInformation will always return an error). +// - Set to 1 to directly invoke MCGEN_EVENTSETINFORMATION. +// - Set to 2 to to locate EventSetInformation at runtime via GetProcAddress +// (user-mode) or MmGetSystemRoutineAddress (kernel-mode). +// Default is determined as follows: +// - If MCGEN_EVENTSETINFORMATION has been customized, set to 1 +// (i.e. use MCGEN_EVENTSETINFORMATION). +// - Else if the target OS version has EventSetInformation, set to 1 +// (i.e. use MCGEN_EVENTSETINFORMATION). +// - Else set to 2 (i.e. try to dynamically locate EventSetInformation). +// Note that an McGenEventSetInformation function will only be generated if one +// or more provider in a manifest has provider traits. +// +#ifndef MCGEN_HAVE_EVENTSETINFORMATION + #ifdef MCGEN_EVENTSETINFORMATION // if MCGEN_EVENTSETINFORMATION has been customized, + #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...). + #elif MCGEN_USE_KERNEL_MODE_APIS // else if using kernel-mode APIs, + #if NTDDI_VERSION >= 0x06040000 // if target OS is Windows 10 or later, + #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...). + #else // else + #define MCGEN_HAVE_EVENTSETINFORMATION 2 // find "EtwSetInformation" via MmGetSystemRoutineAddress. + #endif // else (using user-mode APIs) + #else // if target OS and SDK is Windows 8 or later, + #if WINVER >= 0x0602 && defined(EVENT_FILTER_TYPE_SCHEMATIZED) + #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...). + #else // else + #define MCGEN_HAVE_EVENTSETINFORMATION 2 // find "EventSetInformation" via GetModuleHandleExW/GetProcAddress. + #endif + #endif +#endif // MCGEN_HAVE_EVENTSETINFORMATION + +// +// MCGEN Override Macros +// +// The following override macros may be defined before including this header +// to control the APIs used by this header: +// +// - MCGEN_EVENTREGISTER +// - MCGEN_EVENTUNREGISTER +// - MCGEN_EVENTSETINFORMATION +// - MCGEN_EVENTWRITETRANSFER +// +// If the the macro is undefined, the MC implementation will default to the +// corresponding ETW APIs. For example, if the MCGEN_EVENTREGISTER macro is +// undefined, the EventRegister[MyProviderName] macro will use EventRegister +// in user mode and will use EtwRegister in kernel mode. +// +// To prevent issues from conflicting definitions of these macros, the value +// of the override macro will be used as a suffix in certain internal function +// names. Because of this, the override macros must follow certain rules: +// +// - The macro must be defined before any MC-generated header is included and +// must not be undefined or redefined after any MC-generated header is +// included. Different translation units (i.e. different .c or .cpp files) +// may set the macros to different values, but within a translation unit +// (within a single .c or .cpp file), the macro must be set once and not +// changed. +// - The override must be an object-like macro, not a function-like macro +// (i.e. the override macro must not have a parameter list). +// - The override macro's value must be a simple identifier, i.e. must be +// something that starts with a letter or '_' and contains only letters, +// numbers, and '_' characters. +// - If the override macro's value is the name of a second object-like macro, +// the second object-like macro must follow the same rules. (The override +// macro's value can also be the name of a function-like macro, in which +// case the function-like macro does not need to follow the same rules.) +// +// For example, the following will cause compile errors: +// +// #define MCGEN_EVENTWRITETRANSFER MyNamespace::MyClass::MyFunction // Value has non-identifier characters (colon). +// #define MCGEN_EVENTWRITETRANSFER GetEventWriteFunctionPointer(7) // Value has non-identifier characters (parentheses). +// #define MCGEN_EVENTWRITETRANSFER(h,e,a,r,c,d) EventWrite(h,e,c,d) // Override is defined as a function-like macro. +// #define MY_OBJECT_LIKE_MACRO MyNamespace::MyClass::MyEventWriteFunction +// #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // Evaluates to something with non-identifier characters (colon). +// +// The following would be ok: +// +// #define MCGEN_EVENTWRITETRANSFER MyEventWriteFunction1 // OK, suffix will be "MyEventWriteFunction1". +// #define MY_OBJECT_LIKE_MACRO MyEventWriteFunction2 +// #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // OK, suffix will be "MyEventWriteFunction2". +// #define MY_FUNCTION_LIKE_MACRO(h,e,a,r,c,d) MyNamespace::MyClass::MyEventWriteFunction3(h,e,c,d) +// #define MCGEN_EVENTWRITETRANSFER MY_FUNCTION_LIKE_MACRO // OK, suffix will be "MY_FUNCTION_LIKE_MACRO". +// +#ifndef MCGEN_EVENTREGISTER + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTREGISTER EtwRegister + #else + #define MCGEN_EVENTREGISTER EventRegister + #endif +#endif // MCGEN_EVENTREGISTER +#ifndef MCGEN_EVENTUNREGISTER + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTUNREGISTER EtwUnregister + #else + #define MCGEN_EVENTUNREGISTER EventUnregister + #endif +#endif // MCGEN_EVENTUNREGISTER +#ifndef MCGEN_EVENTSETINFORMATION + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTSETINFORMATION EtwSetInformation + #else + #define MCGEN_EVENTSETINFORMATION EventSetInformation + #endif +#endif // MCGEN_EVENTSETINFORMATION +#ifndef MCGEN_EVENTWRITETRANSFER + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTWRITETRANSFER EtwWriteTransfer + #else + #define MCGEN_EVENTWRITETRANSFER EventWriteTransfer + #endif +#endif // MCGEN_EVENTWRITETRANSFER + +// +// MCGEN_EVENT_ENABLED macro: +// Override to control how the EventWrite[EventName] macros determine whether +// an event is enabled. The default behavior is for EventWrite[EventName] to +// use the EventEnabled[EventName] macros. +// +#ifndef MCGEN_EVENT_ENABLED +#define MCGEN_EVENT_ENABLED(EventName) EventEnabled##EventName() +#endif + +// +// MCGEN_EVENT_ENABLED_FORCONTEXT macro: +// Override to control how the EventWrite[EventName]_ForContext macros +// determine whether an event is enabled. The default behavior is for +// EventWrite[EventName]_ForContext to use the +// EventEnabled[EventName]_ForContext macros. +// +#ifndef MCGEN_EVENT_ENABLED_FORCONTEXT +#define MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, EventName) EventEnabled##EventName##_ForContext(pContext) +#endif + +// +// MCGEN_ENABLE_CHECK macro: +// Determines whether the specified event would be considered as enabled +// based on the state of the specified context. Slightly faster than calling +// McGenEventEnabled directly. +// +#ifndef MCGEN_ENABLE_CHECK +#define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor)) +#endif + +#if !defined(MCGEN_TRACE_CONTEXT_DEF) +#define MCGEN_TRACE_CONTEXT_DEF +// This structure is for use by MC-generated code and should not be used directly. +typedef struct _MCGEN_TRACE_CONTEXT +{ + TRACEHANDLE RegistrationHandle; + TRACEHANDLE Logger; // Used as pointer to provider traits. + ULONGLONG MatchAnyKeyword; + ULONGLONG MatchAllKeyword; + ULONG Flags; + ULONG IsEnabled; + UCHAR Level; + UCHAR Reserve; + USHORT EnableBitsCount; + PULONG EnableBitMask; + const ULONGLONG* EnableKeyWords; + const UCHAR* EnableLevel; +} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT; +#endif // MCGEN_TRACE_CONTEXT_DEF + +#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF) +#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF +// +// Determines whether an event with a given Level and Keyword would be +// considered as enabled based on the state of the specified context. +// Note that you may want to use MCGEN_ENABLE_CHECK instead of calling this +// function directly. +// +FORCEINLINE +BOOLEAN +McGenLevelKeywordEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ UCHAR Level, + _In_ ULONGLONG Keyword + ) +{ + // + // Check if the event Level is lower than the level at which + // the channel is enabled. + // If the event Level is 0 or the channel is enabled at level 0, + // all levels are enabled. + // + + if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0. + (EnableInfo->Level == 0)) { + + // + // Check if Keyword is enabled + // + + if ((Keyword == (ULONGLONG)0) || + ((Keyword & EnableInfo->MatchAnyKeyword) && + ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) { + return TRUE; + } + } + + return FALSE; +} +#endif // MCGEN_LEVEL_KEYWORD_ENABLED_DEF + +#if !defined(MCGEN_EVENT_ENABLED_DEF) +#define MCGEN_EVENT_ENABLED_DEF +// +// Determines whether the specified event would be considered as enabled based +// on the state of the specified context. Note that you may want to use +// MCGEN_ENABLE_CHECK instead of calling this function directly. +// +FORCEINLINE +BOOLEAN +McGenEventEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ PCEVENT_DESCRIPTOR EventDescriptor + ) +{ + return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword); +} +#endif // MCGEN_EVENT_ENABLED_DEF + +#if !defined(MCGEN_CONTROL_CALLBACK) +#define MCGEN_CONTROL_CALLBACK + +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +VOID +__stdcall +McGenControlCallbackV2( + _In_ LPCGUID SourceId, + _In_ ULONG ControlCode, + _In_ UCHAR Level, + _In_ ULONGLONG MatchAnyKeyword, + _In_ ULONGLONG MatchAllKeyword, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, + _Inout_opt_ PVOID CallbackContext + ) +/*++ + +Routine Description: + + This is the notification callback for Windows Vista and later. + +Arguments: + + SourceId - The GUID that identifies the session that enabled the provider. + + ControlCode - The parameter indicates whether the provider + is being enabled or disabled. + + Level - The level at which the event is enabled. + + MatchAnyKeyword - The bitmask of keywords that the provider uses to + determine the category of events that it writes. + + MatchAllKeyword - This bitmask additionally restricts the category + of events that the provider writes. + + FilterData - The provider-defined data. + + CallbackContext - The context of the callback that is defined when the provider + called EtwRegister to register itself. + +Remarks: + + ETW calls this function to notify provider of enable/disable + +--*/ +{ + PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext; + ULONG Ix; +#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + UNREFERENCED_PARAMETER(SourceId); + UNREFERENCED_PARAMETER(FilterData); +#endif + + if (Ctx == NULL) { + return; + } + + switch (ControlCode) { + + case EVENT_CONTROL_CODE_ENABLE_PROVIDER: + Ctx->Level = Level; + Ctx->MatchAnyKeyword = MatchAnyKeyword; + Ctx->MatchAllKeyword = MatchAllKeyword; + Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER; + + for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) { + if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) { + Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32)); + } else { + Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32)); + } + } + break; + + case EVENT_CONTROL_CODE_DISABLE_PROVIDER: + Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER; + Ctx->Level = 0; + Ctx->MatchAnyKeyword = 0; + Ctx->MatchAllKeyword = 0; + if (Ctx->EnableBitsCount > 0) { +#pragma warning(suppress: 26451) // Arithmetic overflow cannot occur, no matter the value of EnableBitCount + RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG)); + } + break; + + default: + break; + } + +#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + // + // Call user defined callback + // + MCGEN_PRIVATE_ENABLE_CALLBACK_V2( + SourceId, + ControlCode, + Level, + MatchAnyKeyword, + MatchAllKeyword, + FilterData, + CallbackContext + ); +#endif // MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + + return; +} + +#endif // MCGEN_CONTROL_CALLBACK + +#ifndef _mcgen_PENABLECALLBACK + #if MCGEN_USE_KERNEL_MODE_APIS + #define _mcgen_PENABLECALLBACK PETWENABLECALLBACK + #else + #define _mcgen_PENABLECALLBACK PENABLECALLBACK + #endif +#endif // _mcgen_PENABLECALLBACK + +#if !defined(_mcgen_PASTE2) +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_PASTE2(a, b) _mcgen_PASTE2_imp(a, b) +#define _mcgen_PASTE2_imp(a, b) a##b +#endif // _mcgen_PASTE2 + +#if !defined(_mcgen_PASTE3) +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_PASTE3(a, b, c) _mcgen_PASTE3_imp(a, b, c) +#define _mcgen_PASTE3_imp(a, b, c) a##b##_##c +#endif // _mcgen_PASTE3 + +// +// Macro validation +// + +// Validate MCGEN_EVENTREGISTER: + +// Trigger an error if MCGEN_EVENTREGISTER is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER); + +// Trigger an error if MCGEN_EVENTREGISTER is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER) + MCGEN_EVENTREGISTER_must_not_be_redefined_between_headers; + +// Trigger an error if MCGEN_EVENTREGISTER is defined as a function-like macro: +typedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER; +typedef int _mcgen_PASTE2(MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTREGISTER); + +// Validate MCGEN_EVENTUNREGISTER: + +// Trigger an error if MCGEN_EVENTUNREGISTER is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER); + +// Trigger an error if MCGEN_EVENTUNREGISTER is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER) + MCGEN_EVENTUNREGISTER_must_not_be_redefined_between_headers; + +// Trigger an error if MCGEN_EVENTUNREGISTER is defined as a function-like macro: +typedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER; +typedef int _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTUNREGISTER); + +// Validate MCGEN_EVENTSETINFORMATION: + +// Trigger an error if MCGEN_EVENTSETINFORMATION is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION); + +// Trigger an error if MCGEN_EVENTSETINFORMATION is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION) + MCGEN_EVENTSETINFORMATION_must_not_be_redefined_between_headers; + +// Trigger an error if MCGEN_EVENTSETINFORMATION is defined as a function-like macro: +typedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION; +typedef int _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_, MCGEN_EVENTSETINFORMATION); + +// Validate MCGEN_EVENTWRITETRANSFER: + +// Trigger an error if MCGEN_EVENTWRITETRANSFER is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER); + +// Trigger an error if MCGEN_EVENTWRITETRANSFER is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER) + MCGEN_EVENTWRITETRANSFER_must_not_be_redefined_between_headers;; + +// Trigger an error if MCGEN_EVENTWRITETRANSFER is defined as a function-like macro: +typedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER; +typedef int _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_, MCGEN_EVENTWRITETRANSFER); + +#ifndef McGenEventWrite_def +#define McGenEventWrite_def + +// This macro is for use by MC-generated code and should not be used directly. +#define McGenEventWrite _mcgen_PASTE2(McGenEventWrite_, MCGEN_EVENTWRITETRANSFER) + +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventWrite( + _In_ PMCGEN_TRACE_CONTEXT Context, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ LPCGUID ActivityId, + _In_range_(1, 128) ULONG EventDataCount, + _Pre_cap_(EventDataCount) EVENT_DATA_DESCRIPTOR* EventData + ) +{ + const USHORT UNALIGNED* Traits; + + // Some customized MCGEN_EVENTWRITETRANSFER macros might ignore ActivityId. + UNREFERENCED_PARAMETER(ActivityId); + + Traits = (const USHORT UNALIGNED*)(UINT_PTR)Context->Logger; + + if (Traits == NULL) { + EventData[0].Ptr = 0; + EventData[0].Size = 0; + EventData[0].Reserved = 0; + } else { + EventData[0].Ptr = (ULONG_PTR)Traits; + EventData[0].Size = *Traits; + EventData[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA + } + + return MCGEN_EVENTWRITETRANSFER( + Context->RegistrationHandle, + Descriptor, + ActivityId, + NULL, + EventDataCount, + EventData); +} +#endif // McGenEventWrite_def + +#if !defined(McGenEventRegisterUnregister) +#define McGenEventRegisterUnregister + +// This macro is for use by MC-generated code and should not be used directly. +#define McGenEventRegister _mcgen_PASTE2(McGenEventRegister_, MCGEN_EVENTREGISTER) + +#pragma warning(push) +#pragma warning(disable:6103) +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventRegister( + _In_ LPCGUID ProviderId, + _In_opt_ _mcgen_PENABLECALLBACK EnableCallback, + _In_opt_ PVOID CallbackContext, + _Inout_ PREGHANDLE RegHandle + ) +/*++ + +Routine Description: + + This function registers the provider with ETW. + +Arguments: + + ProviderId - Provider ID to register with ETW. + + EnableCallback - Callback to be used. + + CallbackContext - Context for the callback. + + RegHandle - Pointer to registration handle. + +Remarks: + + Should not be called if the provider is already registered (i.e. should not + be called if *RegHandle != 0). Repeatedly registering a provider is a bug + and may indicate a race condition. However, for compatibility with previous + behavior, this function will return SUCCESS in this case. + +--*/ +{ + ULONG Error; + + if (*RegHandle != 0) + { + Error = 0; // ERROR_SUCCESS + } + else + { + Error = MCGEN_EVENTREGISTER(ProviderId, EnableCallback, CallbackContext, RegHandle); + } + + return Error; +} +#pragma warning(pop) + +// This macro is for use by MC-generated code and should not be used directly. +#define McGenEventUnregister _mcgen_PASTE2(McGenEventUnregister_, MCGEN_EVENTUNREGISTER) + +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventUnregister(_Inout_ PREGHANDLE RegHandle) +/*++ + +Routine Description: + + Unregister from ETW and set *RegHandle = 0. + +Arguments: + + RegHandle - the pointer to the provider registration handle + +Remarks: + + If provider has not been registered (i.e. if *RegHandle == 0), + return SUCCESS. It is safe to call McGenEventUnregister even if the + call to McGenEventRegister returned an error. + +--*/ +{ + ULONG Error; + + if(*RegHandle == 0) + { + Error = 0; // ERROR_SUCCESS + } + else + { + Error = MCGEN_EVENTUNREGISTER(*RegHandle); + *RegHandle = (REGHANDLE)0; + } + + return Error; +} + +#endif // McGenEventRegisterUnregister + +#ifndef _mcgen_EVENT_BIT_SET + #if defined(_M_IX86) || defined(_M_X64) + // This macro is for use by MC-generated code and should not be used directly. + #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((((const unsigned char*)EnableBits)[BitPosition >> 3] & (1u << (BitPosition & 7))) != 0) + #else // CPU type + // This macro is for use by MC-generated code and should not be used directly. + #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((EnableBits[BitPosition >> 5] & (1u << (BitPosition & 31))) != 0) + #endif // CPU type +#endif // _mcgen_EVENT_BIT_SET + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Provider "microsoft-windows-mimalloc" event count 2 +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +// Provider GUID = 138f4dbb-ee04-4899-aa0a-572ad4475779 +EXTERN_C __declspec(selectany) const GUID ETW_MI_Provider = {0x138f4dbb, 0xee04, 0x4899, {0xaa, 0x0a, 0x57, 0x2a, 0xd4, 0x47, 0x57, 0x79}}; + +#ifndef ETW_MI_Provider_Traits +#define ETW_MI_Provider_Traits NULL +#endif // ETW_MI_Provider_Traits + +// +// Event Descriptors +// +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_ALLOC = {0x64, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0}; +#define ETW_MI_ALLOC_value 0x64 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_FREE = {0x65, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0}; +#define ETW_MI_FREE_value 0x65 + +// +// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro: +// Define this macro to have the compiler skip the generated functions in this +// header. +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Event Enablement Bits +// These variables are for use by MC-generated code and should not be used directly. +// +EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG microsoft_windows_mimallocEnableBits[1]; +EXTERN_C __declspec(selectany) const ULONGLONG microsoft_windows_mimallocKeywords[1] = {0x0}; +EXTERN_C __declspec(selectany) const unsigned char microsoft_windows_mimallocLevels[1] = {4}; + +// +// Provider context +// +EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT ETW_MI_Provider_Context = {0, (ULONG_PTR)ETW_MI_Provider_Traits, 0, 0, 0, 0, 0, 0, 1, microsoft_windows_mimallocEnableBits, microsoft_windows_mimallocKeywords, microsoft_windows_mimallocLevels}; + +// +// Provider REGHANDLE +// +#define microsoft_windows_mimallocHandle (ETW_MI_Provider_Context.RegistrationHandle) + +// +// This macro is set to 0, indicating that the EventWrite[Name] macros do not +// have an Activity parameter. This is controlled by the -km and -um options. +// +#define ETW_MI_Provider_EventWriteActivity 0 + +// +// Register with ETW using the control GUID specified in the manifest. +// Invoke this macro during module initialization (i.e. program startup, +// DLL process attach, or driver load) to initialize the provider. +// Note that if this function returns an error, the error means that +// will not work, but no action needs to be taken -- even if EventRegister +// returns an error, it is generally safe to use EventWrite and +// EventUnregister macros (they will be no-ops if EventRegister failed). +// +#ifndef EventRegistermicrosoft_windows_mimalloc +#define EventRegistermicrosoft_windows_mimalloc() McGenEventRegister(&ETW_MI_Provider, McGenControlCallbackV2, &ETW_MI_Provider_Context, µsoft_windows_mimallocHandle) +#endif + +// +// Register with ETW using a specific control GUID (i.e. a GUID other than what +// is specified in the manifest). Advanced scenarios only. +// +#ifndef EventRegisterByGuidmicrosoft_windows_mimalloc +#define EventRegisterByGuidmicrosoft_windows_mimalloc(Guid) McGenEventRegister(&(Guid), McGenControlCallbackV2, &ETW_MI_Provider_Context, µsoft_windows_mimallocHandle) +#endif + +// +// Unregister with ETW and close the provider. +// Invoke this macro during module shutdown (i.e. program exit, DLL process +// detach, or driver unload) to unregister the provider. +// Note that you MUST call EventUnregister before DLL or driver unload +// (not optional): failure to unregister a provider before DLL or driver unload +// will result in crashes. +// +#ifndef EventUnregistermicrosoft_windows_mimalloc +#define EventUnregistermicrosoft_windows_mimalloc() McGenEventUnregister(µsoft_windows_mimallocHandle) +#endif + +// +// MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION macro: +// Define this macro to enable support for caller-allocated provider context. +// +#ifdef MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION + +// +// Advanced scenarios: Caller-allocated provider context. +// Use when multiple differently-configured provider handles are needed, +// e.g. for container-aware drivers, one context per container. +// +// Usage: +// +// - Caller enables the feature before including this header, e.g. +// #define MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION 1 +// - Caller allocates memory, e.g. pContext = malloc(sizeof(McGenContext_microsoft_windows_mimalloc)); +// - Caller registers the provider, e.g. EventRegistermicrosoft_windows_mimalloc_ForContext(pContext); +// - Caller writes events, e.g. EventWriteMyEvent_ForContext(pContext, ...); +// - Caller unregisters, e.g. EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext); +// - Caller frees memory, e.g. free(pContext); +// + +typedef struct tagMcGenContext_microsoft_windows_mimalloc { + // The fields of this structure are subject to change and should + // not be accessed directly. To access the provider's REGHANDLE, + // use microsoft_windows_mimallocHandle_ForContext(pContext). + MCGEN_TRACE_CONTEXT Context; + ULONG EnableBits[1]; +} McGenContext_microsoft_windows_mimalloc; + +#define EventRegistermicrosoft_windows_mimalloc_ForContext(pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&ETW_MI_Provider, pContext) +#define EventRegisterByGuidmicrosoft_windows_mimalloc_ForContext(Guid, pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&(Guid), pContext) +#define EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext) McGenEventUnregister(&(pContext)->Context.RegistrationHandle) + +// +// Provider REGHANDLE for caller-allocated context. +// +#define microsoft_windows_mimallocHandle_ForContext(pContext) ((pContext)->Context.RegistrationHandle) + +// This function is for use by MC-generated code and should not be used directly. +// Initialize and register the caller-allocated context. +__inline +ULONG __stdcall +_mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)( + _In_ LPCGUID pProviderId, + _Out_ McGenContext_microsoft_windows_mimalloc* pContext) +{ + RtlZeroMemory(pContext, sizeof(*pContext)); + pContext->Context.Logger = (ULONG_PTR)ETW_MI_Provider_Traits; + pContext->Context.EnableBitsCount = 1; + pContext->Context.EnableBitMask = pContext->EnableBits; + pContext->Context.EnableKeyWords = microsoft_windows_mimallocKeywords; + pContext->Context.EnableLevel = microsoft_windows_mimallocLevels; + return McGenEventRegister( + pProviderId, + McGenControlCallbackV2, + &pContext->Context, + &pContext->Context.RegistrationHandle); +} + +// This function is for use by MC-generated code and should not be used directly. +// Trigger a compile error if called with the wrong parameter type. +FORCEINLINE +_Ret_ McGenContext_microsoft_windows_mimalloc* +_mcgen_CheckContextType_microsoft_windows_mimalloc(_In_ McGenContext_microsoft_windows_mimalloc* pContext) +{ + return pContext; +} + +#endif // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION + +// +// Enablement check macro for event "ETW_MI_ALLOC" +// +#define EventEnabledETW_MI_ALLOC() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0) +#define EventEnabledETW_MI_ALLOC_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0) + +// +// Event write macros for event "ETW_MI_ALLOC" +// +#define EventWriteETW_MI_ALLOC(Address, Size) \ + MCGEN_EVENT_ENABLED(ETW_MI_ALLOC) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) : 0 +#define EventWriteETW_MI_ALLOC_AssumeEnabled(Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) +#define EventWriteETW_MI_ALLOC_ForContext(pContext, Address, Size) \ + MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_ALLOC) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&(pContext)->Context, &ETW_MI_ALLOC, Address, Size) : 0 +#define EventWriteETW_MI_ALLOC_ForContextAssumeEnabled(pContext, Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_ALLOC, Address, Size) + +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER) + +// +// Enablement check macro for event "ETW_MI_FREE" +// +#define EventEnabledETW_MI_FREE() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0) +#define EventEnabledETW_MI_FREE_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0) + +// +// Event write macros for event "ETW_MI_FREE" +// +#define EventWriteETW_MI_FREE(Address, Size) \ + MCGEN_EVENT_ENABLED(ETW_MI_FREE) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) : 0 +#define EventWriteETW_MI_FREE_AssumeEnabled(Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) +#define EventWriteETW_MI_FREE_ForContext(pContext, Address, Size) \ + MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_FREE) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&(pContext)->Context, &ETW_MI_FREE, Address, Size) : 0 +#define EventWriteETW_MI_FREE_ForContextAssumeEnabled(pContext, Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_FREE, Address, Size) + +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_TEMPLATE_FOR_ETW_MI_FREE _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER) + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro: +// Define this macro to have the compiler skip the generated functions in this +// header. +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Template Functions +// + +// +// Function for template "ETW_CUSTOM_HEAP_ALLOC_DATA" (and possibly others). +// This function is for use by MC-generated code and should not be used directly. +// +#ifndef McTemplateU0xx_def +#define McTemplateU0xx_def +ETW_INLINE +ULONG +_mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)( + _In_ PMCGEN_TRACE_CONTEXT Context, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned __int64 _Arg0, + _In_ const unsigned __int64 _Arg1 + ) +{ +#define McTemplateU0xx_ARGCOUNT 2 + + EVENT_DATA_DESCRIPTOR EventData[McTemplateU0xx_ARGCOUNT + 1]; + + EventDataDescCreate(&EventData[1],&_Arg0, sizeof(const unsigned __int64) ); + + EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned __int64) ); + + return McGenEventWrite(Context, Descriptor, NULL, McTemplateU0xx_ARGCOUNT + 1, EventData); +} +#endif // McTemplateU0xx_def + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +#if defined(__cplusplus) +} +#endif diff --git a/lib/Utils.Memory/mimalloc/src/prim/windows/etw.man b/lib/Utils.Memory/mimalloc/src/prim/windows/etw.man Binary files differnew file mode 100644 index 0000000..cfd1f8a --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/windows/etw.man diff --git a/lib/Utils.Memory/mimalloc/src/prim/windows/prim.c b/lib/Utils.Memory/mimalloc/src/prim/windows/prim.c new file mode 100644 index 0000000..e6b6107 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/windows/prim.c @@ -0,0 +1,622 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// This file is included in `src/prim/prim.c` + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" +#include <stdio.h> // fputs, stderr + + +//--------------------------------------------- +// Dynamically bind Windows API points for portability +//--------------------------------------------- + +// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. +// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility) +// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB) +// We define a minimal MEM_EXTENDED_PARAMETER ourselves in order to be able to compile with older SDK's. +typedef enum MI_MEM_EXTENDED_PARAMETER_TYPE_E { + MiMemExtendedParameterInvalidType = 0, + MiMemExtendedParameterAddressRequirements, + MiMemExtendedParameterNumaNode, + MiMemExtendedParameterPartitionHandle, + MiMemExtendedParameterUserPhysicalHandle, + MiMemExtendedParameterAttributeFlags, + MiMemExtendedParameterMax +} MI_MEM_EXTENDED_PARAMETER_TYPE; + +typedef struct DECLSPEC_ALIGN(8) MI_MEM_EXTENDED_PARAMETER_S { + struct { DWORD64 Type : 8; DWORD64 Reserved : 56; } Type; + union { DWORD64 ULong64; PVOID Pointer; SIZE_T Size; HANDLE Handle; DWORD ULong; } Arg; +} MI_MEM_EXTENDED_PARAMETER; + +typedef struct MI_MEM_ADDRESS_REQUIREMENTS_S { + PVOID LowestStartingAddress; + PVOID HighestEndingAddress; + SIZE_T Alignment; +} MI_MEM_ADDRESS_REQUIREMENTS; + +#define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 + +#include <winternl.h> +typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG); +typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG); +static PVirtualAlloc2 pVirtualAlloc2 = NULL; +static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL; + +// Similarly, GetNumaProcesorNodeEx is only supported since Windows 7 +typedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER; + +typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber); +typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber); +typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask); +typedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber); +static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL; +static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL; +static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL; +static PGetNumaProcessorNode pGetNumaProcessorNode = NULL; + +//--------------------------------------------- +// Enable large page support dynamically (if possible) +//--------------------------------------------- + +static bool win_enable_large_os_pages(size_t* large_page_size) +{ + static bool large_initialized = false; + if (large_initialized) return (_mi_os_large_page_size() > 0); + large_initialized = true; + + // Try to see if large OS pages are supported + // To use large pages on Windows, we first need access permission + // Set "Lock pages in memory" permission in the group policy editor + // <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643> + unsigned long err = 0; + HANDLE token = NULL; + BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token); + if (ok) { + TOKEN_PRIVILEGES tp; + ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid); + if (ok) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); + if (ok) { + err = GetLastError(); + ok = (err == ERROR_SUCCESS); + if (ok && large_page_size != NULL) { + *large_page_size = GetLargePageMinimum(); + } + } + } + CloseHandle(token); + } + if (!ok) { + if (err == 0) err = GetLastError(); + _mi_warning_message("cannot enable large OS page support, error %lu\n", err); + } + return (ok!=0); +} + + +//--------------------------------------------- +// Initialize +//--------------------------------------------- + +void _mi_prim_mem_init( mi_os_mem_config_t* config ) +{ + config->has_overcommit = false; + config->must_free_whole = true; + config->has_virtual_reserve = true; + // get the page size + SYSTEM_INFO si; + GetSystemInfo(&si); + if (si.dwPageSize > 0) { config->page_size = si.dwPageSize; } + if (si.dwAllocationGranularity > 0) { config->alloc_granularity = si.dwAllocationGranularity; } + // get the VirtualAlloc2 function + HINSTANCE hDll; + hDll = LoadLibrary(TEXT("kernelbase.dll")); + if (hDll != NULL) { + // use VirtualAlloc2FromApp if possible as it is available to Windows store apps + pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2FromApp"); + if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2"); + FreeLibrary(hDll); + } + // NtAllocateVirtualMemoryEx is used for huge page allocation + hDll = LoadLibrary(TEXT("ntdll.dll")); + if (hDll != NULL) { + pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, "NtAllocateVirtualMemoryEx"); + FreeLibrary(hDll); + } + // Try to use Win7+ numa API + hDll = LoadLibrary(TEXT("kernel32.dll")); + if (hDll != NULL) { + pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx"); + pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx"); + pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx"); + pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNode"); + FreeLibrary(hDll); + } + if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { + win_enable_large_os_pages(&config->large_page_size); + } +} + + +//--------------------------------------------- +// Free +//--------------------------------------------- + +int _mi_prim_free(void* addr, size_t size ) { + MI_UNUSED(size); + DWORD errcode = 0; + bool err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); + if (err) { errcode = GetLastError(); } + if (errcode == ERROR_INVALID_ADDRESS) { + // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside + // the memory region returned by VirtualAlloc; in that case we need to free using + // the start of the region. + MEMORY_BASIC_INFORMATION info = { 0 }; + VirtualQuery(addr, &info, sizeof(info)); + if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)MI_SEGMENT_SIZE) { + errcode = 0; + err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0); + if (err) { errcode = GetLastError(); } + } + } + return (int)errcode; +} + + +//--------------------------------------------- +// VirtualAlloc +//--------------------------------------------- + +static void* win_virtual_alloc_prim(void* addr, size_t size, size_t try_alignment, DWORD flags) { + #if (MI_INTPTR_SIZE >= 8) + // on 64-bit systems, try to use the virtual address area after 2TiB for 4MiB aligned allocations + if (addr == NULL) { + void* hint = _mi_os_get_aligned_hint(try_alignment,size); + if (hint != NULL) { + void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); + if (p != NULL) return p; + _mi_verbose_message("warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags); + // fall through on error + } + } + #endif + // on modern Windows try use VirtualAlloc2 for aligned allocation + if (try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) { + MI_MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 }; + reqs.Alignment = try_alignment; + MI_MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} }; + param.Type.Type = MiMemExtendedParameterAddressRequirements; + param.Arg.Pointer = &reqs; + void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1); + if (p != NULL) return p; + _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags); + // fall through on error + } + // last resort + return VirtualAlloc(addr, size, flags, PAGE_READWRITE); +} + +static void* win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) { + mi_assert_internal(!(large_only && !allow_large)); + static _Atomic(size_t) large_page_try_ok; // = 0; + void* p = NULL; + // Try to allocate large OS pages (2MiB) if allowed or required. + if ((large_only || _mi_os_use_large_page(size, try_alignment)) + && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) { + size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); + if (!large_only && try_ok > 0) { + // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive. + // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times. + mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); + } + else { + // large OS pages must always reserve and commit. + *is_large = true; + p = win_virtual_alloc_prim(addr, size, try_alignment, flags | MEM_LARGE_PAGES); + if (large_only) return p; + // fall back to non-large page allocation on error (`p == NULL`). + if (p == NULL) { + mi_atomic_store_release(&large_page_try_ok,10UL); // on error, don't try again for the next N allocations + } + } + } + // Fall back to regular page allocation + if (p == NULL) { + *is_large = ((flags&MEM_LARGE_PAGES) != 0); + p = win_virtual_alloc_prim(addr, size, try_alignment, flags); + } + //if (p == NULL) { _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); } + return p; +} + +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(commit || !allow_large); + mi_assert_internal(try_alignment > 0); + *is_zero = true; + int flags = MEM_RESERVE; + if (commit) { flags |= MEM_COMMIT; } + *addr = win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large); + return (*addr != NULL ? 0 : (int)GetLastError()); +} + + +//--------------------------------------------- +// Commit/Reset/Protect +//--------------------------------------------- +#ifdef _MSC_VER +#pragma warning(disable:6250) // suppress warning calling VirtualFree without MEM_RELEASE (for decommit) +#endif + +int _mi_prim_commit(void* addr, size_t size, bool* is_zero) { + *is_zero = false; + /* + // zero'ing only happens on an initial commit... but checking upfront seems expensive.. + _MEMORY_BASIC_INFORMATION meminfo; _mi_memzero_var(meminfo); + if (VirtualQuery(addr, &meminfo, size) > 0) { + if ((meminfo.State & MEM_COMMIT) == 0) { + *is_zero = true; + } + } + */ + // commit + void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE); + if (p == NULL) return (int)GetLastError(); + return 0; +} + +int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) { + BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT); + *needs_recommit = true; // for safety, assume always decommitted even in the case of an error. + return (ok ? 0 : (int)GetLastError()); +} + +int _mi_prim_reset(void* addr, size_t size) { + void* p = VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE); + mi_assert_internal(p == addr); + #if 0 + if (p != NULL) { + VirtualUnlock(addr,size); // VirtualUnlock after MEM_RESET removes the memory directly from the working set + } + #endif + return (p != NULL ? 0 : (int)GetLastError()); +} + +int _mi_prim_protect(void* addr, size_t size, bool protect) { + DWORD oldprotect = 0; + BOOL ok = VirtualProtect(addr, size, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect); + return (ok ? 0 : (int)GetLastError()); +} + + +//--------------------------------------------- +// Huge page allocation +//--------------------------------------------- + +static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int numa_node) +{ + const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE; + + win_enable_large_os_pages(NULL); + + MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} }; + // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages + static bool mi_huge_pages_available = true; + if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) { + params[0].Type.Type = MiMemExtendedParameterAttributeFlags; + params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE; + ULONG param_count = 1; + if (numa_node >= 0) { + param_count++; + params[1].Type.Type = MiMemExtendedParameterNumaNode; + params[1].Arg.ULong = (unsigned)numa_node; + } + SIZE_T psize = size; + void* base = hint_addr; + NTSTATUS err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count); + if (err == 0 && base != NULL) { + return base; + } + else { + // fall back to regular large pages + mi_huge_pages_available = false; // don't try further huge pages + _mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err); + } + } + // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation + if (pVirtualAlloc2 != NULL && numa_node >= 0) { + params[0].Type.Type = MiMemExtendedParameterNumaNode; + params[0].Arg.ULong = (unsigned)numa_node; + return (*pVirtualAlloc2)(GetCurrentProcess(), hint_addr, size, flags, PAGE_READWRITE, params, 1); + } + + // otherwise use regular virtual alloc on older windows + return VirtualAlloc(hint_addr, size, flags, PAGE_READWRITE); +} + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + *is_zero = true; + *addr = _mi_prim_alloc_huge_os_pagesx(hint_addr,size,numa_node); + return (*addr != NULL ? 0 : (int)GetLastError()); +} + + +//--------------------------------------------- +// Numa nodes +//--------------------------------------------- + +size_t _mi_prim_numa_node(void) { + USHORT numa_node = 0; + if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) { + // Extended API is supported + MI_PROCESSOR_NUMBER pnum; + (*pGetCurrentProcessorNumberEx)(&pnum); + USHORT nnode = 0; + BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode); + if (ok) { numa_node = nnode; } + } + else if (pGetNumaProcessorNode != NULL) { + // Vista or earlier, use older API that is limited to 64 processors. Issue #277 + DWORD pnum = GetCurrentProcessorNumber(); + UCHAR nnode = 0; + BOOL ok = pGetNumaProcessorNode((UCHAR)pnum, &nnode); + if (ok) { numa_node = nnode; } + } + return numa_node; +} + +size_t _mi_prim_numa_node_count(void) { + ULONG numa_max = 0; + GetNumaHighestNodeNumber(&numa_max); + // find the highest node number that has actual processors assigned to it. Issue #282 + while(numa_max > 0) { + if (pGetNumaNodeProcessorMaskEx != NULL) { + // Extended API is supported + GROUP_AFFINITY affinity; + if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) { + if (affinity.Mask != 0) break; // found the maximum non-empty node + } + } + else { + // Vista or earlier, use older API that is limited to 64 processors. + ULONGLONG mask; + if (GetNumaNodeProcessorMask((UCHAR)numa_max, &mask)) { + if (mask != 0) break; // found the maximum non-empty node + }; + } + // max node was invalid or had no processor assigned, try again + numa_max--; + } + return ((size_t)numa_max + 1); +} + + +//---------------------------------------------------------------- +// Clock +//---------------------------------------------------------------- + +static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) { + static LARGE_INTEGER mfreq; // = 0 + if (mfreq.QuadPart == 0LL) { + LARGE_INTEGER f; + QueryPerformanceFrequency(&f); + mfreq.QuadPart = f.QuadPart/1000LL; + if (mfreq.QuadPart == 0) mfreq.QuadPart = 1; + } + return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart); +} + +mi_msecs_t _mi_prim_clock_now(void) { + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return mi_to_msecs(t); +} + + +//---------------------------------------------------------------- +// Process Info +//---------------------------------------------------------------- + +#include <windows.h> +#include <psapi.h> + +static mi_msecs_t filetime_msecs(const FILETIME* ftime) { + ULARGE_INTEGER i; + i.LowPart = ftime->dwLowDateTime; + i.HighPart = ftime->dwHighDateTime; + mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds + return msecs; +} + +typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD); +static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL; + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + FILETIME ct; + FILETIME ut; + FILETIME st; + FILETIME et; + GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut); + pinfo->utime = filetime_msecs(&ut); + pinfo->stime = filetime_msecs(&st); + + // load psapi on demand + if (pGetProcessMemoryInfo == NULL) { + HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll")); + if (hDll != NULL) { + pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo"); + } + } + + // get process info + PROCESS_MEMORY_COUNTERS info; + memset(&info, 0, sizeof(info)); + if (pGetProcessMemoryInfo != NULL) { + pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); + } + pinfo->current_rss = (size_t)info.WorkingSetSize; + pinfo->peak_rss = (size_t)info.PeakWorkingSetSize; + pinfo->current_commit = (size_t)info.PagefileUsage; + pinfo->peak_commit = (size_t)info.PeakPagefileUsage; + pinfo->page_faults = (size_t)info.PageFaultCount; +} + +//---------------------------------------------------------------- +// Output +//---------------------------------------------------------------- + +void _mi_prim_out_stderr( const char* msg ) +{ + // on windows with redirection, the C runtime cannot handle locale dependent output + // after the main thread closes so we use direct console output. + if (!_mi_preloading()) { + // _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console + static HANDLE hcon = INVALID_HANDLE_VALUE; + static bool hconIsConsole; + if (hcon == INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO sbi; + hcon = GetStdHandle(STD_ERROR_HANDLE); + hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi)); + } + const size_t len = _mi_strlen(msg); + if (len > 0 && len < UINT32_MAX) { + DWORD written = 0; + if (hconIsConsole) { + WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL); + } + else if (hcon != INVALID_HANDLE_VALUE) { + // use direct write if stderr was redirected + WriteFile(hcon, msg, (DWORD)len, &written, NULL); + } + else { + // finally fall back to fputs after all + fputs(msg, stderr); + } + } + } +} + + +//---------------------------------------------------------------- +// Environment +//---------------------------------------------------------------- + +// On Windows use GetEnvironmentVariable instead of getenv to work +// reliably even when this is invoked before the C runtime is initialized. +// i.e. when `_mi_preloading() == true`. +// Note: on windows, environment names are not case sensitive. +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + result[0] = 0; + size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size); + return (len > 0 && len < result_size); +} + + + +//---------------------------------------------------------------- +// Random +//---------------------------------------------------------------- + +#if defined(MI_USE_RTLGENRANDOM) // || defined(__cplusplus) +// We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using +// dynamic overriding, we observed it can raise an exception when compiled with C++, and +// sometimes deadlocks when also running under the VS debugger. +// In contrast, issue #623 implies that on Windows Server 2019 we need to use BCryptGenRandom. +// To be continued.. +#pragma comment (lib,"advapi32.lib") +#define RtlGenRandom SystemFunction036 +mi_decl_externc BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + return (RtlGenRandom(buf, (ULONG)buf_len) != 0); +} + +#else + +#ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG +#define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 +#endif + +typedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG); +static PBCryptGenRandom pBCryptGenRandom = NULL; + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + if (pBCryptGenRandom == NULL) { + HINSTANCE hDll = LoadLibrary(TEXT("bcrypt.dll")); + if (hDll != NULL) { + pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, "BCryptGenRandom"); + } + if (pBCryptGenRandom == NULL) return false; + } + return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0); +} + +#endif // MI_USE_RTLGENRANDOM + +//---------------------------------------------------------------- +// Thread init/done +//---------------------------------------------------------------- + +#if !defined(MI_SHARED_LIB) + +// use thread local storage keys to detect thread ending +#include <fibersapi.h> +#if (_WIN32_WINNT < 0x600) // before Windows Vista +WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback ); +WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex ); +WINBASEAPI BOOL WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData ); +WINBASEAPI BOOL WINAPI FlsFree(_In_ DWORD dwFlsIndex); +#endif + +static DWORD mi_fls_key = (DWORD)(-1); + +static void NTAPI mi_fls_done(PVOID value) { + mi_heap_t* heap = (mi_heap_t*)value; + if (heap != NULL) { + _mi_thread_done(heap); + FlsSetValue(mi_fls_key, NULL); // prevent recursion as _mi_thread_done may set it back to the main heap, issue #672 + } +} + +void _mi_prim_thread_init_auto_done(void) { + mi_fls_key = FlsAlloc(&mi_fls_done); +} + +void _mi_prim_thread_done_auto_done(void) { + // call thread-done on all threads (except the main thread) to prevent + // dangling callback pointer if statically linked with a DLL; Issue #208 + FlsFree(mi_fls_key); +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + mi_assert_internal(mi_fls_key != (DWORD)(-1)); + FlsSetValue(mi_fls_key, heap); +} + +#else + +// Dll; nothing to do as in that case thread_done is handled through the DLL_THREAD_DETACH event. + +void _mi_prim_thread_init_auto_done(void) { +} + +void _mi_prim_thread_done_auto_done(void) { +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + MI_UNUSED(heap); +} + +#endif diff --git a/lib/Utils.Memory/mimalloc/src/prim/windows/readme.md b/lib/Utils.Memory/mimalloc/src/prim/windows/readme.md new file mode 100644 index 0000000..217c3d1 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/prim/windows/readme.md @@ -0,0 +1,17 @@ +## Primitives: + +- `prim.c` contains Windows primitives for OS allocation. + +## Event Tracing for Windows (ETW) + +- `etw.h` is generated from `etw.man` which contains the manifest for mimalloc events. + (100 is an allocation, 101 is for a free) + +- `etw-mimalloc.wprp` is a profile for the Windows Performance Recorder (WPR). + In an admin prompt, you can use: + ``` + > wpr -start src\prim\windows\etw-mimalloc.wprp -filemode + > <my mimalloc program> + > wpr -stop test.etl + ``` + and then open `test.etl` in the Windows Performance Analyzer (WPA).
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/src/random.c b/lib/Utils.Memory/mimalloc/src/random.c new file mode 100644 index 0000000..4fc8b2f --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/random.c @@ -0,0 +1,254 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/prim.h" // _mi_prim_random_buf +#include <string.h> // memset + +/* ---------------------------------------------------------------------------- +We use our own PRNG to keep predictable performance of random number generation +and to avoid implementations that use a lock. We only use the OS provided +random source to initialize the initial seeds. Since we do not need ultimate +performance but we do rely on the security (for secret cookies in secure mode) +we use a cryptographically secure generator (chacha20). +-----------------------------------------------------------------------------*/ + +#define MI_CHACHA_ROUNDS (20) // perhaps use 12 for better performance? + + +/* ---------------------------------------------------------------------------- +Chacha20 implementation as the original algorithm with a 64-bit nonce +and counter: https://en.wikipedia.org/wiki/Salsa20 +The input matrix has sixteen 32-bit values: +Position 0 to 3: constant key +Position 4 to 11: the key +Position 12 to 13: the counter. +Position 14 to 15: the nonce. + +The implementation uses regular C code which compiles very well on modern compilers. +(gcc x64 has no register spills, and clang 6+ uses SSE instructions) +-----------------------------------------------------------------------------*/ + +static inline uint32_t rotl(uint32_t x, uint32_t shift) { + return (x << shift) | (x >> (32 - shift)); +} + +static inline void qround(uint32_t x[16], size_t a, size_t b, size_t c, size_t d) { + x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 16); + x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 12); + x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 8); + x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 7); +} + +static void chacha_block(mi_random_ctx_t* ctx) +{ + // scramble into `x` + uint32_t x[16]; + for (size_t i = 0; i < 16; i++) { + x[i] = ctx->input[i]; + } + for (size_t i = 0; i < MI_CHACHA_ROUNDS; i += 2) { + qround(x, 0, 4, 8, 12); + qround(x, 1, 5, 9, 13); + qround(x, 2, 6, 10, 14); + qround(x, 3, 7, 11, 15); + qround(x, 0, 5, 10, 15); + qround(x, 1, 6, 11, 12); + qround(x, 2, 7, 8, 13); + qround(x, 3, 4, 9, 14); + } + + // add scrambled data to the initial state + for (size_t i = 0; i < 16; i++) { + ctx->output[i] = x[i] + ctx->input[i]; + } + ctx->output_available = 16; + + // increment the counter for the next round + ctx->input[12] += 1; + if (ctx->input[12] == 0) { + ctx->input[13] += 1; + if (ctx->input[13] == 0) { // and keep increasing into the nonce + ctx->input[14] += 1; + } + } +} + +static uint32_t chacha_next32(mi_random_ctx_t* ctx) { + if (ctx->output_available <= 0) { + chacha_block(ctx); + ctx->output_available = 16; // (assign again to suppress static analysis warning) + } + const uint32_t x = ctx->output[16 - ctx->output_available]; + ctx->output[16 - ctx->output_available] = 0; // reset once the data is handed out + ctx->output_available--; + return x; +} + +static inline uint32_t read32(const uint8_t* p, size_t idx32) { + const size_t i = 4*idx32; + return ((uint32_t)p[i+0] | (uint32_t)p[i+1] << 8 | (uint32_t)p[i+2] << 16 | (uint32_t)p[i+3] << 24); +} + +static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t nonce) +{ + // since we only use chacha for randomness (and not encryption) we + // do not _need_ to read 32-bit values as little endian but we do anyways + // just for being compatible :-) + memset(ctx, 0, sizeof(*ctx)); + for (size_t i = 0; i < 4; i++) { + const uint8_t* sigma = (uint8_t*)"expand 32-byte k"; + ctx->input[i] = read32(sigma,i); + } + for (size_t i = 0; i < 8; i++) { + ctx->input[i + 4] = read32(key,i); + } + ctx->input[12] = 0; + ctx->input[13] = 0; + ctx->input[14] = (uint32_t)nonce; + ctx->input[15] = (uint32_t)(nonce >> 32); +} + +static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) { + memset(ctx_new, 0, sizeof(*ctx_new)); + _mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input)); + ctx_new->input[12] = 0; + ctx_new->input[13] = 0; + ctx_new->input[14] = (uint32_t)nonce; + ctx_new->input[15] = (uint32_t)(nonce >> 32); + mi_assert_internal(ctx->input[14] != ctx_new->input[14] || ctx->input[15] != ctx_new->input[15]); // do not reuse nonces! + chacha_block(ctx_new); +} + + +/* ---------------------------------------------------------------------------- +Random interface +-----------------------------------------------------------------------------*/ + +#if MI_DEBUG>1 +static bool mi_random_is_initialized(mi_random_ctx_t* ctx) { + return (ctx != NULL && ctx->input[0] != 0); +} +#endif + +void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* ctx_new) { + mi_assert_internal(mi_random_is_initialized(ctx)); + mi_assert_internal(ctx != ctx_new); + chacha_split(ctx, (uintptr_t)ctx_new /*nonce*/, ctx_new); +} + +uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { + mi_assert_internal(mi_random_is_initialized(ctx)); + #if MI_INTPTR_SIZE <= 4 + return chacha_next32(ctx); + #elif MI_INTPTR_SIZE == 8 + return (((uintptr_t)chacha_next32(ctx) << 32) | chacha_next32(ctx)); + #else + # error "define mi_random_next for this platform" + #endif +} + + +/* ---------------------------------------------------------------------------- +To initialize a fresh random context. +If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. +-----------------------------------------------------------------------------*/ + +uintptr_t _mi_os_random_weak(uintptr_t extra_seed) { + uintptr_t x = (uintptr_t)&_mi_os_random_weak ^ extra_seed; // ASLR makes the address random + x ^= _mi_prim_clock_now(); + // and do a few randomization steps + uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1; + for (uintptr_t i = 0; i < max; i++) { + x = _mi_random_shuffle(x); + } + mi_assert_internal(x != 0); + return x; +} + +static void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) { + uint8_t key[32]; + if (use_weak || !_mi_prim_random_buf(key, sizeof(key))) { + // if we fail to get random data from the OS, we fall back to a + // weak random source based on the current time + #if !defined(__wasi__) + if (!use_weak) { _mi_warning_message("unable to use secure randomness\n"); } + #endif + uintptr_t x = _mi_os_random_weak(0); + for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words. + x = _mi_random_shuffle(x); + ((uint32_t*)key)[i] = (uint32_t)x; + } + ctx->weak = true; + } + else { + ctx->weak = false; + } + chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ ); +} + +void _mi_random_init(mi_random_ctx_t* ctx) { + mi_random_init_ex(ctx, false); +} + +void _mi_random_init_weak(mi_random_ctx_t * ctx) { + mi_random_init_ex(ctx, true); +} + +void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx) { + if (ctx->weak) { + _mi_random_init(ctx); + } +} + +/* -------------------------------------------------------- +test vectors from <https://tools.ietf.org/html/rfc8439> +----------------------------------------------------------- */ +/* +static bool array_equals(uint32_t* x, uint32_t* y, size_t n) { + for (size_t i = 0; i < n; i++) { + if (x[i] != y[i]) return false; + } + return true; +} +static void chacha_test(void) +{ + uint32_t x[4] = { 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 }; + uint32_t x_out[4] = { 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb }; + qround(x, 0, 1, 2, 3); + mi_assert_internal(array_equals(x, x_out, 4)); + + uint32_t y[16] = { + 0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a, + 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0x2a5f714c, + 0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963, + 0x5c971061, 0x3d631689, 0x2098d9d6, 0x91dbd320 }; + uint32_t y_out[16] = { + 0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a, + 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0xcfacafd2, + 0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963, + 0x5c971061, 0xccc07c79, 0x2098d9d6, 0x91dbd320 }; + qround(y, 2, 7, 8, 13); + mi_assert_internal(array_equals(y, y_out, 16)); + + mi_random_ctx_t r = { + { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, + 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, + 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c, + 0x00000001, 0x09000000, 0x4a000000, 0x00000000 }, + {0}, + 0 + }; + uint32_t r_out[16] = { + 0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3, + 0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3, + 0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9, + 0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 }; + chacha_block(&r); + mi_assert_internal(array_equals(r.output, r_out, 16)); +} +*/ diff --git a/lib/Utils.Memory/mimalloc/src/segment-map.c b/lib/Utils.Memory/mimalloc/src/segment-map.c new file mode 100644 index 0000000..4c2104b --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/segment-map.c @@ -0,0 +1,153 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + The following functions are to reliably find the segment or + block that encompasses any pointer p (or NULL if it is not + in any of our segments). + We maintain a bitmap of all memory with 1 bit per MI_SEGMENT_SIZE (64MiB) + set to 1 if it contains the segment meta data. +----------------------------------------------------------- */ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +#if (MI_INTPTR_SIZE==8) +#define MI_MAX_ADDRESS ((size_t)40 << 40) // 40TB (to include huge page areas) +#else +#define MI_MAX_ADDRESS ((size_t)2 << 30) // 2Gb +#endif + +#define MI_SEGMENT_MAP_BITS (MI_MAX_ADDRESS / MI_SEGMENT_SIZE) +#define MI_SEGMENT_MAP_SIZE (MI_SEGMENT_MAP_BITS / 8) +#define MI_SEGMENT_MAP_WSIZE (MI_SEGMENT_MAP_SIZE / MI_INTPTR_SIZE) + +static _Atomic(uintptr_t) mi_segment_map[MI_SEGMENT_MAP_WSIZE + 1]; // 2KiB per TB with 64MiB segments + +static size_t mi_segment_map_index_of(const mi_segment_t* segment, size_t* bitidx) { + mi_assert_internal(_mi_ptr_segment(segment + 1) == segment); // is it aligned on MI_SEGMENT_SIZE? + if ((uintptr_t)segment >= MI_MAX_ADDRESS) { + *bitidx = 0; + return MI_SEGMENT_MAP_WSIZE; + } + else { + const uintptr_t segindex = ((uintptr_t)segment) / MI_SEGMENT_SIZE; + *bitidx = segindex % MI_INTPTR_BITS; + const size_t mapindex = segindex / MI_INTPTR_BITS; + mi_assert_internal(mapindex < MI_SEGMENT_MAP_WSIZE); + return mapindex; + } +} + +void _mi_segment_map_allocated_at(const mi_segment_t* segment) { + size_t bitidx; + size_t index = mi_segment_map_index_of(segment, &bitidx); + mi_assert_internal(index <= MI_SEGMENT_MAP_WSIZE); + if (index==MI_SEGMENT_MAP_WSIZE) return; + uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]); + uintptr_t newmask; + do { + newmask = (mask | ((uintptr_t)1 << bitidx)); + } while (!mi_atomic_cas_weak_release(&mi_segment_map[index], &mask, newmask)); +} + +void _mi_segment_map_freed_at(const mi_segment_t* segment) { + size_t bitidx; + size_t index = mi_segment_map_index_of(segment, &bitidx); + mi_assert_internal(index <= MI_SEGMENT_MAP_WSIZE); + if (index == MI_SEGMENT_MAP_WSIZE) return; + uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]); + uintptr_t newmask; + do { + newmask = (mask & ~((uintptr_t)1 << bitidx)); + } while (!mi_atomic_cas_weak_release(&mi_segment_map[index], &mask, newmask)); +} + +// Determine the segment belonging to a pointer or NULL if it is not in a valid segment. +static mi_segment_t* _mi_segment_of(const void* p) { + if (p == NULL) return NULL; + mi_segment_t* segment = _mi_ptr_segment(p); + mi_assert_internal(segment != NULL); + size_t bitidx; + size_t index = mi_segment_map_index_of(segment, &bitidx); + // fast path: for any pointer to valid small/medium/large object or first MI_SEGMENT_SIZE in huge + const uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]); + if mi_likely((mask & ((uintptr_t)1 << bitidx)) != 0) { + return segment; // yes, allocated by us + } + if (index==MI_SEGMENT_MAP_WSIZE) return NULL; + + // TODO: maintain max/min allocated range for efficiency for more efficient rejection of invalid pointers? + + // search downwards for the first segment in case it is an interior pointer + // could be slow but searches in MI_INTPTR_SIZE * MI_SEGMENT_SIZE (512MiB) steps trough + // valid huge objects + // note: we could maintain a lowest index to speed up the path for invalid pointers? + size_t lobitidx; + size_t loindex; + uintptr_t lobits = mask & (((uintptr_t)1 << bitidx) - 1); + if (lobits != 0) { + loindex = index; + lobitidx = mi_bsr(lobits); // lobits != 0 + } + else if (index == 0) { + return NULL; + } + else { + mi_assert_internal(index > 0); + uintptr_t lomask = mask; + loindex = index; + do { + loindex--; + lomask = mi_atomic_load_relaxed(&mi_segment_map[loindex]); + } while (lomask != 0 && loindex > 0); + if (lomask == 0) return NULL; + lobitidx = mi_bsr(lomask); // lomask != 0 + } + mi_assert_internal(loindex < MI_SEGMENT_MAP_WSIZE); + // take difference as the addresses could be larger than the MAX_ADDRESS space. + size_t diff = (((index - loindex) * (8*MI_INTPTR_SIZE)) + bitidx - lobitidx) * MI_SEGMENT_SIZE; + segment = (mi_segment_t*)((uint8_t*)segment - diff); + + if (segment == NULL) return NULL; + mi_assert_internal((void*)segment < p); + bool cookie_ok = (_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(cookie_ok); + if mi_unlikely(!cookie_ok) return NULL; + if (((uint8_t*)segment + mi_segment_size(segment)) <= (uint8_t*)p) return NULL; // outside the range + mi_assert_internal(p >= (void*)segment && (uint8_t*)p < (uint8_t*)segment + mi_segment_size(segment)); + return segment; +} + +// Is this a valid pointer in our heap? +static bool mi_is_valid_pointer(const void* p) { + return ((_mi_segment_of(p) != NULL) || (_mi_arena_contains(p))); +} + +mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept { + return mi_is_valid_pointer(p); +} + +/* +// Return the full segment range belonging to a pointer +static void* mi_segment_range_of(const void* p, size_t* size) { + mi_segment_t* segment = _mi_segment_of(p); + if (segment == NULL) { + if (size != NULL) *size = 0; + return NULL; + } + else { + if (size != NULL) *size = segment->segment_size; + return segment; + } + mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld)); + mi_assert_internal(page == NULL || (mi_segment_page_size(_mi_page_segment(page)) - (MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= block_size); + mi_reset_delayed(tld); + mi_assert_internal(page == NULL || mi_page_not_in_queue(page, tld)); + return page; +} +*/ diff --git a/lib/Utils.Memory/mimalloc/src/segment.c b/lib/Utils.Memory/mimalloc/src/segment.c new file mode 100644 index 0000000..28685f2 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/segment.c @@ -0,0 +1,1619 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +#include <string.h> // memset +#include <stdio.h> + +#define MI_PAGE_HUGE_ALIGN (256*1024) + +static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t* stats); + + +// ------------------------------------------------------------------- +// commit mask +// ------------------------------------------------------------------- + +static bool mi_commit_mask_all_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if ((commit->mask[i] & cm->mask[i]) != cm->mask[i]) return false; + } + return true; +} + +static bool mi_commit_mask_any_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if ((commit->mask[i] & cm->mask[i]) != 0) return true; + } + return false; +} + +static void mi_commit_mask_create_intersect(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm, mi_commit_mask_t* res) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + res->mask[i] = (commit->mask[i] & cm->mask[i]); + } +} + +static void mi_commit_mask_clear(mi_commit_mask_t* res, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + res->mask[i] &= ~(cm->mask[i]); + } +} + +static void mi_commit_mask_set(mi_commit_mask_t* res, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + res->mask[i] |= cm->mask[i]; + } +} + +static void mi_commit_mask_create(size_t bitidx, size_t bitcount, mi_commit_mask_t* cm) { + mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS); + mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS); + if (bitcount == MI_COMMIT_MASK_BITS) { + mi_assert_internal(bitidx==0); + mi_commit_mask_create_full(cm); + } + else if (bitcount == 0) { + mi_commit_mask_create_empty(cm); + } + else { + mi_commit_mask_create_empty(cm); + size_t i = bitidx / MI_COMMIT_MASK_FIELD_BITS; + size_t ofs = bitidx % MI_COMMIT_MASK_FIELD_BITS; + while (bitcount > 0) { + mi_assert_internal(i < MI_COMMIT_MASK_FIELD_COUNT); + size_t avail = MI_COMMIT_MASK_FIELD_BITS - ofs; + size_t count = (bitcount > avail ? avail : bitcount); + size_t mask = (count >= MI_COMMIT_MASK_FIELD_BITS ? ~((size_t)0) : (((size_t)1 << count) - 1) << ofs); + cm->mask[i] = mask; + bitcount -= count; + ofs = 0; + i++; + } + } +} + +size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total) { + mi_assert_internal((total%MI_COMMIT_MASK_BITS)==0); + size_t count = 0; + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + size_t mask = cm->mask[i]; + if (~mask == 0) { + count += MI_COMMIT_MASK_FIELD_BITS; + } + else { + for (; mask != 0; mask >>= 1) { // todo: use popcount + if ((mask&1)!=0) count++; + } + } + } + // we use total since for huge segments each commit bit may represent a larger size + return ((total / MI_COMMIT_MASK_BITS) * count); +} + + +size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx) { + size_t i = (*idx) / MI_COMMIT_MASK_FIELD_BITS; + size_t ofs = (*idx) % MI_COMMIT_MASK_FIELD_BITS; + size_t mask = 0; + // find first ones + while (i < MI_COMMIT_MASK_FIELD_COUNT) { + mask = cm->mask[i]; + mask >>= ofs; + if (mask != 0) { + while ((mask&1) == 0) { + mask >>= 1; + ofs++; + } + break; + } + i++; + ofs = 0; + } + if (i >= MI_COMMIT_MASK_FIELD_COUNT) { + // not found + *idx = MI_COMMIT_MASK_BITS; + return 0; + } + else { + // found, count ones + size_t count = 0; + *idx = (i*MI_COMMIT_MASK_FIELD_BITS) + ofs; + do { + mi_assert_internal(ofs < MI_COMMIT_MASK_FIELD_BITS && (mask&1) == 1); + do { + count++; + mask >>= 1; + } while ((mask&1) == 1); + if ((((*idx + count) % MI_COMMIT_MASK_FIELD_BITS) == 0)) { + i++; + if (i >= MI_COMMIT_MASK_FIELD_COUNT) break; + mask = cm->mask[i]; + ofs = 0; + } + } while ((mask&1) == 1); + mi_assert_internal(count > 0); + return count; + } +} + + +/* -------------------------------------------------------------------------------- + Segment allocation + + If a thread ends, it "abandons" pages with used blocks + and there is an abandoned segment list whose segments can + be reclaimed by still running threads, much like work-stealing. +-------------------------------------------------------------------------------- */ + + +/* ----------------------------------------------------------- + Slices +----------------------------------------------------------- */ + + +static const mi_slice_t* mi_segment_slices_end(const mi_segment_t* segment) { + return &segment->slices[segment->slice_entries]; +} + +static uint8_t* mi_slice_start(const mi_slice_t* slice) { + mi_segment_t* segment = _mi_ptr_segment(slice); + mi_assert_internal(slice >= segment->slices && slice < mi_segment_slices_end(segment)); + return ((uint8_t*)segment + ((slice - segment->slices)*MI_SEGMENT_SLICE_SIZE)); +} + + +/* ----------------------------------------------------------- + Bins +----------------------------------------------------------- */ +// Use bit scan forward to quickly find the first zero bit if it is available + +static inline size_t mi_slice_bin8(size_t slice_count) { + if (slice_count<=1) return slice_count; + mi_assert_internal(slice_count <= MI_SLICES_PER_SEGMENT); + slice_count--; + size_t s = mi_bsr(slice_count); // slice_count > 1 + if (s <= 2) return slice_count + 1; + size_t bin = ((s << 2) | ((slice_count >> (s - 2))&0x03)) - 4; + return bin; +} + +static inline size_t mi_slice_bin(size_t slice_count) { + mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_SEGMENT_SIZE); + mi_assert_internal(mi_slice_bin8(MI_SLICES_PER_SEGMENT) <= MI_SEGMENT_BIN_MAX); + size_t bin = mi_slice_bin8(slice_count); + mi_assert_internal(bin <= MI_SEGMENT_BIN_MAX); + return bin; +} + +static inline size_t mi_slice_index(const mi_slice_t* slice) { + mi_segment_t* segment = _mi_ptr_segment(slice); + ptrdiff_t index = slice - segment->slices; + mi_assert_internal(index >= 0 && index < (ptrdiff_t)segment->slice_entries); + return index; +} + + +/* ----------------------------------------------------------- + Slice span queues +----------------------------------------------------------- */ + +static void mi_span_queue_push(mi_span_queue_t* sq, mi_slice_t* slice) { + // todo: or push to the end? + mi_assert_internal(slice->prev == NULL && slice->next==NULL); + slice->prev = NULL; // paranoia + slice->next = sq->first; + sq->first = slice; + if (slice->next != NULL) slice->next->prev = slice; + else sq->last = slice; + slice->xblock_size = 0; // free +} + +static mi_span_queue_t* mi_span_queue_for(size_t slice_count, mi_segments_tld_t* tld) { + size_t bin = mi_slice_bin(slice_count); + mi_span_queue_t* sq = &tld->spans[bin]; + mi_assert_internal(sq->slice_count >= slice_count); + return sq; +} + +static void mi_span_queue_delete(mi_span_queue_t* sq, mi_slice_t* slice) { + mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0); + // should work too if the queue does not contain slice (which can happen during reclaim) + if (slice->prev != NULL) slice->prev->next = slice->next; + if (slice == sq->first) sq->first = slice->next; + if (slice->next != NULL) slice->next->prev = slice->prev; + if (slice == sq->last) sq->last = slice->prev; + slice->prev = NULL; + slice->next = NULL; + slice->xblock_size = 1; // no more free +} + + +/* ----------------------------------------------------------- + Invariant checking +----------------------------------------------------------- */ + +static bool mi_slice_is_used(const mi_slice_t* slice) { + return (slice->xblock_size > 0); +} + + +#if (MI_DEBUG>=3) +static bool mi_span_queue_contains(mi_span_queue_t* sq, mi_slice_t* slice) { + for (mi_slice_t* s = sq->first; s != NULL; s = s->next) { + if (s==slice) return true; + } + return false; +} + +static bool mi_segment_is_valid(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(segment != NULL); + mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(segment->abandoned <= segment->used); + mi_assert_internal(segment->thread_id == 0 || segment->thread_id == _mi_thread_id()); + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); // can only decommit committed blocks + //mi_assert_internal(segment->segment_info_size % MI_SEGMENT_SLICE_SIZE == 0); + mi_slice_t* slice = &segment->slices[0]; + const mi_slice_t* end = mi_segment_slices_end(segment); + size_t used_count = 0; + mi_span_queue_t* sq; + while(slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + size_t index = mi_slice_index(slice); + size_t maxindex = (index + slice->slice_count >= segment->slice_entries ? segment->slice_entries : index + slice->slice_count) - 1; + if (mi_slice_is_used(slice)) { // a page in use, we need at least MAX_SLICE_OFFSET valid back offsets + used_count++; + for (size_t i = 0; i <= MI_MAX_SLICE_OFFSET && index + i <= maxindex; i++) { + mi_assert_internal(segment->slices[index + i].slice_offset == i*sizeof(mi_slice_t)); + mi_assert_internal(i==0 || segment->slices[index + i].slice_count == 0); + mi_assert_internal(i==0 || segment->slices[index + i].xblock_size == 1); + } + // and the last entry as well (for coalescing) + const mi_slice_t* last = slice + slice->slice_count - 1; + if (last > slice && last < mi_segment_slices_end(segment)) { + mi_assert_internal(last->slice_offset == (slice->slice_count-1)*sizeof(mi_slice_t)); + mi_assert_internal(last->slice_count == 0); + mi_assert_internal(last->xblock_size == 1); + } + } + else { // free range of slices; only last slice needs a valid back offset + mi_slice_t* last = &segment->slices[maxindex]; + if (segment->kind != MI_SEGMENT_HUGE || slice->slice_count <= (segment->slice_entries - segment->segment_info_slices)) { + mi_assert_internal((uint8_t*)slice == (uint8_t*)last - last->slice_offset); + } + mi_assert_internal(slice == last || last->slice_count == 0 ); + mi_assert_internal(last->xblock_size == 0 || (segment->kind==MI_SEGMENT_HUGE && last->xblock_size==1)); + if (segment->kind != MI_SEGMENT_HUGE && segment->thread_id != 0) { // segment is not huge or abandoned + sq = mi_span_queue_for(slice->slice_count,tld); + mi_assert_internal(mi_span_queue_contains(sq,slice)); + } + } + slice = &segment->slices[maxindex+1]; + } + mi_assert_internal(slice == end); + mi_assert_internal(used_count == segment->used + 1); + return true; +} +#endif + +/* ----------------------------------------------------------- + Segment size calculations +----------------------------------------------------------- */ + +static size_t mi_segment_info_size(mi_segment_t* segment) { + return segment->segment_info_slices * MI_SEGMENT_SLICE_SIZE; +} + +static uint8_t* _mi_segment_page_start_from_slice(const mi_segment_t* segment, const mi_slice_t* slice, size_t xblock_size, size_t* page_size) +{ + ptrdiff_t idx = slice - segment->slices; + size_t psize = (size_t)slice->slice_count * MI_SEGMENT_SLICE_SIZE; + // make the start not OS page aligned for smaller blocks to avoid page/cache effects + // note: the offset must always be an xblock_size multiple since we assume small allocations + // are aligned (see `mi_heap_malloc_aligned`). + size_t start_offset = 0; + if (xblock_size >= MI_INTPTR_SIZE) { + if (xblock_size <= 64) { start_offset = 3*xblock_size; } + else if (xblock_size <= 512) { start_offset = xblock_size; } + } + if (page_size != NULL) { *page_size = psize - start_offset; } + return (uint8_t*)segment + ((idx*MI_SEGMENT_SLICE_SIZE) + start_offset); +} + +// Start of the page available memory; can be used on uninitialized pages +uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) +{ + const mi_slice_t* slice = mi_page_to_slice((mi_page_t*)page); + uint8_t* p = _mi_segment_page_start_from_slice(segment, slice, page->xblock_size, page_size); + mi_assert_internal(page->xblock_size > 0 || _mi_ptr_page(p) == page); + mi_assert_internal(_mi_ptr_segment(p) == segment); + return p; +} + + +static size_t mi_segment_calculate_slices(size_t required, size_t* pre_size, size_t* info_slices) { + size_t page_size = _mi_os_page_size(); + size_t isize = _mi_align_up(sizeof(mi_segment_t), page_size); + size_t guardsize = 0; + + if (MI_SECURE>0) { + // in secure mode, we set up a protected page in between the segment info + // and the page data (and one at the end of the segment) + guardsize = page_size; + if (required > 0) { + required = _mi_align_up(required, MI_SEGMENT_SLICE_SIZE) + page_size; + } + } + + if (pre_size != NULL) *pre_size = isize; + isize = _mi_align_up(isize + guardsize, MI_SEGMENT_SLICE_SIZE); + if (info_slices != NULL) *info_slices = isize / MI_SEGMENT_SLICE_SIZE; + size_t segment_size = (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + guardsize, MI_SEGMENT_SLICE_SIZE) ); + mi_assert_internal(segment_size % MI_SEGMENT_SLICE_SIZE == 0); + return (segment_size / MI_SEGMENT_SLICE_SIZE); +} + + +/* ---------------------------------------------------------------------------- +Segment caches +We keep a small segment cache per thread to increase local +reuse and avoid setting/clearing guard pages in secure mode. +------------------------------------------------------------------------------- */ + +static void mi_segments_track_size(long segment_size, mi_segments_tld_t* tld) { + if (segment_size>=0) _mi_stat_increase(&tld->stats->segments,1); + else _mi_stat_decrease(&tld->stats->segments,1); + tld->count += (segment_size >= 0 ? 1 : -1); + if (tld->count > tld->peak_count) tld->peak_count = tld->count; + tld->current_size += segment_size; + if (tld->current_size > tld->peak_size) tld->peak_size = tld->current_size; +} + +static void mi_segment_os_free(mi_segment_t* segment, mi_segments_tld_t* tld) { + segment->thread_id = 0; + _mi_segment_map_freed_at(segment); + mi_segments_track_size(-((long)mi_segment_size(segment)),tld); + if (MI_SECURE>0) { + // _mi_os_unprotect(segment, mi_segment_size(segment)); // ensure no more guard pages are set + // unprotect the guard pages; we cannot just unprotect the whole segment size as part may be decommitted + size_t os_pagesize = _mi_os_page_size(); + _mi_os_unprotect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize); + uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize; + _mi_os_unprotect(end, os_pagesize); + } + + // purge delayed decommits now? (no, leave it to the arena) + // mi_segment_try_purge(segment,true,tld->stats); + + const size_t size = mi_segment_size(segment); + const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size); + + _mi_abandoned_await_readers(); // wait until safe to free + _mi_arena_free(segment, mi_segment_size(segment), csize, segment->memid, tld->stats); +} + +// called by threads that are terminating +void _mi_segment_thread_collect(mi_segments_tld_t* tld) { + MI_UNUSED(tld); + // nothing to do +} + + +/* ----------------------------------------------------------- + Commit/Decommit ranges +----------------------------------------------------------- */ + +static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uint8_t* p, size_t size, uint8_t** start_p, size_t* full_size, mi_commit_mask_t* cm) { + mi_assert_internal(_mi_ptr_segment(p + 1) == segment); + mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); + mi_commit_mask_create_empty(cm); + if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return; + const size_t segstart = mi_segment_info_size(segment); + const size_t segsize = mi_segment_size(segment); + if (p >= (uint8_t*)segment + segsize) return; + + size_t pstart = (p - (uint8_t*)segment); + mi_assert_internal(pstart + size <= segsize); + + size_t start; + size_t end; + if (conservative) { + // decommit conservative + start = _mi_align_up(pstart, MI_COMMIT_SIZE); + end = _mi_align_down(pstart + size, MI_COMMIT_SIZE); + mi_assert_internal(start >= segstart); + mi_assert_internal(end <= segsize); + } + else { + // commit liberal + start = _mi_align_down(pstart, MI_MINIMAL_COMMIT_SIZE); + end = _mi_align_up(pstart + size, MI_MINIMAL_COMMIT_SIZE); + } + if (pstart >= segstart && start < segstart) { // note: the mask is also calculated for an initial commit of the info area + start = segstart; + } + if (end > segsize) { + end = segsize; + } + + mi_assert_internal(start <= pstart && (pstart + size) <= end); + mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0); + *start_p = (uint8_t*)segment + start; + *full_size = (end > start ? end - start : 0); + if (*full_size == 0) return; + + size_t bitidx = start / MI_COMMIT_SIZE; + mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS); + + size_t bitcount = *full_size / MI_COMMIT_SIZE; // can be 0 + if (bitidx + bitcount > MI_COMMIT_MASK_BITS) { + _mi_warning_message("commit mask overflow: idx=%zu count=%zu start=%zx end=%zx p=0x%p size=%zu fullsize=%zu\n", bitidx, bitcount, start, end, p, size, *full_size); + } + mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS); + mi_commit_mask_create(bitidx, bitcount, cm); +} + +static bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); + + // commit liberal + uint8_t* start = NULL; + size_t full_size = 0; + mi_commit_mask_t mask; + mi_segment_commit_mask(segment, false /* conservative? */, p, size, &start, &full_size, &mask); + if (mi_commit_mask_is_empty(&mask) || full_size == 0) return true; + + if (!mi_commit_mask_all_set(&segment->commit_mask, &mask)) { + // committing + bool is_zero = false; + mi_commit_mask_t cmask; + mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); + _mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap + if (!_mi_os_commit(start, full_size, &is_zero, stats)) return false; + mi_commit_mask_set(&segment->commit_mask, &mask); + } + + // increase purge expiration when using part of delayed purges -- we assume more allocations are coming soon. + if (mi_commit_mask_any_set(&segment->purge_mask, &mask)) { + segment->purge_expire = _mi_clock_now() + mi_option_get(mi_option_purge_delay); + } + + // always clear any delayed purges in our range (as they are either committed now) + mi_commit_mask_clear(&segment->purge_mask, &mask); + return true; +} + +static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); + // note: assumes commit_mask is always full for huge segments as otherwise the commit mask bits can overflow + if (mi_commit_mask_is_full(&segment->commit_mask) && mi_commit_mask_is_empty(&segment->purge_mask)) return true; // fully committed + mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); + return mi_segment_commit(segment, p, size, stats); +} + +static bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); + if (!segment->allow_purge) return true; + + // purge conservative + uint8_t* start = NULL; + size_t full_size = 0; + mi_commit_mask_t mask; + mi_segment_commit_mask(segment, true /* conservative? */, p, size, &start, &full_size, &mask); + if (mi_commit_mask_is_empty(&mask) || full_size==0) return true; + + if (mi_commit_mask_any_set(&segment->commit_mask, &mask)) { + // purging + mi_assert_internal((void*)start != (void*)segment); + mi_assert_internal(segment->allow_decommit); + const bool decommitted = _mi_os_purge(start, full_size, stats); // reset or decommit + if (decommitted) { + mi_commit_mask_t cmask; + mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); + _mi_stat_increase(&_mi_stats_main.committed, full_size - _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for double counting + mi_commit_mask_clear(&segment->commit_mask, &mask); + } + } + + // always clear any scheduled purges in our range + mi_commit_mask_clear(&segment->purge_mask, &mask); + return true; +} + +static void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + if (!segment->allow_purge) return; + + if (mi_option_get(mi_option_purge_delay) == 0) { + mi_segment_purge(segment, p, size, stats); + } + else { + // register for future purge in the purge mask + uint8_t* start = NULL; + size_t full_size = 0; + mi_commit_mask_t mask; + mi_segment_commit_mask(segment, true /*conservative*/, p, size, &start, &full_size, &mask); + if (mi_commit_mask_is_empty(&mask) || full_size==0) return; + + // update delayed commit + mi_assert_internal(segment->purge_expire > 0 || mi_commit_mask_is_empty(&segment->purge_mask)); + mi_commit_mask_t cmask; + mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); // only purge what is committed; span_free may try to decommit more + mi_commit_mask_set(&segment->purge_mask, &cmask); + mi_msecs_t now = _mi_clock_now(); + if (segment->purge_expire == 0) { + // no previous purgess, initialize now + segment->purge_expire = now + mi_option_get(mi_option_purge_delay); + } + else if (segment->purge_expire <= now) { + // previous purge mask already expired + if (segment->purge_expire + mi_option_get(mi_option_purge_extend_delay) <= now) { + mi_segment_try_purge(segment, true, stats); + } + else { + segment->purge_expire = now + mi_option_get(mi_option_purge_extend_delay); // (mi_option_get(mi_option_purge_delay) / 8); // wait a tiny bit longer in case there is a series of free's + } + } + else { + // previous purge mask is not yet expired, increase the expiration by a bit. + segment->purge_expire += mi_option_get(mi_option_purge_extend_delay); + } + } +} + +static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t* stats) { + if (!segment->allow_purge || mi_commit_mask_is_empty(&segment->purge_mask)) return; + mi_msecs_t now = _mi_clock_now(); + if (!force && now < segment->purge_expire) return; + + mi_commit_mask_t mask = segment->purge_mask; + segment->purge_expire = 0; + mi_commit_mask_create_empty(&segment->purge_mask); + + size_t idx; + size_t count; + mi_commit_mask_foreach(&mask, idx, count) { + // if found, decommit that sequence + if (count > 0) { + uint8_t* p = (uint8_t*)segment + (idx*MI_COMMIT_SIZE); + size_t size = count * MI_COMMIT_SIZE; + mi_segment_purge(segment, p, size, stats); + } + } + mi_commit_mask_foreach_end() + mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask)); +} + + +/* ----------------------------------------------------------- + Span free +----------------------------------------------------------- */ + +static bool mi_segment_is_abandoned(mi_segment_t* segment) { + return (segment->thread_id == 0); +} + +// note: can be called on abandoned segments +static void mi_segment_span_free(mi_segment_t* segment, size_t slice_index, size_t slice_count, bool allow_purge, mi_segments_tld_t* tld) { + mi_assert_internal(slice_index < segment->slice_entries); + mi_span_queue_t* sq = (segment->kind == MI_SEGMENT_HUGE || mi_segment_is_abandoned(segment) + ? NULL : mi_span_queue_for(slice_count,tld)); + if (slice_count==0) slice_count = 1; + mi_assert_internal(slice_index + slice_count - 1 < segment->slice_entries); + + // set first and last slice (the intermediates can be undetermined) + mi_slice_t* slice = &segment->slices[slice_index]; + slice->slice_count = (uint32_t)slice_count; + mi_assert_internal(slice->slice_count == slice_count); // no overflow? + slice->slice_offset = 0; + if (slice_count > 1) { + mi_slice_t* last = &segment->slices[slice_index + slice_count - 1]; + last->slice_count = 0; + last->slice_offset = (uint32_t)(sizeof(mi_page_t)*(slice_count - 1)); + last->xblock_size = 0; + } + + // perhaps decommit + if (allow_purge) { + mi_segment_schedule_purge(segment, mi_slice_start(slice), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats); + } + + // and push it on the free page queue (if it was not a huge page) + if (sq != NULL) mi_span_queue_push( sq, slice ); + else slice->xblock_size = 0; // mark huge page as free anyways +} + +/* +// called from reclaim to add existing free spans +static void mi_segment_span_add_free(mi_slice_t* slice, mi_segments_tld_t* tld) { + mi_segment_t* segment = _mi_ptr_segment(slice); + mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0); + size_t slice_index = mi_slice_index(slice); + mi_segment_span_free(segment,slice_index,slice->slice_count,tld); +} +*/ + +static void mi_segment_span_remove_from_queue(mi_slice_t* slice, mi_segments_tld_t* tld) { + mi_assert_internal(slice->slice_count > 0 && slice->slice_offset==0 && slice->xblock_size==0); + mi_assert_internal(_mi_ptr_segment(slice)->kind != MI_SEGMENT_HUGE); + mi_span_queue_t* sq = mi_span_queue_for(slice->slice_count, tld); + mi_span_queue_delete(sq, slice); +} + +// note: can be called on abandoned segments +static mi_slice_t* mi_segment_span_free_coalesce(mi_slice_t* slice, mi_segments_tld_t* tld) { + mi_assert_internal(slice != NULL && slice->slice_count > 0 && slice->slice_offset == 0); + mi_segment_t* segment = _mi_ptr_segment(slice); + bool is_abandoned = mi_segment_is_abandoned(segment); + + // for huge pages, just mark as free but don't add to the queues + if (segment->kind == MI_SEGMENT_HUGE) { + // issue #691: segment->used can be 0 if the huge page block was freed while abandoned (reclaim will get here in that case) + mi_assert_internal((segment->used==0 && slice->xblock_size==0) || segment->used == 1); // decreased right after this call in `mi_segment_page_clear` + slice->xblock_size = 0; // mark as free anyways + // we should mark the last slice `xblock_size=0` now to maintain invariants but we skip it to + // avoid a possible cache miss (and the segment is about to be freed) + return slice; + } + + // otherwise coalesce the span and add to the free span queues + size_t slice_count = slice->slice_count; + mi_slice_t* next = slice + slice->slice_count; + mi_assert_internal(next <= mi_segment_slices_end(segment)); + if (next < mi_segment_slices_end(segment) && next->xblock_size==0) { + // free next block -- remove it from free and merge + mi_assert_internal(next->slice_count > 0 && next->slice_offset==0); + slice_count += next->slice_count; // extend + if (!is_abandoned) { mi_segment_span_remove_from_queue(next, tld); } + } + if (slice > segment->slices) { + mi_slice_t* prev = mi_slice_first(slice - 1); + mi_assert_internal(prev >= segment->slices); + if (prev->xblock_size==0) { + // free previous slice -- remove it from free and merge + mi_assert_internal(prev->slice_count > 0 && prev->slice_offset==0); + slice_count += prev->slice_count; + if (!is_abandoned) { mi_segment_span_remove_from_queue(prev, tld); } + slice = prev; + } + } + + // and add the new free page + mi_segment_span_free(segment, mi_slice_index(slice), slice_count, true, tld); + return slice; +} + + + +/* ----------------------------------------------------------- + Page allocation +----------------------------------------------------------- */ + +// Note: may still return NULL if committing the memory failed +static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) { + mi_assert_internal(slice_index < segment->slice_entries); + mi_slice_t* const slice = &segment->slices[slice_index]; + mi_assert_internal(slice->xblock_size==0 || slice->xblock_size==1); + + // commit before changing the slice data + if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats)) { + return NULL; // commit failed! + } + + // convert the slices to a page + slice->slice_offset = 0; + slice->slice_count = (uint32_t)slice_count; + mi_assert_internal(slice->slice_count == slice_count); + const size_t bsize = slice_count * MI_SEGMENT_SLICE_SIZE; + slice->xblock_size = (uint32_t)(bsize >= MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : bsize); + mi_page_t* page = mi_slice_to_page(slice); + mi_assert_internal(mi_page_block_size(page) == bsize); + + // set slice back pointers for the first MI_MAX_SLICE_OFFSET entries + size_t extra = slice_count-1; + if (extra > MI_MAX_SLICE_OFFSET) extra = MI_MAX_SLICE_OFFSET; + if (slice_index + extra >= segment->slice_entries) extra = segment->slice_entries - slice_index - 1; // huge objects may have more slices than avaiable entries in the segment->slices + + mi_slice_t* slice_next = slice + 1; + for (size_t i = 1; i <= extra; i++, slice_next++) { + slice_next->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i); + slice_next->slice_count = 0; + slice_next->xblock_size = 1; + } + + // and also for the last one (if not set already) (the last one is needed for coalescing and for large alignments) + // note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543) + mi_slice_t* last = slice + slice_count - 1; + mi_slice_t* end = (mi_slice_t*)mi_segment_slices_end(segment); + if (last > end) last = end; + if (last > slice) { + last->slice_offset = (uint32_t)(sizeof(mi_slice_t) * (last - slice)); + last->slice_count = 0; + last->xblock_size = 1; + } + + // and initialize the page + page->is_committed = true; + segment->used++; + return page; +} + +static void mi_segment_slice_split(mi_segment_t* segment, mi_slice_t* slice, size_t slice_count, mi_segments_tld_t* tld) { + mi_assert_internal(_mi_ptr_segment(slice) == segment); + mi_assert_internal(slice->slice_count >= slice_count); + mi_assert_internal(slice->xblock_size > 0); // no more in free queue + if (slice->slice_count <= slice_count) return; + mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); + size_t next_index = mi_slice_index(slice) + slice_count; + size_t next_count = slice->slice_count - slice_count; + mi_segment_span_free(segment, next_index, next_count, false /* don't purge left-over part */, tld); + slice->slice_count = (uint32_t)slice_count; +} + +static mi_page_t* mi_segments_page_find_and_allocate(size_t slice_count, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld) { + mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_LARGE_OBJ_SIZE_MAX); + // search from best fit up + mi_span_queue_t* sq = mi_span_queue_for(slice_count, tld); + if (slice_count == 0) slice_count = 1; + while (sq <= &tld->spans[MI_SEGMENT_BIN_MAX]) { + for (mi_slice_t* slice = sq->first; slice != NULL; slice = slice->next) { + if (slice->slice_count >= slice_count) { + // found one + mi_segment_t* segment = _mi_ptr_segment(slice); + if (_mi_arena_memid_is_suitable(segment->memid, req_arena_id)) { + // found a suitable page span + mi_span_queue_delete(sq, slice); + + if (slice->slice_count > slice_count) { + mi_segment_slice_split(segment, slice, slice_count, tld); + } + mi_assert_internal(slice != NULL && slice->slice_count == slice_count && slice->xblock_size > 0); + mi_page_t* page = mi_segment_span_allocate(segment, mi_slice_index(slice), slice->slice_count, tld); + if (page == NULL) { + // commit failed; return NULL but first restore the slice + mi_segment_span_free_coalesce(slice, tld); + return NULL; + } + return page; + } + } + } + sq++; + } + // could not find a page.. + return NULL; +} + + +/* ----------------------------------------------------------- + Segment allocation +----------------------------------------------------------- */ + +static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment, bool eager_delayed, mi_arena_id_t req_arena_id, + size_t* psegment_slices, size_t* ppre_size, size_t* pinfo_slices, + bool commit, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) + +{ + mi_memid_t memid; + bool allow_large = (!eager_delayed && (MI_SECURE == 0)); // only allow large OS pages once we are no longer lazy + size_t align_offset = 0; + size_t alignment = MI_SEGMENT_ALIGN; + + if (page_alignment > 0) { + // mi_assert_internal(huge_page != NULL); + mi_assert_internal(page_alignment >= MI_SEGMENT_ALIGN); + alignment = page_alignment; + const size_t info_size = (*pinfo_slices) * MI_SEGMENT_SLICE_SIZE; + align_offset = _mi_align_up( info_size, MI_SEGMENT_ALIGN ); + const size_t extra = align_offset - info_size; + // recalculate due to potential guard pages + *psegment_slices = mi_segment_calculate_slices(required + extra, ppre_size, pinfo_slices); + } + + const size_t segment_size = (*psegment_slices) * MI_SEGMENT_SLICE_SIZE; + mi_segment_t* segment = (mi_segment_t*)_mi_arena_alloc_aligned(segment_size, alignment, align_offset, commit, allow_large, req_arena_id, &memid, os_tld); + if (segment == NULL) { + return NULL; // failed to allocate + } + + // ensure metadata part of the segment is committed + mi_commit_mask_t commit_mask; + if (memid.initially_committed) { + mi_commit_mask_create_full(&commit_mask); + } + else { + // at least commit the info slices + const size_t commit_needed = _mi_divide_up((*pinfo_slices)*MI_SEGMENT_SLICE_SIZE, MI_COMMIT_SIZE); + mi_assert_internal(commit_needed>0); + mi_commit_mask_create(0, commit_needed, &commit_mask); + mi_assert_internal(commit_needed*MI_COMMIT_SIZE >= (*pinfo_slices)*MI_SEGMENT_SLICE_SIZE); + if (!_mi_os_commit(segment, commit_needed*MI_COMMIT_SIZE, NULL, tld->stats)) { + _mi_arena_free(segment,segment_size,0,memid,tld->stats); + return NULL; + } + } + mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0); + + segment->memid = memid; + segment->allow_decommit = !memid.is_pinned; + segment->allow_purge = segment->allow_decommit && (mi_option_get(mi_option_purge_delay) >= 0); + segment->segment_size = segment_size; + segment->commit_mask = commit_mask; + segment->purge_expire = 0; + mi_commit_mask_create_empty(&segment->purge_mask); + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); // tsan + + mi_segments_track_size((long)(segment_size), tld); + _mi_segment_map_allocated_at(segment); + return segment; +} + + +// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` . +static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld, mi_page_t** huge_page) +{ + mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL)); + + // calculate needed sizes first + size_t info_slices; + size_t pre_size; + size_t segment_slices = mi_segment_calculate_slices(required, &pre_size, &info_slices); + + // Commit eagerly only if not the first N lazy segments (to reduce impact of many threads that allocate just a little) + const bool eager_delay = (// !_mi_os_has_overcommit() && // never delay on overcommit systems + _mi_current_thread_count() > 1 && // do not delay for the first N threads + tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay)); + const bool eager = !eager_delay && mi_option_is_enabled(mi_option_eager_commit); + bool commit = eager || (required > 0); + + // Allocate the segment from the OS + mi_segment_t* segment = mi_segment_os_alloc(required, page_alignment, eager_delay, req_arena_id, + &segment_slices, &pre_size, &info_slices, commit, tld, os_tld); + if (segment == NULL) return NULL; + + // zero the segment info? -- not always needed as it may be zero initialized from the OS + if (!segment->memid.initially_zero) { + ptrdiff_t ofs = offsetof(mi_segment_t, next); + size_t prefix = offsetof(mi_segment_t, slices) - ofs; + size_t zsize = prefix + (sizeof(mi_slice_t) * (segment_slices + 1)); // one more + _mi_memzero((uint8_t*)segment + ofs, zsize); + } + + // initialize the rest of the segment info + const size_t slice_entries = (segment_slices > MI_SLICES_PER_SEGMENT ? MI_SLICES_PER_SEGMENT : segment_slices); + segment->segment_slices = segment_slices; + segment->segment_info_slices = info_slices; + segment->thread_id = _mi_thread_id(); + segment->cookie = _mi_ptr_cookie(segment); + segment->slice_entries = slice_entries; + segment->kind = (required == 0 ? MI_SEGMENT_NORMAL : MI_SEGMENT_HUGE); + + // _mi_memzero(segment->slices, sizeof(mi_slice_t)*(info_slices+1)); + _mi_stat_increase(&tld->stats->page_committed, mi_segment_info_size(segment)); + + // set up guard pages + size_t guard_slices = 0; + if (MI_SECURE>0) { + // in secure mode, we set up a protected page in between the segment info + // and the page data, and at the end of the segment. + size_t os_pagesize = _mi_os_page_size(); + mi_assert_internal(mi_segment_info_size(segment) - os_pagesize >= pre_size); + _mi_os_protect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize); + uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize; + mi_segment_ensure_committed(segment, end, os_pagesize, tld->stats); + _mi_os_protect(end, os_pagesize); + if (slice_entries == segment_slices) segment->slice_entries--; // don't use the last slice :-( + guard_slices = 1; + } + + // reserve first slices for segment info + mi_page_t* page0 = mi_segment_span_allocate(segment, 0, info_slices, tld); + mi_assert_internal(page0!=NULL); if (page0==NULL) return NULL; // cannot fail as we always commit in advance + mi_assert_internal(segment->used == 1); + segment->used = 0; // don't count our internal slices towards usage + + // initialize initial free pages + if (segment->kind == MI_SEGMENT_NORMAL) { // not a huge page + mi_assert_internal(huge_page==NULL); + mi_segment_span_free(segment, info_slices, segment->slice_entries - info_slices, false /* don't purge */, tld); + } + else { + mi_assert_internal(huge_page!=NULL); + mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask)); + mi_assert_internal(mi_commit_mask_is_full(&segment->commit_mask)); + *huge_page = mi_segment_span_allocate(segment, info_slices, segment_slices - info_slices - guard_slices, tld); + mi_assert_internal(*huge_page != NULL); // cannot fail as we commit in advance + } + + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + return segment; +} + + +static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) { + MI_UNUSED(force); + mi_assert_internal(segment != NULL); + mi_assert_internal(segment->next == NULL); + mi_assert_internal(segment->used == 0); + + // Remove the free pages + mi_slice_t* slice = &segment->slices[0]; + const mi_slice_t* end = mi_segment_slices_end(segment); + #if MI_DEBUG>1 + size_t page_count = 0; + #endif + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + mi_assert_internal(mi_slice_index(slice)==0 || slice->xblock_size == 0); // no more used pages .. + if (slice->xblock_size == 0 && segment->kind != MI_SEGMENT_HUGE) { + mi_segment_span_remove_from_queue(slice, tld); + } + #if MI_DEBUG>1 + page_count++; + #endif + slice = slice + slice->slice_count; + } + mi_assert_internal(page_count == 2); // first page is allocated by the segment itself + + // stats + _mi_stat_decrease(&tld->stats->page_committed, mi_segment_info_size(segment)); + + // return it to the OS + mi_segment_os_free(segment, tld); +} + + +/* ----------------------------------------------------------- + Page Free +----------------------------------------------------------- */ + +static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld); + +// note: can be called on abandoned pages +static mi_slice_t* mi_segment_page_clear(mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert_internal(page->xblock_size > 0); + mi_assert_internal(mi_page_all_free(page)); + mi_segment_t* segment = _mi_ptr_segment(page); + mi_assert_internal(segment->used > 0); + + size_t inuse = page->capacity * mi_page_block_size(page); + _mi_stat_decrease(&tld->stats->page_committed, inuse); + _mi_stat_decrease(&tld->stats->pages, 1); + + // reset the page memory to reduce memory pressure? + if (segment->allow_decommit && mi_option_is_enabled(mi_option_deprecated_page_reset)) { + size_t psize; + uint8_t* start = _mi_page_start(segment, page, &psize); + _mi_os_reset(start, psize, tld->stats); + } + + // zero the page data, but not the segment fields + page->is_zero_init = false; + ptrdiff_t ofs = offsetof(mi_page_t, capacity); + _mi_memzero((uint8_t*)page + ofs, sizeof(*page) - ofs); + page->xblock_size = 1; + + // and free it + mi_slice_t* slice = mi_segment_span_free_coalesce(mi_page_to_slice(page), tld); + segment->used--; + // cannot assert segment valid as it is called during reclaim + // mi_assert_expensive(mi_segment_is_valid(segment, tld)); + return slice; +} + +void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld) +{ + mi_assert(page != NULL); + + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + + // mark it as free now + mi_segment_page_clear(page, tld); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + + if (segment->used == 0) { + // no more used pages; remove from the free list and free the segment + mi_segment_free(segment, force, tld); + } + else if (segment->used == segment->abandoned) { + // only abandoned pages; remove from free list and abandon + mi_segment_abandon(segment,tld); + } +} + + +/* ----------------------------------------------------------- +Abandonment + +When threads terminate, they can leave segments with +live blocks (reachable through other threads). Such segments +are "abandoned" and will be reclaimed by other threads to +reuse their pages and/or free them eventually + +We maintain a global list of abandoned segments that are +reclaimed on demand. Since this is shared among threads +the implementation needs to avoid the A-B-A problem on +popping abandoned segments: <https://en.wikipedia.org/wiki/ABA_problem> +We use tagged pointers to avoid accidentally identifying +reused segments, much like stamped references in Java. +Secondly, we maintain a reader counter to avoid resetting +or decommitting segments that have a pending read operation. + +Note: the current implementation is one possible design; +another way might be to keep track of abandoned segments +in the arenas/segment_cache's. This would have the advantage of keeping +all concurrent code in one place and not needing to deal +with ABA issues. The drawback is that it is unclear how to +scan abandoned segments efficiently in that case as they +would be spread among all other segments in the arenas. +----------------------------------------------------------- */ + +// Use the bottom 20-bits (on 64-bit) of the aligned segment pointers +// to put in a tag that increments on update to avoid the A-B-A problem. +#define MI_TAGGED_MASK MI_SEGMENT_MASK +typedef uintptr_t mi_tagged_segment_t; + +static mi_segment_t* mi_tagged_segment_ptr(mi_tagged_segment_t ts) { + return (mi_segment_t*)(ts & ~MI_TAGGED_MASK); +} + +static mi_tagged_segment_t mi_tagged_segment(mi_segment_t* segment, mi_tagged_segment_t ts) { + mi_assert_internal(((uintptr_t)segment & MI_TAGGED_MASK) == 0); + uintptr_t tag = ((ts & MI_TAGGED_MASK) + 1) & MI_TAGGED_MASK; + return ((uintptr_t)segment | tag); +} + +// This is a list of visited abandoned pages that were full at the time. +// this list migrates to `abandoned` when that becomes NULL. The use of +// this list reduces contention and the rate at which segments are visited. +static mi_decl_cache_align _Atomic(mi_segment_t*) abandoned_visited; // = NULL + +// The abandoned page list (tagged as it supports pop) +static mi_decl_cache_align _Atomic(mi_tagged_segment_t) abandoned; // = NULL + +// Maintain these for debug purposes (these counts may be a bit off) +static mi_decl_cache_align _Atomic(size_t) abandoned_count; +static mi_decl_cache_align _Atomic(size_t) abandoned_visited_count; + +// We also maintain a count of current readers of the abandoned list +// in order to prevent resetting/decommitting segment memory if it might +// still be read. +static mi_decl_cache_align _Atomic(size_t) abandoned_readers; // = 0 + +// Push on the visited list +static void mi_abandoned_visited_push(mi_segment_t* segment) { + mi_assert_internal(segment->thread_id == 0); + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t,&segment->abandoned_next) == NULL); + mi_assert_internal(segment->next == NULL); + mi_assert_internal(segment->used > 0); + mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited); + do { + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, anext); + } while (!mi_atomic_cas_ptr_weak_release(mi_segment_t, &abandoned_visited, &anext, segment)); + mi_atomic_increment_relaxed(&abandoned_visited_count); +} + +// Move the visited list to the abandoned list. +static bool mi_abandoned_visited_revisit(void) +{ + // quick check if the visited list is empty + if (mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited) == NULL) return false; + + // grab the whole visited list + mi_segment_t* first = mi_atomic_exchange_ptr_acq_rel(mi_segment_t, &abandoned_visited, NULL); + if (first == NULL) return false; + + // first try to swap directly if the abandoned list happens to be NULL + mi_tagged_segment_t afirst; + mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); + if (mi_tagged_segment_ptr(ts)==NULL) { + size_t count = mi_atomic_load_relaxed(&abandoned_visited_count); + afirst = mi_tagged_segment(first, ts); + if (mi_atomic_cas_strong_acq_rel(&abandoned, &ts, afirst)) { + mi_atomic_add_relaxed(&abandoned_count, count); + mi_atomic_sub_relaxed(&abandoned_visited_count, count); + return true; + } + } + + // find the last element of the visited list: O(n) + mi_segment_t* last = first; + mi_segment_t* next; + while ((next = mi_atomic_load_ptr_relaxed(mi_segment_t, &last->abandoned_next)) != NULL) { + last = next; + } + + // and atomically prepend to the abandoned list + // (no need to increase the readers as we don't access the abandoned segments) + mi_tagged_segment_t anext = mi_atomic_load_relaxed(&abandoned); + size_t count; + do { + count = mi_atomic_load_relaxed(&abandoned_visited_count); + mi_atomic_store_ptr_release(mi_segment_t, &last->abandoned_next, mi_tagged_segment_ptr(anext)); + afirst = mi_tagged_segment(first, anext); + } while (!mi_atomic_cas_weak_release(&abandoned, &anext, afirst)); + mi_atomic_add_relaxed(&abandoned_count, count); + mi_atomic_sub_relaxed(&abandoned_visited_count, count); + return true; +} + +// Push on the abandoned list. +static void mi_abandoned_push(mi_segment_t* segment) { + mi_assert_internal(segment->thread_id == 0); + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); + mi_assert_internal(segment->next == NULL); + mi_assert_internal(segment->used > 0); + mi_tagged_segment_t next; + mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); + do { + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, mi_tagged_segment_ptr(ts)); + next = mi_tagged_segment(segment, ts); + } while (!mi_atomic_cas_weak_release(&abandoned, &ts, next)); + mi_atomic_increment_relaxed(&abandoned_count); +} + +// Wait until there are no more pending reads on segments that used to be in the abandoned list +// called for example from `arena.c` before decommitting +void _mi_abandoned_await_readers(void) { + size_t n; + do { + n = mi_atomic_load_acquire(&abandoned_readers); + if (n != 0) mi_atomic_yield(); + } while (n != 0); +} + +// Pop from the abandoned list +static mi_segment_t* mi_abandoned_pop(void) { + mi_segment_t* segment; + // Check efficiently if it is empty (or if the visited list needs to be moved) + mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); + segment = mi_tagged_segment_ptr(ts); + if mi_likely(segment == NULL) { + if mi_likely(!mi_abandoned_visited_revisit()) { // try to swap in the visited list on NULL + return NULL; + } + } + + // Do a pop. We use a reader count to prevent + // a segment to be decommitted while a read is still pending, + // and a tagged pointer to prevent A-B-A link corruption. + // (this is called from `region.c:_mi_mem_free` for example) + mi_atomic_increment_relaxed(&abandoned_readers); // ensure no segment gets decommitted + mi_tagged_segment_t next = 0; + ts = mi_atomic_load_acquire(&abandoned); + do { + segment = mi_tagged_segment_ptr(ts); + if (segment != NULL) { + mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next); + next = mi_tagged_segment(anext, ts); // note: reads the segment's `abandoned_next` field so should not be decommitted + } + } while (segment != NULL && !mi_atomic_cas_weak_acq_rel(&abandoned, &ts, next)); + mi_atomic_decrement_relaxed(&abandoned_readers); // release reader lock + if (segment != NULL) { + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); + mi_atomic_decrement_relaxed(&abandoned_count); + } + return segment; +} + +/* ----------------------------------------------------------- + Abandon segment/page +----------------------------------------------------------- */ + +static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(segment->used == segment->abandoned); + mi_assert_internal(segment->used > 0); + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); + mi_assert_internal(segment->abandoned_visits == 0); + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + + // remove the free pages from the free page queues + mi_slice_t* slice = &segment->slices[0]; + const mi_slice_t* end = mi_segment_slices_end(segment); + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + if (slice->xblock_size == 0) { // a free page + mi_segment_span_remove_from_queue(slice,tld); + slice->xblock_size = 0; // but keep it free + } + slice = slice + slice->slice_count; + } + + // perform delayed decommits (forcing is much slower on mstress) + mi_segment_try_purge(segment, mi_option_is_enabled(mi_option_abandoned_page_purge) /* force? */, tld->stats); + + // all pages in the segment are abandoned; add it to the abandoned list + _mi_stat_increase(&tld->stats->segments_abandoned, 1); + mi_segments_track_size(-((long)mi_segment_size(segment)), tld); + segment->thread_id = 0; + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); + segment->abandoned_visits = 1; // from 0 to 1 to signify it is abandoned + mi_abandoned_push(segment); +} + +void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert(page != NULL); + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_assert_internal(mi_page_heap(page) == NULL); + mi_segment_t* segment = _mi_page_segment(page); + + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + segment->abandoned++; + + _mi_stat_increase(&tld->stats->pages_abandoned, 1); + mi_assert_internal(segment->abandoned <= segment->used); + if (segment->used == segment->abandoned) { + // all pages are abandoned, abandon the entire segment + mi_segment_abandon(segment, tld); + } +} + +/* ----------------------------------------------------------- + Reclaim abandoned pages +----------------------------------------------------------- */ + +static mi_slice_t* mi_slices_start_iterate(mi_segment_t* segment, const mi_slice_t** end) { + mi_slice_t* slice = &segment->slices[0]; + *end = mi_segment_slices_end(segment); + mi_assert_internal(slice->slice_count>0 && slice->xblock_size>0); // segment allocated page + slice = slice + slice->slice_count; // skip the first segment allocated page + return slice; +} + +// Possibly free pages and check if free space is available +static bool mi_segment_check_free(mi_segment_t* segment, size_t slices_needed, size_t block_size, mi_segments_tld_t* tld) +{ + mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); + mi_assert_internal(mi_segment_is_abandoned(segment)); + bool has_page = false; + + // for all slices + const mi_slice_t* end; + mi_slice_t* slice = mi_slices_start_iterate(segment, &end); + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + if (mi_slice_is_used(slice)) { // used page + // ensure used count is up to date and collect potential concurrent frees + mi_page_t* const page = mi_slice_to_page(slice); + _mi_page_free_collect(page, false); + if (mi_page_all_free(page)) { + // if this page is all free now, free it without adding to any queues (yet) + mi_assert_internal(page->next == NULL && page->prev==NULL); + _mi_stat_decrease(&tld->stats->pages_abandoned, 1); + segment->abandoned--; + slice = mi_segment_page_clear(page, tld); // re-assign slice due to coalesce! + mi_assert_internal(!mi_slice_is_used(slice)); + if (slice->slice_count >= slices_needed) { + has_page = true; + } + } + else { + if (page->xblock_size == block_size && mi_page_has_any_available(page)) { + // a page has available free blocks of the right size + has_page = true; + } + } + } + else { + // empty span + if (slice->slice_count >= slices_needed) { + has_page = true; + } + } + slice = slice + slice->slice_count; + } + return has_page; +} + +// Reclaim an abandoned segment; returns NULL if the segment was freed +// set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full. +static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) { + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; } + + segment->thread_id = _mi_thread_id(); + segment->abandoned_visits = 0; + mi_segments_track_size((long)mi_segment_size(segment), tld); + mi_assert_internal(segment->next == NULL); + _mi_stat_decrease(&tld->stats->segments_abandoned, 1); + + // for all slices + const mi_slice_t* end; + mi_slice_t* slice = mi_slices_start_iterate(segment, &end); + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + if (mi_slice_is_used(slice)) { + // in use: reclaim the page in our heap + mi_page_t* page = mi_slice_to_page(slice); + mi_assert_internal(page->is_committed); + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_assert_internal(mi_page_heap(page) == NULL); + mi_assert_internal(page->next == NULL && page->prev==NULL); + _mi_stat_decrease(&tld->stats->pages_abandoned, 1); + segment->abandoned--; + // set the heap again and allow delayed free again + mi_page_set_heap(page, heap); + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set) + _mi_page_free_collect(page, false); // ensure used count is up to date + if (mi_page_all_free(page)) { + // if everything free by now, free the page + slice = mi_segment_page_clear(page, tld); // set slice again due to coalesceing + } + else { + // otherwise reclaim it into the heap + _mi_page_reclaim(heap, page); + if (requested_block_size == page->xblock_size && mi_page_has_any_available(page)) { + if (right_page_reclaimed != NULL) { *right_page_reclaimed = true; } + } + } + } + else { + // the span is free, add it to our page queues + slice = mi_segment_span_free_coalesce(slice, tld); // set slice again due to coalesceing + } + mi_assert_internal(slice->slice_count>0 && slice->slice_offset==0); + slice = slice + slice->slice_count; + } + + mi_assert(segment->abandoned == 0); + if (segment->used == 0) { // due to page_clear + mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed)); + mi_segment_free(segment, false, tld); + return NULL; + } + else { + return segment; + } +} + + +void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld) { + mi_segment_t* segment; + while ((segment = mi_abandoned_pop()) != NULL) { + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } +} + +static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slices, size_t block_size, bool* reclaimed, mi_segments_tld_t* tld) +{ + *reclaimed = false; + mi_segment_t* segment; + long max_tries = mi_option_get_clamp(mi_option_max_segment_reclaim, 8, 1024); // limit the work to bound allocation times + while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { + segment->abandoned_visits++; + // todo: an arena exclusive heap will potentially visit many abandoned unsuitable segments + // and push them into the visited list and use many tries. Perhaps we can skip non-suitable ones in a better way? + bool is_suitable = _mi_heap_memid_is_suitable(heap, segment->memid); + bool has_page = mi_segment_check_free(segment,needed_slices,block_size,tld); // try to free up pages (due to concurrent frees) + if (segment->used == 0) { + // free the segment (by forced reclaim) to make it available to other threads. + // note1: we prefer to free a segment as that might lead to reclaiming another + // segment that is still partially used. + // note2: we could in principle optimize this by skipping reclaim and directly + // freeing but that would violate some invariants temporarily) + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else if (has_page && is_suitable) { + // found a large enough free span, or a page of the right block_size with free space + // we return the result of reclaim (which is usually `segment`) as it might free + // the segment due to concurrent frees (in which case `NULL` is returned). + return mi_segment_reclaim(segment, heap, block_size, reclaimed, tld); + } + else if (segment->abandoned_visits > 3 && is_suitable) { + // always reclaim on 3rd visit to limit the abandoned queue length. + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else { + // otherwise, push on the visited list so it gets not looked at too quickly again + mi_segment_try_purge(segment, true /* force? */, tld->stats); // force purge if needed as we may not visit soon again + mi_abandoned_visited_push(segment); + } + } + return NULL; +} + + +void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld) +{ + mi_segment_t* segment; + int max_tries = (force ? 16*1024 : 1024); // limit latency + if (force) { + mi_abandoned_visited_revisit(); + } + while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { + mi_segment_check_free(segment,0,0,tld); // try to free up pages (due to concurrent frees) + if (segment->used == 0) { + // free the segment (by forced reclaim) to make it available to other threads. + // note: we could in principle optimize this by skipping reclaim and directly + // freeing but that would violate some invariants temporarily) + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else { + // otherwise, purge if needed and push on the visited list + // note: forced purge can be expensive if many threads are destroyed/created as in mstress. + mi_segment_try_purge(segment, force, tld->stats); + mi_abandoned_visited_push(segment); + } + } +} + +/* ----------------------------------------------------------- + Reclaim or allocate +----------------------------------------------------------- */ + +static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_slices, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); + mi_assert_internal(block_size <= MI_LARGE_OBJ_SIZE_MAX); + + // 1. try to reclaim an abandoned segment + bool reclaimed; + mi_segment_t* segment = mi_segment_try_reclaim(heap, needed_slices, block_size, &reclaimed, tld); + if (reclaimed) { + // reclaimed the right page right into the heap + mi_assert_internal(segment != NULL); + return NULL; // pretend out-of-memory as the page will be in the page queue of the heap with available blocks + } + else if (segment != NULL) { + // reclaimed a segment with a large enough empty span in it + return segment; + } + // 2. otherwise allocate a fresh segment + return mi_segment_alloc(0, 0, heap->arena_id, tld, os_tld, NULL); +} + + +/* ----------------------------------------------------------- + Page allocation +----------------------------------------------------------- */ + +static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_kind, size_t required, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_assert_internal(required <= MI_LARGE_OBJ_SIZE_MAX && page_kind <= MI_PAGE_LARGE); + + // find a free page + size_t page_size = _mi_align_up(required, (required > MI_MEDIUM_PAGE_SIZE ? MI_MEDIUM_PAGE_SIZE : MI_SEGMENT_SLICE_SIZE)); + size_t slices_needed = page_size / MI_SEGMENT_SLICE_SIZE; + mi_assert_internal(slices_needed * MI_SEGMENT_SLICE_SIZE == page_size); + mi_page_t* page = mi_segments_page_find_and_allocate(slices_needed, heap->arena_id, tld); //(required <= MI_SMALL_SIZE_MAX ? 0 : slices_needed), tld); + if (page==NULL) { + // no free page, allocate a new segment and try again + if (mi_segment_reclaim_or_alloc(heap, slices_needed, block_size, tld, os_tld) == NULL) { + // OOM or reclaimed a good page in the heap + return NULL; + } + else { + // otherwise try again + return mi_segments_page_alloc(heap, page_kind, required, block_size, tld, os_tld); + } + } + mi_assert_internal(page != NULL && page->slice_count*MI_SEGMENT_SLICE_SIZE == page_size); + mi_assert_internal(_mi_ptr_segment(page)->thread_id == _mi_thread_id()); + mi_segment_try_purge(_mi_ptr_segment(page), false, tld->stats); + return page; +} + + + +/* ----------------------------------------------------------- + Huge page allocation +----------------------------------------------------------- */ + +static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_page_t* page = NULL; + mi_segment_t* segment = mi_segment_alloc(size,page_alignment,req_arena_id,tld,os_tld,&page); + if (segment == NULL || page==NULL) return NULL; + mi_assert_internal(segment->used==1); + mi_assert_internal(mi_page_block_size(page) >= size); + #if MI_HUGE_PAGE_ABANDON + segment->thread_id = 0; // huge segments are immediately abandoned + #endif + + // for huge pages we initialize the xblock_size as we may + // overallocate to accommodate large alignments. + size_t psize; + uint8_t* start = _mi_segment_page_start(segment, page, &psize); + page->xblock_size = (psize > MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : (uint32_t)psize); + + // decommit the part of the prefix of a page that will not be used; this can be quite large (close to MI_SEGMENT_SIZE) + if (page_alignment > 0 && segment->allow_decommit) { + uint8_t* aligned_p = (uint8_t*)_mi_align_up((uintptr_t)start, page_alignment); + mi_assert_internal(_mi_is_aligned(aligned_p, page_alignment)); + mi_assert_internal(psize - (aligned_p - start) >= size); + uint8_t* decommit_start = start + sizeof(mi_block_t); // for the free list + ptrdiff_t decommit_size = aligned_p - decommit_start; + _mi_os_reset(decommit_start, decommit_size, &_mi_stats_main); // note: cannot use segment_decommit on huge segments + } + + return page; +} + +#if MI_HUGE_PAGE_ABANDON +// free huge block from another thread +void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) { + // huge page segments are always abandoned and can be freed immediately by any thread + mi_assert_internal(segment->kind==MI_SEGMENT_HUGE); + mi_assert_internal(segment == _mi_page_segment(page)); + mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id)==0); + + // claim it and free + mi_heap_t* heap = mi_heap_get_default(); // issue #221; don't use the internal get_default_heap as we need to ensure the thread is initialized. + // paranoia: if this it the last reference, the cas should always succeed + size_t expected_tid = 0; + if (mi_atomic_cas_strong_acq_rel(&segment->thread_id, &expected_tid, heap->thread_id)) { + mi_block_set_next(page, block, page->free); + page->free = block; + page->used--; + page->is_zero = false; + mi_assert(page->used == 0); + mi_tld_t* tld = heap->tld; + _mi_segment_page_free(page, true, &tld->segments); + } +#if (MI_DEBUG!=0) + else { + mi_assert_internal(false); + } +#endif +} + +#else +// reset memory of a huge block from another thread +void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) { + MI_UNUSED(page); + mi_assert_internal(segment->kind == MI_SEGMENT_HUGE); + mi_assert_internal(segment == _mi_page_segment(page)); + mi_assert_internal(page->used == 1); // this is called just before the free + mi_assert_internal(page->free == NULL); + if (segment->allow_decommit) { + size_t csize = mi_usable_size(block); + if (csize > sizeof(mi_block_t)) { + csize = csize - sizeof(mi_block_t); + uint8_t* p = (uint8_t*)block + sizeof(mi_block_t); + _mi_os_reset(p, csize, &_mi_stats_main); // note: cannot use segment_decommit on huge segments + } + } +} +#endif + +/* ----------------------------------------------------------- + Page allocation and free +----------------------------------------------------------- */ +mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + mi_page_t* page; + if mi_unlikely(page_alignment > MI_ALIGNMENT_MAX) { + mi_assert_internal(_mi_is_power_of_two(page_alignment)); + mi_assert_internal(page_alignment >= MI_SEGMENT_SIZE); + if (page_alignment < MI_SEGMENT_SIZE) { page_alignment = MI_SEGMENT_SIZE; } + page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld,os_tld); + } + else if (block_size <= MI_SMALL_OBJ_SIZE_MAX) { + page = mi_segments_page_alloc(heap,MI_PAGE_SMALL,block_size,block_size,tld,os_tld); + } + else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) { + page = mi_segments_page_alloc(heap,MI_PAGE_MEDIUM,MI_MEDIUM_PAGE_SIZE,block_size,tld, os_tld); + } + else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) { + page = mi_segments_page_alloc(heap,MI_PAGE_LARGE,block_size,block_size,tld, os_tld); + } + else { + page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld,os_tld); + } + mi_assert_internal(page == NULL || _mi_heap_memid_is_suitable(heap, _mi_page_segment(page)->memid)); + mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld)); + return page; +} + + diff --git a/lib/Utils.Memory/mimalloc/src/static.c b/lib/Utils.Memory/mimalloc/src/static.c new file mode 100644 index 0000000..bc05dd7 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/static.c @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif +#if defined(__sun) +// same remarks as os.c for the static's context. +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#include "mimalloc.h" +#include "mimalloc/internal.h" + +// For a static override we create a single object file +// containing the whole library. If it is linked first +// it will override all the standard library allocation +// functions (on Unix's). +#include "alloc.c" // includes alloc-override.c +#include "alloc-aligned.c" +#include "alloc-posix.c" +#include "arena.c" +#include "bitmap.c" +#include "heap.c" +#include "init.c" +#include "options.c" +#include "os.c" +#include "page.c" // includes page-queue.c +#include "random.c" +#include "segment.c" +#include "segment-map.c" +#include "stats.c" +#include "prim/prim.c" +#if MI_OSX_ZONE +#include "prim/osx/alloc-override-zone.c" +#endif diff --git a/lib/Utils.Memory/mimalloc/src/stats.c b/lib/Utils.Memory/mimalloc/src/stats.c new file mode 100644 index 0000000..300956c --- /dev/null +++ b/lib/Utils.Memory/mimalloc/src/stats.c @@ -0,0 +1,467 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + +#include <stdio.h> // snprintf +#include <string.h> // memset + +#if defined(_MSC_VER) && (_MSC_VER < 1920) +#pragma warning(disable:4204) // non-constant aggregate initializer +#endif + +/* ----------------------------------------------------------- + Statistics operations +----------------------------------------------------------- */ + +static bool mi_is_in_main(void* stat) { + return ((uint8_t*)stat >= (uint8_t*)&_mi_stats_main + && (uint8_t*)stat < ((uint8_t*)&_mi_stats_main + sizeof(mi_stats_t))); +} + +static void mi_stat_update(mi_stat_count_t* stat, int64_t amount) { + if (amount == 0) return; + if (mi_is_in_main(stat)) + { + // add atomically (for abandoned pages) + int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount); + mi_atomic_maxi64_relaxed(&stat->peak, current + amount); + if (amount > 0) { + mi_atomic_addi64_relaxed(&stat->allocated,amount); + } + else { + mi_atomic_addi64_relaxed(&stat->freed, -amount); + } + } + else { + // add thread local + stat->current += amount; + if (stat->current > stat->peak) stat->peak = stat->current; + if (amount > 0) { + stat->allocated += amount; + } + else { + stat->freed += -amount; + } + } +} + +void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) { + if (mi_is_in_main(stat)) { + mi_atomic_addi64_relaxed( &stat->count, 1 ); + mi_atomic_addi64_relaxed( &stat->total, (int64_t)amount ); + } + else { + stat->count++; + stat->total += amount; + } +} + +void _mi_stat_increase(mi_stat_count_t* stat, size_t amount) { + mi_stat_update(stat, (int64_t)amount); +} + +void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount) { + mi_stat_update(stat, -((int64_t)amount)); +} + +// must be thread safe as it is called from stats_merge +static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src, int64_t unit) { + if (stat==src) return; + if (src->allocated==0 && src->freed==0) return; + mi_atomic_addi64_relaxed( &stat->allocated, src->allocated * unit); + mi_atomic_addi64_relaxed( &stat->current, src->current * unit); + mi_atomic_addi64_relaxed( &stat->freed, src->freed * unit); + // peak scores do not work across threads.. + mi_atomic_addi64_relaxed( &stat->peak, src->peak * unit); +} + +static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src, int64_t unit) { + if (stat==src) return; + mi_atomic_addi64_relaxed( &stat->total, src->total * unit); + mi_atomic_addi64_relaxed( &stat->count, src->count * unit); +} + +// must be thread safe as it is called from stats_merge +static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) { + if (stats==src) return; + mi_stat_add(&stats->segments, &src->segments,1); + mi_stat_add(&stats->pages, &src->pages,1); + mi_stat_add(&stats->reserved, &src->reserved, 1); + mi_stat_add(&stats->committed, &src->committed, 1); + mi_stat_add(&stats->reset, &src->reset, 1); + mi_stat_add(&stats->purged, &src->purged, 1); + mi_stat_add(&stats->page_committed, &src->page_committed, 1); + + mi_stat_add(&stats->pages_abandoned, &src->pages_abandoned, 1); + mi_stat_add(&stats->segments_abandoned, &src->segments_abandoned, 1); + mi_stat_add(&stats->threads, &src->threads, 1); + + mi_stat_add(&stats->malloc, &src->malloc, 1); + mi_stat_add(&stats->segments_cache, &src->segments_cache, 1); + mi_stat_add(&stats->normal, &src->normal, 1); + mi_stat_add(&stats->huge, &src->huge, 1); + mi_stat_add(&stats->large, &src->large, 1); + + mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1); + mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls, 1); + mi_stat_counter_add(&stats->commit_calls, &src->commit_calls, 1); + mi_stat_counter_add(&stats->reset_calls, &src->reset_calls, 1); + mi_stat_counter_add(&stats->purge_calls, &src->purge_calls, 1); + + mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1); + mi_stat_counter_add(&stats->searches, &src->searches, 1); + mi_stat_counter_add(&stats->normal_count, &src->normal_count, 1); + mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1); + mi_stat_counter_add(&stats->large_count, &src->large_count, 1); +#if MI_STAT>1 + for (size_t i = 0; i <= MI_BIN_HUGE; i++) { + if (src->normal_bins[i].allocated > 0 || src->normal_bins[i].freed > 0) { + mi_stat_add(&stats->normal_bins[i], &src->normal_bins[i], 1); + } + } +#endif +} + +/* ----------------------------------------------------------- + Display statistics +----------------------------------------------------------- */ + +// unit > 0 : size in binary bytes +// unit == 0: count as decimal +// unit < 0 : count in binary +static void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) { + char buf[32]; buf[0] = 0; + int len = 32; + const char* suffix = (unit <= 0 ? " " : "B"); + const int64_t base = (unit == 0 ? 1000 : 1024); + if (unit>0) n *= unit; + + const int64_t pos = (n < 0 ? -n : n); + if (pos < base) { + if (n!=1 || suffix[0] != 'B') { // skip printing 1 B for the unit column + snprintf(buf, len, "%d %-3s", (int)n, (n==0 ? "" : suffix)); + } + } + else { + int64_t divider = base; + const char* magnitude = "K"; + if (pos >= divider*base) { divider *= base; magnitude = "M"; } + if (pos >= divider*base) { divider *= base; magnitude = "G"; } + const int64_t tens = (n / (divider/10)); + const long whole = (long)(tens/10); + const long frac1 = (long)(tens%10); + char unitdesc[8]; + snprintf(unitdesc, 8, "%s%s%s", magnitude, (base==1024 ? "i" : ""), suffix); + snprintf(buf, len, "%ld.%ld %-3s", whole, (frac1 < 0 ? -frac1 : frac1), unitdesc); + } + _mi_fprintf(out, arg, (fmt==NULL ? "%12s" : fmt), buf); +} + + +static void mi_print_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { + mi_printf_amount(n,unit,out,arg,NULL); +} + +static void mi_print_count(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { + if (unit==1) _mi_fprintf(out, arg, "%12s"," "); + else mi_print_amount(n,0,out,arg); +} + +static void mi_stat_print_ex(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg, const char* notok ) { + _mi_fprintf(out, arg,"%10s:", msg); + if (unit > 0) { + mi_print_amount(stat->peak, unit, out, arg); + mi_print_amount(stat->allocated, unit, out, arg); + mi_print_amount(stat->freed, unit, out, arg); + mi_print_amount(stat->current, unit, out, arg); + mi_print_amount(unit, 1, out, arg); + mi_print_count(stat->allocated, unit, out, arg); + if (stat->allocated > stat->freed) { + _mi_fprintf(out, arg, " "); + _mi_fprintf(out, arg, (notok == NULL ? "not all freed" : notok)); + _mi_fprintf(out, arg, "\n"); + } + else { + _mi_fprintf(out, arg, " ok\n"); + } + } + else if (unit<0) { + mi_print_amount(stat->peak, -1, out, arg); + mi_print_amount(stat->allocated, -1, out, arg); + mi_print_amount(stat->freed, -1, out, arg); + mi_print_amount(stat->current, -1, out, arg); + if (unit==-1) { + _mi_fprintf(out, arg, "%24s", ""); + } + else { + mi_print_amount(-unit, 1, out, arg); + mi_print_count((stat->allocated / -unit), 0, out, arg); + } + if (stat->allocated > stat->freed) + _mi_fprintf(out, arg, " not all freed!\n"); + else + _mi_fprintf(out, arg, " ok\n"); + } + else { + mi_print_amount(stat->peak, 1, out, arg); + mi_print_amount(stat->allocated, 1, out, arg); + _mi_fprintf(out, arg, "%11s", " "); // no freed + mi_print_amount(stat->current, 1, out, arg); + _mi_fprintf(out, arg, "\n"); + } +} + +static void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) { + mi_stat_print_ex(stat, msg, unit, out, arg, NULL); +} + +static void mi_stat_peak_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) { + _mi_fprintf(out, arg, "%10s:", msg); + mi_print_amount(stat->peak, unit, out, arg); + _mi_fprintf(out, arg, "\n"); +} + +static void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg, "%10s:", msg); + mi_print_amount(stat->total, -1, out, arg); + _mi_fprintf(out, arg, "\n"); +} + + +static void mi_stat_counter_print_avg(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg) { + const int64_t avg_tens = (stat->count == 0 ? 0 : (stat->total*10 / stat->count)); + const long avg_whole = (long)(avg_tens/10); + const long avg_frac1 = (long)(avg_tens%10); + _mi_fprintf(out, arg, "%10s: %5ld.%ld avg\n", msg, avg_whole, avg_frac1); +} + + +static void mi_print_header(mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg, "%10s: %11s %11s %11s %11s %11s %11s\n", "heap stats", "peak ", "total ", "freed ", "current ", "unit ", "count "); +} + +#if MI_STAT>1 +static void mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) { + bool found = false; + char buf[64]; + for (size_t i = 0; i <= max; i++) { + if (bins[i].allocated > 0) { + found = true; + int64_t unit = _mi_bin_size((uint8_t)i); + snprintf(buf, 64, "%s %3lu", fmt, (long)i); + mi_stat_print(&bins[i], buf, unit, out, arg); + } + } + if (found) { + _mi_fprintf(out, arg, "\n"); + mi_print_header(out, arg); + } +} +#endif + + + +//------------------------------------------------------------ +// Use an output wrapper for line-buffered output +// (which is nice when using loggers etc.) +//------------------------------------------------------------ +typedef struct buffered_s { + mi_output_fun* out; // original output function + void* arg; // and state + char* buf; // local buffer of at least size `count+1` + size_t used; // currently used chars `used <= count` + size_t count; // total chars available for output +} buffered_t; + +static void mi_buffered_flush(buffered_t* buf) { + buf->buf[buf->used] = 0; + _mi_fputs(buf->out, buf->arg, NULL, buf->buf); + buf->used = 0; +} + +static void mi_cdecl mi_buffered_out(const char* msg, void* arg) { + buffered_t* buf = (buffered_t*)arg; + if (msg==NULL || buf==NULL) return; + for (const char* src = msg; *src != 0; src++) { + char c = *src; + if (buf->used >= buf->count) mi_buffered_flush(buf); + mi_assert_internal(buf->used < buf->count); + buf->buf[buf->used++] = c; + if (c == '\n') mi_buffered_flush(buf); + } +} + +//------------------------------------------------------------ +// Print statistics +//------------------------------------------------------------ + +static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept { + // wrap the output function to be line buffered + char buf[256]; + buffered_t buffer = { out0, arg0, NULL, 0, 255 }; + buffer.buf = buf; + mi_output_fun* out = &mi_buffered_out; + void* arg = &buffer; + + // and print using that + mi_print_header(out,arg); + #if MI_STAT>1 + mi_stats_print_bins(stats->normal_bins, MI_BIN_HUGE, "normal",out,arg); + #endif + #if MI_STAT + mi_stat_print(&stats->normal, "normal", (stats->normal_count.count == 0 ? 1 : -(stats->normal.allocated / stats->normal_count.count)), out, arg); + mi_stat_print(&stats->large, "large", (stats->large_count.count == 0 ? 1 : -(stats->large.allocated / stats->large_count.count)), out, arg); + mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out, arg); + mi_stat_count_t total = { 0,0,0,0 }; + mi_stat_add(&total, &stats->normal, 1); + mi_stat_add(&total, &stats->large, 1); + mi_stat_add(&total, &stats->huge, 1); + mi_stat_print(&total, "total", 1, out, arg); + #endif + #if MI_STAT>1 + mi_stat_print(&stats->malloc, "malloc req", 1, out, arg); + _mi_fprintf(out, arg, "\n"); + #endif + mi_stat_print_ex(&stats->reserved, "reserved", 1, out, arg, ""); + mi_stat_print_ex(&stats->committed, "committed", 1, out, arg, ""); + mi_stat_peak_print(&stats->reset, "reset", 1, out, arg ); + mi_stat_peak_print(&stats->purged, "purged", 1, out, arg ); + mi_stat_print(&stats->page_committed, "touched", 1, out, arg); + mi_stat_print(&stats->segments, "segments", -1, out, arg); + mi_stat_print(&stats->segments_abandoned, "-abandoned", -1, out, arg); + mi_stat_print(&stats->segments_cache, "-cached", -1, out, arg); + mi_stat_print(&stats->pages, "pages", -1, out, arg); + mi_stat_print(&stats->pages_abandoned, "-abandoned", -1, out, arg); + mi_stat_counter_print(&stats->pages_extended, "-extended", out, arg); + mi_stat_counter_print(&stats->page_no_retire, "-noretire", out, arg); + mi_stat_counter_print(&stats->mmap_calls, "mmaps", out, arg); + mi_stat_counter_print(&stats->commit_calls, "commits", out, arg); + mi_stat_counter_print(&stats->reset_calls, "resets", out, arg); + mi_stat_counter_print(&stats->purge_calls, "purges", out, arg); + mi_stat_print(&stats->threads, "threads", -1, out, arg); + mi_stat_counter_print_avg(&stats->searches, "searches", out, arg); + _mi_fprintf(out, arg, "%10s: %5zu\n", "numa nodes", _mi_os_numa_node_count()); + + size_t elapsed; + size_t user_time; + size_t sys_time; + size_t current_rss; + size_t peak_rss; + size_t current_commit; + size_t peak_commit; + size_t page_faults; + mi_process_info(&elapsed, &user_time, &sys_time, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults); + _mi_fprintf(out, arg, "%10s: %5ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000); + _mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, rss: ", "process", + user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults ); + mi_printf_amount((int64_t)peak_rss, 1, out, arg, "%s"); + if (peak_commit > 0) { + _mi_fprintf(out, arg, ", commit: "); + mi_printf_amount((int64_t)peak_commit, 1, out, arg, "%s"); + } + _mi_fprintf(out, arg, "\n"); +} + +static mi_msecs_t mi_process_start; // = 0 + +static mi_stats_t* mi_stats_get_default(void) { + mi_heap_t* heap = mi_heap_get_default(); + return &heap->tld->stats; +} + +static void mi_stats_merge_from(mi_stats_t* stats) { + if (stats != &_mi_stats_main) { + mi_stats_add(&_mi_stats_main, stats); + memset(stats, 0, sizeof(mi_stats_t)); + } +} + +void mi_stats_reset(void) mi_attr_noexcept { + mi_stats_t* stats = mi_stats_get_default(); + if (stats != &_mi_stats_main) { memset(stats, 0, sizeof(mi_stats_t)); } + memset(&_mi_stats_main, 0, sizeof(mi_stats_t)); + if (mi_process_start == 0) { mi_process_start = _mi_clock_start(); }; +} + +void mi_stats_merge(void) mi_attr_noexcept { + mi_stats_merge_from( mi_stats_get_default() ); +} + +void _mi_stats_done(mi_stats_t* stats) { // called from `mi_thread_done` + mi_stats_merge_from(stats); +} + +void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_stats_merge_from(mi_stats_get_default()); + _mi_stats_print(&_mi_stats_main, out, arg); +} + +void mi_stats_print(void* out) mi_attr_noexcept { + // for compatibility there is an `out` parameter (which can be `stdout` or `stderr`) + mi_stats_print_out((mi_output_fun*)out, NULL); +} + +void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { + _mi_stats_print(mi_stats_get_default(), out, arg); +} + + +// ---------------------------------------------------------------- +// Basic timer for convenience; use milli-seconds to avoid doubles +// ---------------------------------------------------------------- + +static mi_msecs_t mi_clock_diff; + +mi_msecs_t _mi_clock_now(void) { + return _mi_prim_clock_now(); +} + +mi_msecs_t _mi_clock_start(void) { + if (mi_clock_diff == 0.0) { + mi_msecs_t t0 = _mi_clock_now(); + mi_clock_diff = _mi_clock_now() - t0; + } + return _mi_clock_now(); +} + +mi_msecs_t _mi_clock_end(mi_msecs_t start) { + mi_msecs_t end = _mi_clock_now(); + return (end - start - mi_clock_diff); +} + + +// -------------------------------------------------------- +// Basic process statistics +// -------------------------------------------------------- + +mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept +{ + mi_process_info_t pinfo; + _mi_memzero_var(pinfo); + pinfo.elapsed = _mi_clock_end(mi_process_start); + pinfo.current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); + pinfo.peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); + pinfo.current_rss = pinfo.current_commit; + pinfo.peak_rss = pinfo.peak_commit; + pinfo.utime = 0; + pinfo.stime = 0; + pinfo.page_faults = 0; + + _mi_prim_process_info(&pinfo); + + if (elapsed_msecs!=NULL) *elapsed_msecs = (pinfo.elapsed < 0 ? 0 : (pinfo.elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.elapsed : PTRDIFF_MAX)); + if (user_msecs!=NULL) *user_msecs = (pinfo.utime < 0 ? 0 : (pinfo.utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.utime : PTRDIFF_MAX)); + if (system_msecs!=NULL) *system_msecs = (pinfo.stime < 0 ? 0 : (pinfo.stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.stime : PTRDIFF_MAX)); + if (current_rss!=NULL) *current_rss = pinfo.current_rss; + if (peak_rss!=NULL) *peak_rss = pinfo.peak_rss; + if (current_commit!=NULL) *current_commit = pinfo.current_commit; + if (peak_commit!=NULL) *peak_commit = pinfo.peak_commit; + if (page_faults!=NULL) *page_faults = pinfo.page_faults; +} diff --git a/lib/Utils.Memory/mimalloc/test/CMakeLists.txt b/lib/Utils.Memory/mimalloc/test/CMakeLists.txt new file mode 100644 index 0000000..e76ffa6 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.0) +project(mimalloc-test C CXX) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +# Set default build type +if (NOT CMAKE_BUILD_TYPE) + if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$") + message(STATUS "No build type selected, default to *** Debug ***") + set(CMAKE_BUILD_TYPE "Debug") + else() + message(STATUS "No build type selected, default to *** Release ***") + set(CMAKE_BUILD_TYPE "Release") + endif() +endif() + +# Import mimalloc (if installed) +find_package(mimalloc 2.0 REQUIRED NO_SYSTEM_ENVIRONMENT_PATH) +message(STATUS "Found mimalloc installed at: ${MIMALLOC_LIBRARY_DIR} (${MIMALLOC_VERSION_DIR})") + +# overriding with a dynamic library +add_executable(dynamic-override main-override.c) +target_link_libraries(dynamic-override PUBLIC mimalloc) + +add_executable(dynamic-override-cxx main-override.cpp) +target_link_libraries(dynamic-override-cxx PUBLIC mimalloc) + + +# overriding with a static object file works reliable as the symbols in the +# object file have priority over those in library files +add_executable(static-override-obj main-override.c ${MIMALLOC_OBJECT_DIR}/mimalloc.o) +target_include_directories(static-override-obj PUBLIC ${MIMALLOC_INCLUDE_DIR}) +target_link_libraries(static-override-obj PUBLIC pthread) + + +# overriding with a static library works too if using the `mimalloc-override.h` +# header to redefine malloc/free. (the library already overrides new/delete) +add_executable(static-override-static main-override-static.c) +target_link_libraries(static-override-static PUBLIC mimalloc-static) + + +# overriding with a static library: this may not work if the library is linked too late +# on the command line after the C runtime library; but we cannot control that well in CMake +add_executable(static-override main-override.c) +target_link_libraries(static-override PUBLIC mimalloc-static) + +add_executable(static-override-cxx main-override.cpp) +target_link_libraries(static-override-cxx PUBLIC mimalloc-static) + + +## test memory errors +add_executable(test-wrong test-wrong.c) +target_link_libraries(test-wrong PUBLIC mimalloc) diff --git a/lib/Utils.Memory/mimalloc/test/main-override-static.c b/lib/Utils.Memory/mimalloc/test/main-override-static.c new file mode 100644 index 0000000..e71be29 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/main-override-static.c @@ -0,0 +1,415 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <stdint.h> + +#include <mimalloc.h> +#include <mimalloc-override.h> // redefines malloc etc. + + +static void double_free1(); +static void double_free2(); +static void corrupt_free(); +static void block_overflow1(); +static void invalid_free(); +static void test_aslr(void); +static void test_process_info(void); +static void test_reserved(void); +static void negative_stat(void); +static void alloc_huge(void); +static void test_heap_walk(void); +static void test_heap_arena(void); +static void test_align(void); + +int main() { + mi_version(); + mi_stats_reset(); + // detect double frees and heap corruption + // double_free1(); + // double_free2(); + // corrupt_free(); + // block_overflow1(); + // test_aslr(); + // invalid_free(); + // test_reserved(); + // negative_stat(); + // test_heap_walk(); + // alloc_huge(); + // test_heap_walk(); + // test_heap_arena(); + // test_align(); + + void* p1 = malloc(78); + void* p2 = malloc(24); + free(p1); + p1 = mi_malloc(8); + char* s = strdup("hello\n"); + free(p2); + + mi_heap_t* h = mi_heap_new(); + mi_heap_set_default(h); + + p2 = malloc(16); + p1 = realloc(p1, 32); + free(p1); + free(p2); + free(s); + + /* now test if override worked by allocating/freeing across the api's*/ + //p1 = mi_malloc(32); + //free(p1); + //p2 = malloc(32); + //mi_free(p2); + + //mi_collect(true); + //mi_stats_print(NULL); + + // test_process_info(); + + return 0; +} + +static void test_align() { + void* p = mi_malloc_aligned(256, 256); + if (((uintptr_t)p % 256) != 0) { + fprintf(stderr, "%p is not 256 alignend!\n", p); + } +} + +static void invalid_free() { + free((void*)0xBADBEEF); + realloc((void*)0xBADBEEF,10); +} + +static void block_overflow1() { + uint8_t* p = (uint8_t*)mi_malloc(17); + p[18] = 0; + free(p); +} + +// The double free samples come ArcHeap [1] by Insu Yun (issue #161) +// [1]: https://arxiv.org/pdf/1903.00503.pdf + +static void double_free1() { + void* p[256]; + //uintptr_t buf[256]; + + p[0] = mi_malloc(622616); + p[1] = mi_malloc(655362); + p[2] = mi_malloc(786432); + mi_free(p[2]); + // [VULN] Double free + mi_free(p[2]); + p[3] = mi_malloc(786456); + // [BUG] Found overlap + // p[3]=0x429b2ea2000 (size=917504), p[1]=0x429b2e42000 (size=786432) + fprintf(stderr, "p3: %p-%p, p1: %p-%p, p2: %p\n", p[3], (uint8_t*)(p[3]) + 786456, p[1], (uint8_t*)(p[1]) + 655362, p[2]); +} + +static void double_free2() { + void* p[256]; + //uintptr_t buf[256]; + // [INFO] Command buffer: 0x327b2000 + // [INFO] Input size: 182 + p[0] = malloc(712352); + p[1] = malloc(786432); + free(p[0]); + // [VULN] Double free + free(p[0]); + p[2] = malloc(786440); + p[3] = malloc(917504); + p[4] = malloc(786440); + // [BUG] Found overlap + // p[4]=0x433f1402000 (size=917504), p[1]=0x433f14c2000 (size=786432) + fprintf(stderr, "p1: %p-%p, p2: %p-%p\n", p[4], (uint8_t*)(p[4]) + 917504, p[1], (uint8_t*)(p[1]) + 786432); +} + + +// Try to corrupt the heap through buffer overflow +#define N 256 +#define SZ 64 + +static void corrupt_free() { + void* p[N]; + // allocate + for (int i = 0; i < N; i++) { + p[i] = malloc(SZ); + } + // free some + for (int i = 0; i < N; i += (N/10)) { + free(p[i]); + p[i] = NULL; + } + // try to corrupt the free list + for (int i = 0; i < N; i++) { + if (p[i] != NULL) { + memset(p[i], 0, SZ+8); + } + } + // allocate more.. trying to trigger an allocation from a corrupted entry + // this may need many allocations to get there (if at all) + for (int i = 0; i < 4096; i++) { + malloc(SZ); + } +} + +static void test_aslr(void) { + void* p[256]; + p[0] = malloc(378200); + p[1] = malloc(1134626); + printf("p1: %p, p2: %p\n", p[0], p[1]); +} + +static void test_process_info(void) { + size_t elapsed = 0; + size_t user_msecs = 0; + size_t system_msecs = 0; + size_t current_rss = 0; + size_t peak_rss = 0; + size_t current_commit = 0; + size_t peak_commit = 0; + size_t page_faults = 0; + for (int i = 0; i < 100000; i++) { + void* p = calloc(100,10); + free(p); + } + mi_process_info(&elapsed, &user_msecs, &system_msecs, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults); + printf("\n\n*** process info: elapsed %3zd.%03zd s, user: %3zd.%03zd s, rss: %zd b, commit: %zd b\n\n", elapsed/1000, elapsed%1000, user_msecs/1000, user_msecs%1000, peak_rss, peak_commit); +} + +static void test_reserved(void) { +#define KiB 1024ULL +#define MiB (KiB*KiB) +#define GiB (MiB*KiB) + mi_reserve_os_memory(4*GiB, false, true); + void* p1 = malloc(100); + void* p2 = malloc(100000); + void* p3 = malloc(2*GiB); + void* p4 = malloc(1*GiB + 100000); + free(p1); + free(p2); + free(p3); + p3 = malloc(1*GiB); + free(p4); +} + + + +static void negative_stat(void) { + int* p = mi_malloc(60000); + mi_stats_print_out(NULL, NULL); + *p = 100; + mi_free(p); + mi_stats_print_out(NULL, NULL); +} + +static void alloc_huge(void) { + void* p = mi_malloc(67108872); + mi_free(p); +} + +static bool test_visit(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) { + if (block == NULL) { + printf("visiting an area with blocks of size %zu (including padding)\n", area->full_block_size); + } + else { + printf(" block of size %zu (allocated size is %zu)\n", block_size, mi_usable_size(block)); + } + return true; +} + +static void test_heap_walk(void) { + mi_heap_t* heap = mi_heap_new(); + mi_heap_malloc(heap, 16*2097152); + mi_heap_malloc(heap, 2067152); + mi_heap_malloc(heap, 2097160); + mi_heap_malloc(heap, 24576); + mi_heap_visit_blocks(heap, true, &test_visit, NULL); +} + +static void test_heap_arena(void) { + mi_arena_id_t arena_id; + int err = mi_reserve_os_memory_ex(100 * 1024 * 1024, false /* commit */, false /* allow large */, true /* exclusive */, &arena_id); + if (err) abort(); + mi_heap_t* heap = mi_heap_new_in_arena(arena_id); + for (int i = 0; i < 500000; i++) { + void* p = mi_heap_malloc(heap, 1024); + if (p == NULL) { + printf("out of memory after %d kb (expecting about 100_000kb)\n", i); + break; + } + } +} + +// ---------------------------- +// bin size experiments +// ------------------------------ + +#if 0 +#include <stdint.h> +#include <stdbool.h> + +#define MI_INTPTR_SIZE 8 +#define MI_LARGE_WSIZE_MAX (4*1024*1024 / MI_INTPTR_SIZE) + +#define MI_BIN_HUGE 100 +//#define MI_ALIGN2W + +// Bit scan reverse: return the index of the highest bit. +static inline uint8_t mi_bsr32(uint32_t x); + +#if defined(_MSC_VER) +#include <windows.h> +#include <intrin.h> +static inline uint8_t mi_bsr32(uint32_t x) { + uint32_t idx; + _BitScanReverse((DWORD*)&idx, x); + return idx; +} +#elif defined(__GNUC__) || defined(__clang__) +static inline uint8_t mi_bsr32(uint32_t x) { + return (31 - __builtin_clz(x)); +} +#else +static inline uint8_t mi_bsr32(uint32_t x) { + // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf> + static const uint8_t debruijn[32] = { + 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12, + 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13, + }; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return debruijn[(x*0x076be629) >> 27]; +} +#endif + +/* +// Bit scan reverse: return the index of the highest bit. +uint8_t _mi_bsr(uintptr_t x) { + if (x == 0) return 0; + #if MI_INTPTR_SIZE==8 + uint32_t hi = (x >> 32); + return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi)); + #elif MI_INTPTR_SIZE==4 + return mi_bsr32(x); + #else + # error "define bsr for non-32 or 64-bit platforms" + #endif +} +*/ + + +static inline size_t _mi_wsize_from_size(size_t size) { + return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); +} + +// Return the bin for a given field size. +// Returns MI_BIN_HUGE if the size is too large. +// We use `wsize` for the size in "machine word sizes", +// i.e. byte size == `wsize*sizeof(void*)`. +extern inline uint8_t _mi_bin8(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } +#if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } +#endif + else if (wsize > MI_LARGE_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { +#if defined(MI_ALIGN4W) + if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes +#endif + wsize--; + // find the highest bit + uint8_t b = mi_bsr32((uint32_t)wsize); + // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). + // - adjust with 3 because we use do not round the first 8 sizes + // which each get an exact bin + bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; + } + return bin; +} + +static inline uint8_t _mi_bin4(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } +#if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } +#endif + else if (wsize > MI_LARGE_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { + uint8_t b = mi_bsr32((uint32_t)wsize); + bin = ((b << 1) + (uint8_t)((wsize >> (b - 1)) & 0x01)) + 3; + } + return bin; +} + +static size_t _mi_binx4(size_t bsize) { + if (bsize==0) return 0; + uint8_t b = mi_bsr32((uint32_t)bsize); + if (b <= 1) return bsize; + size_t bin = ((b << 1) | (bsize >> (b - 1))&0x01); + return bin; +} + +static size_t _mi_binx8(size_t bsize) { + if (bsize<=1) return bsize; + uint8_t b = mi_bsr32((uint32_t)bsize); + if (b <= 2) return bsize; + size_t bin = ((b << 2) | (bsize >> (b - 2))&0x03) - 5; + return bin; +} + +static void mi_bins(void) { + //printf(" QNULL(1), /* 0 */ \\\n "); + size_t last_bin = 0; + size_t min_bsize = 0; + size_t last_bsize = 0; + for (size_t bsize = 1; bsize < 2*1024; bsize++) { + size_t size = bsize * 64 * 1024; + size_t bin = _mi_binx8(bsize); + if (bin != last_bin) { + printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_bsize, last_bsize, last_bin); + //printf("QNULL(%6zd), ", wsize); + //if (last_bin%8 == 0) printf("/* %i */ \\\n ", last_bin); + last_bin = bin; + min_bsize = bsize; + } + last_bsize = bsize; + } +} +#endif diff --git a/lib/Utils.Memory/mimalloc/test/main-override.c b/lib/Utils.Memory/mimalloc/test/main-override.c new file mode 100644 index 0000000..284fdd2 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/main-override.c @@ -0,0 +1,36 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> + +#include <mimalloc-override.h> + +int main() { + mi_version(); // ensure mimalloc library is linked + void* p1 = malloc(78); + void* p2 = malloc(24); + free(p1); + p1 = malloc(8); + //char* s = strdup("hello\n"); + free(p2); + p2 = malloc(16); + p1 = realloc(p1, 32); + free(p1); + free(p2); + //free(s); + //mi_collect(true); + + /* now test if override worked by allocating/freeing across the api's*/ + //p1 = mi_malloc(32); + //free(p1); + //p2 = malloc(32); + //mi_free(p2); + p1 = malloc(24); + p2 = reallocarray(p1, 16, 16); + free(p2); + p1 = malloc(24); + assert(reallocarr(&p1, 16, 16) == 0); + free(p1); + mi_stats_print(NULL); + return 0; +} diff --git a/lib/Utils.Memory/mimalloc/test/main-override.cpp b/lib/Utils.Memory/mimalloc/test/main-override.cpp new file mode 100644 index 0000000..c1607b6 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/main-override.cpp @@ -0,0 +1,400 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <stdint.h> + +#include <mimalloc.h> +#include <new> +#include <vector> +#include <future> +#include <iostream> + +#include <thread> +#include <mimalloc.h> +#include <assert.h> + +#ifdef _WIN32 +#include <mimalloc-new-delete.h> +#endif + +#ifdef _WIN32 +#include <Windows.h> +static void msleep(unsigned long msecs) { Sleep(msecs); } +#else +#include <unistd.h> +static void msleep(unsigned long msecs) { usleep(msecs * 1000UL); } +#endif + +static void heap_thread_free_large(); // issue #221 +static void heap_no_delete(); // issue #202 +static void heap_late_free(); // issue #204 +static void padding_shrink(); // issue #209 +static void various_tests(); +static void test_mt_shutdown(); +static void large_alloc(void); // issue #363 +static void fail_aslr(); // issue #372 +static void tsan_numa_test(); // issue #414 +static void strdup_test(); // issue #445 +static void bench_alloc_large(void); // issue #xxx +//static void test_large_migrate(void); // issue #691 +static void heap_thread_free_huge(); +static void test_std_string(); // issue #697 + +static void test_stl_allocators(); + + +int main() { + // mi_stats_reset(); // ignore earlier allocations + + // test_std_string(); + // heap_thread_free_huge(); + /* + heap_thread_free_huge(); + heap_thread_free_large(); + heap_no_delete(); + heap_late_free(); + padding_shrink(); + various_tests(); + large_alloc(); + tsan_numa_test(); + strdup_test(); + */ + // test_stl_allocators(); + // test_mt_shutdown(); + // test_large_migrate(); + + //fail_aslr(); + // bench_alloc_large(); + // mi_stats_print(NULL); + return 0; +} + +static void* p = malloc(8); + +void free_p() { + free(p); + return; +} + +class Test { +private: + int i; +public: + Test(int x) { i = x; } + ~Test() { } +}; + + +static void various_tests() { + atexit(free_p); + void* p1 = malloc(78); + void* p2 = mi_malloc_aligned(24, 16); + free(p1); + p1 = malloc(8); + char* s = mi_strdup("hello\n"); + + mi_free(p2); + p2 = malloc(16); + p1 = realloc(p1, 32); + free(p1); + free(p2); + mi_free(s); + + Test* t = new Test(42); + delete t; + t = new (std::nothrow) Test(42); + delete t; + auto tbuf = new unsigned char[sizeof(Test)]; + t = new (tbuf) Test(42); + t->~Test(); + delete tbuf; +} + +class Static { +private: + void* p; +public: + Static() { + p = malloc(64); + return; + } + ~Static() { + free(p); + return; + } +}; + +static Static s = Static(); + + +static bool test_stl_allocator1() { + std::vector<int, mi_stl_allocator<int> > vec; + vec.push_back(1); + vec.pop_back(); + return vec.size() == 0; +} + +struct some_struct { int i; int j; double z; }; + +static bool test_stl_allocator2() { + std::vector<some_struct, mi_stl_allocator<some_struct> > vec; + vec.push_back(some_struct()); + vec.pop_back(); + return vec.size() == 0; +} + +#if MI_HAS_HEAP_STL_ALLOCATOR +static bool test_stl_allocator3() { + std::vector<int, mi_heap_stl_allocator<int> > vec; + vec.push_back(1); + vec.pop_back(); + return vec.size() == 0; +} + +static bool test_stl_allocator4() { + std::vector<some_struct, mi_heap_stl_allocator<some_struct> > vec; + vec.push_back(some_struct()); + vec.pop_back(); + return vec.size() == 0; +} + +static bool test_stl_allocator5() { + std::vector<int, mi_heap_destroy_stl_allocator<int> > vec; + vec.push_back(1); + vec.pop_back(); + return vec.size() == 0; +} + +static bool test_stl_allocator6() { + std::vector<some_struct, mi_heap_destroy_stl_allocator<some_struct> > vec; + vec.push_back(some_struct()); + vec.pop_back(); + return vec.size() == 0; +} +#endif + +static void test_stl_allocators() { + test_stl_allocator1(); + test_stl_allocator2(); +#if MI_HAS_HEAP_STL_ALLOCATOR + test_stl_allocator3(); + test_stl_allocator4(); + test_stl_allocator5(); + test_stl_allocator6(); +#endif +} + +#if 0 +// issue #691 +static char* cptr; + +static void* thread1_allocate() +{ + cptr = mi_calloc_tp(char,22085632); + return NULL; +} + +static void* thread2_free() +{ + assert(cptr); + mi_free(cptr); + cptr = NULL; + return NULL; +} + +static void test_large_migrate(void) { + auto t1 = std::thread(thread1_allocate); + t1.join(); + auto t2 = std::thread(thread2_free); + t2.join(); + /* + pthread_t thread1, thread2; + + pthread_create(&thread1, NULL, &thread1_allocate, NULL); + pthread_join(thread1, NULL); + + pthread_create(&thread2, NULL, &thread2_free, NULL); + pthread_join(thread2, NULL); + */ + return; +} +#endif + +// issue 445 +static void strdup_test() { +#ifdef _MSC_VER + char* s = _strdup("hello\n"); + char* buf = NULL; + size_t len; + _dupenv_s(&buf, &len, "MIMALLOC_VERBOSE"); + mi_free(buf); + mi_free(s); +#endif +} + +// Issue #202 +static void heap_no_delete_worker() { + mi_heap_t* heap = mi_heap_new(); + void* q = mi_heap_malloc(heap, 1024); (void)(q); + // mi_heap_delete(heap); // uncomment to prevent assertion +} + +static void heap_no_delete() { + auto t1 = std::thread(heap_no_delete_worker); + t1.join(); +} + + +// Issue #697 +static void test_std_string() { + std::string path = "/Users/xxxx/Library/Developer/Xcode/DerivedData/xxxxxxxxxx/Build/Intermediates.noindex/xxxxxxxxxxx/arm64/XX_lto.o/0.arm64.lto.o"; + std::string path1 = "/Users/xxxx/Library/Developer/Xcode/DerivedData/xxxxxxxxxx/Build/Intermediates.noindex/xxxxxxxxxxx/arm64/XX_lto.o/1.arm64.lto.o"; + std::cout << path + "\n>>> " + path1 + "\n>>> " << std::endl; +} + +// Issue #204 +static volatile void* global_p; + +static void t1main() { + mi_heap_t* heap = mi_heap_new(); + global_p = mi_heap_malloc(heap, 1024); + mi_heap_delete(heap); +} + +static void heap_late_free() { + auto t1 = std::thread(t1main); + + msleep(2000); + assert(global_p); + mi_free((void*)global_p); + + t1.join(); +} + +// issue #209 +static void* shared_p; +static void alloc0(/* void* arg */) +{ + shared_p = mi_malloc(8); +} + +static void padding_shrink(void) +{ + auto t1 = std::thread(alloc0); + t1.join(); + mi_free(shared_p); +} + + +// Issue #221 +static void heap_thread_free_large_worker() { + mi_free(shared_p); +} + +static void heap_thread_free_large() { + for (int i = 0; i < 100; i++) { + shared_p = mi_malloc_aligned(2 * 1024 * 1024 + 1, 8); + auto t1 = std::thread(heap_thread_free_large_worker); + t1.join(); + } +} + +static void heap_thread_free_huge_worker() { + mi_free(shared_p); +} + +static void heap_thread_free_huge() { + for (int i = 0; i < 100; i++) { + shared_p = mi_malloc(1024 * 1024 * 1024); + auto t1 = std::thread(heap_thread_free_huge_worker); + t1.join(); + } +} + +static void test_mt_shutdown() +{ + const int threads = 5; + std::vector< std::future< std::vector< char* > > > ts; + + auto fn = [&]() + { + std::vector< char* > ps; + ps.reserve(1000); + for (int i = 0; i < 1000; i++) + ps.emplace_back(new char[1]); + return ps; + }; + + for (int i = 0; i < threads; i++) + ts.emplace_back(std::async(std::launch::async, fn)); + + for (auto& f : ts) + for (auto& p : f.get()) + delete[] p; + + std::cout << "done" << std::endl; +} + +// issue #363 +using namespace std; + +void large_alloc(void) +{ + char* a = new char[1ull << 25]; + thread th([&] { + delete[] a; + }); + th.join(); +} + +// issue #372 +static void fail_aslr() { + size_t sz = (4ULL << 40); // 4TiB + void* p = malloc(sz); + printf("pointer p: %p: area up to %p\n", p, (uint8_t*)p + sz); + *(int*)0x5FFFFFFF000 = 0; // should segfault +} + +// issues #414 +static void dummy_worker() { + void* p = mi_malloc(0); + mi_free(p); +} + +static void tsan_numa_test() { + auto t1 = std::thread(dummy_worker); + dummy_worker(); + t1.join(); +} + +// issue #? +#include <chrono> +#include <random> +#include <iostream> + +static void bench_alloc_large(void) { + static constexpr int kNumBuffers = 20; + static constexpr size_t kMinBufferSize = 5 * 1024 * 1024; + static constexpr size_t kMaxBufferSize = 25 * 1024 * 1024; + std::unique_ptr<char[]> buffers[kNumBuffers]; + + std::random_device rd; + std::mt19937 gen(42); //rd()); + std::uniform_int_distribution<> size_distribution(kMinBufferSize, kMaxBufferSize); + std::uniform_int_distribution<> buf_number_distribution(0, kNumBuffers - 1); + + static constexpr int kNumIterations = 2000; + const auto start = std::chrono::steady_clock::now(); + for (int i = 0; i < kNumIterations; ++i) { + int buffer_idx = buf_number_distribution(gen); + size_t new_size = size_distribution(gen); + buffers[buffer_idx] = std::make_unique<char[]>(new_size); + } + const auto end = std::chrono::steady_clock::now(); + const auto num_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); + const auto us_per_allocation = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / kNumIterations; + std::cout << kNumIterations << " allocations Done in " << num_ms << "ms." << std::endl; + std::cout << "Avg " << us_per_allocation << " us per allocation" << std::endl; +} + diff --git a/lib/Utils.Memory/mimalloc/test/main.c b/lib/Utils.Memory/mimalloc/test/main.c new file mode 100644 index 0000000..b148f71 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/main.c @@ -0,0 +1,46 @@ +#include <stdio.h> +#include <assert.h> +#include <mimalloc.h> + +void test_heap(void* p_out) { + mi_heap_t* heap = mi_heap_new(); + void* p1 = mi_heap_malloc(heap,32); + void* p2 = mi_heap_malloc(heap,48); + mi_free(p_out); + mi_heap_destroy(heap); + //mi_heap_delete(heap); mi_free(p1); mi_free(p2); +} + +void test_large() { + const size_t N = 1000; + + for (size_t i = 0; i < N; ++i) { + size_t sz = 1ull << 21; + char* a = mi_mallocn_tp(char,sz); + for (size_t k = 0; k < sz; k++) { a[k] = 'x'; } + mi_free(a); + } +} + +int main() { + void* p1 = mi_malloc(16); + void* p2 = mi_malloc(1000000); + mi_free(p1); + mi_free(p2); + p1 = mi_malloc(16); + p2 = mi_malloc(16); + mi_free(p1); + mi_free(p2); + + test_heap(mi_malloc(32)); + + p1 = mi_malloc_aligned(64, 16); + p2 = mi_malloc_aligned(160,24); + mi_free(p2); + mi_free(p1); + //test_large(); + + mi_collect(true); + mi_stats_print(NULL); + return 0; +} diff --git a/lib/Utils.Memory/mimalloc/test/readme.md b/lib/Utils.Memory/mimalloc/test/readme.md new file mode 100644 index 0000000..db3524c --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/readme.md @@ -0,0 +1,16 @@ +Testing allocators is difficult as bugs may only surface after particular +allocation patterns. The main approach to testing _mimalloc_ is therefore +to have extensive internal invariant checking (see `page_is_valid` in `page.c` +for example), which is enabled in debug mode with `-DMI_DEBUG_FULL=ON`. +The main testing strategy is then to run [`mimalloc-bench`][bench] using full +invariant checking to catch any potential problems over a wide range of intensive +allocation benchmarks and programs. + +However, this does not test well for the entire API surface and this is tested +with `test-api.c` when using `make test` (from `out/debug` etc). (This is +not complete yet, please add to it.) + +The `main.c` and `main-override.c` are there to test if building and overriding +from a local install works and therefore these build a separate `test/CMakeLists.txt`. + +[bench]: https://github.com/daanx/mimalloc-bench diff --git a/lib/Utils.Memory/mimalloc/test/test-api-fill.c b/lib/Utils.Memory/mimalloc/test/test-api-fill.c new file mode 100644 index 0000000..3fca3b9 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/test-api-fill.c @@ -0,0 +1,343 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/types.h" + +#include "testhelper.h" + +// --------------------------------------------------------------------------- +// Helper functions +// --------------------------------------------------------------------------- +bool check_zero_init(uint8_t* p, size_t size); +#if MI_DEBUG >= 2 +bool check_debug_fill_uninit(uint8_t* p, size_t size); +bool check_debug_fill_freed(uint8_t* p, size_t size); +#endif + +// --------------------------------------------------------------------------- +// Main testing +// --------------------------------------------------------------------------- +int main(void) { + mi_option_disable(mi_option_verbose); + + // --------------------------------------------------- + // Zeroing allocation + // --------------------------------------------------- + CHECK_BODY("zeroinit-zalloc-small") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size); + result = check_zero_init(p, zalloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-zalloc-large") { + size_t zalloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size); + result = check_zero_init(p, zalloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-zalloc_small") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc_small(zalloc_size); + result = check_zero_init(p, zalloc_size); + mi_free(p); + }; + + CHECK_BODY("zeroinit-calloc-small") { + size_t calloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1); + result = check_zero_init(p, calloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-calloc-large") { + size_t calloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1); + result = check_zero_init(p, calloc_size); + mi_free(p); + }; + + CHECK_BODY("zeroinit-rezalloc-small") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size); + result = check_zero_init(p, zalloc_size); + zalloc_size *= 3; + p = (uint8_t*)mi_rezalloc(p, zalloc_size); + result &= check_zero_init(p, zalloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-rezalloc-large") { + size_t zalloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size); + result = check_zero_init(p, zalloc_size); + zalloc_size *= 3; + p = (uint8_t*)mi_rezalloc(p, zalloc_size); + result &= check_zero_init(p, zalloc_size); + mi_free(p); + }; + + CHECK_BODY("zeroinit-recalloc-small") { + size_t calloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1); + result = check_zero_init(p, calloc_size); + calloc_size *= 3; + p = (uint8_t*)mi_recalloc(p, calloc_size, 1); + result &= check_zero_init(p, calloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-recalloc-large") { + size_t calloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1); + result = check_zero_init(p, calloc_size); + calloc_size *= 3; + p = (uint8_t*)mi_recalloc(p, calloc_size, 1); + result &= check_zero_init(p, calloc_size); + mi_free(p); + }; + + // --------------------------------------------------- + // Zeroing in aligned API + // --------------------------------------------------- + CHECK_BODY("zeroinit-zalloc_aligned-small") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, zalloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-zalloc_aligned-large") { + size_t zalloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, zalloc_size); + mi_free(p); + }; + + CHECK_BODY("zeroinit-calloc_aligned-small") { + size_t calloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, calloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-calloc_aligned-large") { + size_t calloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, calloc_size); + mi_free(p); + }; + + CHECK_BODY("zeroinit-rezalloc_aligned-small") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, zalloc_size); + zalloc_size *= 3; + p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result &= check_zero_init(p, zalloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-rezalloc_aligned-large") { + size_t zalloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, zalloc_size); + zalloc_size *= 3; + p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result &= check_zero_init(p, zalloc_size); + mi_free(p); + }; + + CHECK_BODY("zeroinit-recalloc_aligned-small") { + size_t calloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, calloc_size); + calloc_size *= 3; + p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2); + result &= check_zero_init(p, calloc_size); + mi_free(p); + }; + CHECK_BODY("zeroinit-recalloc_aligned-large") { + size_t calloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2); + result = check_zero_init(p, calloc_size); + calloc_size *= 3; + p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2); + result &= check_zero_init(p, calloc_size); + mi_free(p); + }; + +#if (MI_DEBUG >= 2) && !MI_TSAN + // --------------------------------------------------- + // Debug filling + // --------------------------------------------------- + CHECK_BODY("uninit-malloc-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_malloc(malloc_size); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + CHECK_BODY("uninit-malloc-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_malloc(malloc_size); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + CHECK_BODY("uninit-malloc_small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_malloc_small(malloc_size); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + CHECK_BODY("uninit-realloc-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_malloc(malloc_size); + result = check_debug_fill_uninit(p, malloc_size); + malloc_size *= 3; + p = (uint8_t*)mi_realloc(p, malloc_size); + result &= check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + CHECK_BODY("uninit-realloc-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_malloc(malloc_size); + result = check_debug_fill_uninit(p, malloc_size); + malloc_size *= 3; + p = (uint8_t*)mi_realloc(p, malloc_size); + result &= check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + CHECK_BODY("uninit-mallocn-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + CHECK_BODY("uninit-mallocn-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + CHECK_BODY("uninit-reallocn-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1); + result = check_debug_fill_uninit(p, malloc_size); + malloc_size *= 3; + p = (uint8_t*)mi_reallocn(p, malloc_size, 1); + result &= check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + CHECK_BODY("uninit-reallocn-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1); + result = check_debug_fill_uninit(p, malloc_size); + malloc_size *= 3; + p = (uint8_t*)mi_reallocn(p, malloc_size, 1); + result &= check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + CHECK_BODY("uninit-malloc_aligned-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + CHECK_BODY("uninit-malloc_aligned-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + CHECK_BODY("uninit-realloc_aligned-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_debug_fill_uninit(p, malloc_size); + malloc_size *= 3; + p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2); + result &= check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + CHECK_BODY("uninit-realloc_aligned-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2); + result = check_debug_fill_uninit(p, malloc_size); + malloc_size *= 3; + p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2); + result &= check_debug_fill_uninit(p, malloc_size); + mi_free(p); + }; + + #if !(MI_TRACK_VALGRIND || MI_TRACK_ASAN) + CHECK_BODY("fill-freed-small") { + size_t malloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_malloc(malloc_size); + mi_free(p); + // First sizeof(void*) bytes will contain housekeeping data, skip these + result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*)); + }; + CHECK_BODY("fill-freed-large") { + size_t malloc_size = MI_SMALL_SIZE_MAX * 2; + uint8_t* p = (uint8_t*)mi_malloc(malloc_size); + mi_free(p); + // First sizeof(void*) bytes will contain housekeeping data, skip these + result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*)); + }; + #endif +#endif + + // --------------------------------------------------- + // Done + // ---------------------------------------------------[] + return print_test_summary(); +} + +// --------------------------------------------------------------------------- +// Helper functions +// --------------------------------------------------------------------------- +bool check_zero_init(uint8_t* p, size_t size) { + if(!p) + return false; + bool result = true; + for (size_t i = 0; i < size; ++i) { + result &= p[i] == 0; + } + return result; +} + +#if MI_DEBUG >= 2 +bool check_debug_fill_uninit(uint8_t* p, size_t size) { +#if MI_TRACK_VALGRIND || MI_TRACK_ASAN + (void)p; (void)size; + return true; // when compiled with valgrind we don't init on purpose +#else + if(!p) + return false; + + bool result = true; + for (size_t i = 0; i < size; ++i) { + result &= p[i] == MI_DEBUG_UNINIT; + } + return result; +#endif +} + +bool check_debug_fill_freed(uint8_t* p, size_t size) { +#if MI_TRACK_VALGRIND + (void)p; (void)size; + return true; // when compiled with valgrind we don't fill on purpose +#else + if(!p) + return false; + + bool result = true; + for (size_t i = 0; i < size; ++i) { + result &= p[i] == MI_DEBUG_FREED; + } + return result; +#endif +} +#endif diff --git a/lib/Utils.Memory/mimalloc/test/test-api.c b/lib/Utils.Memory/mimalloc/test/test-api.c new file mode 100644 index 0000000..8dd24e1 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/test-api.c @@ -0,0 +1,359 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic ignored "-Walloc-size-larger-than=" +#endif + +/* +Testing allocators is difficult as bugs may only surface after particular +allocation patterns. The main approach to testing _mimalloc_ is therefore +to have extensive internal invariant checking (see `page_is_valid` in `page.c` +for example), which is enabled in debug mode with `-DMI_DEBUG_FULL=ON`. +The main testing is then to run `mimalloc-bench` [1] using full invariant checking +to catch any potential problems over a wide range of intensive allocation bench +marks. + +However, this does not test well for the entire API surface. In this test file +we therefore test the API over various inputs. Please add more tests :-) + +[1] https://github.com/daanx/mimalloc-bench +*/ + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <errno.h> + +#ifdef __cplusplus +#include <vector> +#endif + +#include "mimalloc.h" +// #include "mimalloc/internal.h" +#include "mimalloc/types.h" // for MI_DEBUG and MI_ALIGNMENT_MAX + +#include "testhelper.h" + +// --------------------------------------------------------------------------- +// Test functions +// --------------------------------------------------------------------------- +bool test_heap1(void); +bool test_heap2(void); +bool test_stl_allocator1(void); +bool test_stl_allocator2(void); + +bool mem_is_zero(uint8_t* p, size_t size) { + if (p==NULL) return false; + for (size_t i = 0; i < size; ++i) { + if (p[i] != 0) return false; + } + return true; +} + +// --------------------------------------------------------------------------- +// Main testing +// --------------------------------------------------------------------------- +int main(void) { + mi_option_disable(mi_option_verbose); + + // --------------------------------------------------- + // Malloc + // --------------------------------------------------- + + CHECK_BODY("malloc-zero") { + void* p = mi_malloc(0); + result = (p != NULL); + mi_free(p); + }; + CHECK_BODY("malloc-nomem1") { + result = (mi_malloc((size_t)PTRDIFF_MAX + (size_t)1) == NULL); + }; + CHECK_BODY("malloc-null") { + mi_free(NULL); + }; + CHECK_BODY("calloc-overflow") { + // use (size_t)&mi_calloc to get some number without triggering compiler warnings + result = (mi_calloc((size_t)&mi_calloc,SIZE_MAX/1000) == NULL); + }; + CHECK_BODY("calloc0") { + void* p = mi_calloc(0,1000); + result = (mi_usable_size(p) <= 16); + mi_free(p); + }; + CHECK_BODY("malloc-large") { // see PR #544. + void* p = mi_malloc(67108872); + mi_free(p); + }; + + // --------------------------------------------------- + // Extended + // --------------------------------------------------- + CHECK_BODY("posix_memalign1") { + void* p = &p; + int err = mi_posix_memalign(&p, sizeof(void*), 32); + result = ((err==0 && (uintptr_t)p % sizeof(void*) == 0) || p==&p); + mi_free(p); + }; + CHECK_BODY("posix_memalign_no_align") { + void* p = &p; + int err = mi_posix_memalign(&p, 3, 32); + result = (err==EINVAL && p==&p); + }; + CHECK_BODY("posix_memalign_zero") { + void* p = &p; + int err = mi_posix_memalign(&p, sizeof(void*), 0); + mi_free(p); + result = (err==0); + }; + CHECK_BODY("posix_memalign_nopow2") { + void* p = &p; + int err = mi_posix_memalign(&p, 3*sizeof(void*), 32); + result = (err==EINVAL && p==&p); + }; + CHECK_BODY("posix_memalign_nomem") { + void* p = &p; + int err = mi_posix_memalign(&p, sizeof(void*), SIZE_MAX); + result = (err==ENOMEM && p==&p); + }; + + // --------------------------------------------------- + // Aligned API + // --------------------------------------------------- + CHECK_BODY("malloc-aligned1") { + void* p = mi_malloc_aligned(32,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p); + }; + CHECK_BODY("malloc-aligned2") { + void* p = mi_malloc_aligned(48,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p); + }; + CHECK_BODY("malloc-aligned3") { + void* p1 = mi_malloc_aligned(48,32); bool result1 = (p1 != NULL && (uintptr_t)(p1) % 32 == 0); + void* p2 = mi_malloc_aligned(48,32); bool result2 = (p2 != NULL && (uintptr_t)(p2) % 32 == 0); + mi_free(p2); + mi_free(p1); + result = (result1&&result2); + }; + CHECK_BODY("malloc-aligned4") { + void* p; + bool ok = true; + for (int i = 0; i < 8 && ok; i++) { + p = mi_malloc_aligned(8, 16); + ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); + } + result = ok; + }; + CHECK_BODY("malloc-aligned5") { + void* p = mi_malloc_aligned(4097,4096); + size_t usable = mi_usable_size(p); + result = (usable >= 4097 && usable < 16000); + printf("malloc_aligned5: usable size: %zi\n", usable); + mi_free(p); + }; + CHECK_BODY("malloc-aligned6") { + bool ok = true; + for (size_t align = 1; align <= MI_ALIGNMENT_MAX && ok; align *= 2) { + void* ps[8]; + for (int i = 0; i < 8 && ok; i++) { + ps[i] = mi_malloc_aligned(align*13 // size + , align); + if (ps[i] == NULL || (uintptr_t)(ps[i]) % align != 0) { + ok = false; + } + } + for (int i = 0; i < 8 && ok; i++) { + mi_free(ps[i]); + } + } + result = ok; + }; + CHECK_BODY("malloc-aligned7") { + void* p = mi_malloc_aligned(1024,MI_ALIGNMENT_MAX); + mi_free(p); + result = ((uintptr_t)p % MI_ALIGNMENT_MAX) == 0; + }; + CHECK_BODY("malloc-aligned8") { + bool ok = true; + for (int i = 0; i < 5 && ok; i++) { + int n = (1 << i); + void* p = mi_malloc_aligned(1024, n * MI_ALIGNMENT_MAX); + ok = ((uintptr_t)p % (n*MI_ALIGNMENT_MAX)) == 0; + mi_free(p); + } + result = ok; + }; + CHECK_BODY("malloc-aligned9") { + bool ok = true; + void* p[8]; + size_t sizes[8] = { 8, 512, 1024 * 1024, MI_ALIGNMENT_MAX, MI_ALIGNMENT_MAX + 1, 2 * MI_ALIGNMENT_MAX, 8 * MI_ALIGNMENT_MAX, 0 }; + for (int i = 0; i < 28 && ok; i++) { + int align = (1 << i); + for (int j = 0; j < 8 && ok; j++) { + p[j] = mi_zalloc_aligned(sizes[j], align); + ok = ((uintptr_t)p[j] % align) == 0; + } + for (int j = 0; j < 8; j++) { + mi_free(p[j]); + } + } + result = ok; + }; + CHECK_BODY("malloc-aligned10") { + bool ok = true; + void* p[10+1]; + int align; + int j; + for(j = 0, align = 1; j <= 10 && ok; align *= 2, j++ ) { + p[j] = mi_malloc_aligned(43 + align, align); + ok = ((uintptr_t)p[j] % align) == 0; + } + for ( ; j > 0; j--) { + mi_free(p[j-1]); + } + result = ok; + } + CHECK_BODY("malloc_aligned11") { + mi_heap_t* heap = mi_heap_new(); + void* p = mi_heap_malloc_aligned(heap, 33554426, 8); + result = mi_heap_contains_block(heap, p); + mi_heap_destroy(heap); + } + CHECK_BODY("mimalloc-aligned12") { + void* p = mi_malloc_aligned(0x100, 0x100); + result = (((uintptr_t)p % 0x100) == 0); // #602 + mi_free(p); + } + CHECK_BODY("malloc-aligned-at1") { + void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p); + }; + CHECK_BODY("malloc-aligned-at2") { + void* p = mi_malloc_aligned_at(50,32,8); result = (p != NULL && ((uintptr_t)(p) + 8) % 32 == 0); mi_free(p); + }; + CHECK_BODY("memalign1") { + void* p; + bool ok = true; + for (int i = 0; i < 8 && ok; i++) { + p = mi_memalign(16,8); + ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); + } + result = ok; + }; + CHECK_BODY("zalloc-aligned-small1") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = mem_is_zero(p, zalloc_size); + mi_free(p); + }; + CHECK_BODY("rezalloc_aligned-small1") { + size_t zalloc_size = MI_SMALL_SIZE_MAX / 2; + uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = mem_is_zero(p, zalloc_size); + zalloc_size *= 3; + p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2); + result = result && mem_is_zero(p, zalloc_size); + mi_free(p); + }; + + // --------------------------------------------------- + // Reallocation + // --------------------------------------------------- + CHECK_BODY("realloc-null") { + void* p = mi_realloc(NULL,4); + result = (p != NULL); + mi_free(p); + }; + + CHECK_BODY("realloc-null-sizezero") { + void* p = mi_realloc(NULL,0); // <https://en.cppreference.com/w/c/memory/realloc> "If ptr is NULL, the behavior is the same as calling malloc(new_size)." + result = (p != NULL); + mi_free(p); + }; + + CHECK_BODY("realloc-sizezero") { + void* p = mi_malloc(4); + void* q = mi_realloc(p, 0); + result = (q != NULL); + mi_free(q); + }; + + CHECK_BODY("reallocarray-null-sizezero") { + void* p = mi_reallocarray(NULL,0,16); // issue #574 + result = (p != NULL && errno == 0); + mi_free(p); + }; + + // --------------------------------------------------- + // Heaps + // --------------------------------------------------- + CHECK("heap_destroy", test_heap1()); + CHECK("heap_delete", test_heap2()); + + //mi_stats_print(NULL); + + // --------------------------------------------------- + // various + // --------------------------------------------------- + CHECK_BODY("realpath") { + char* s = mi_realpath( ".", NULL ); + // printf("realpath: %s\n",s); + mi_free(s); + }; + + CHECK("stl_allocator1", test_stl_allocator1()); + CHECK("stl_allocator2", test_stl_allocator2()); + + // --------------------------------------------------- + // Done + // ---------------------------------------------------[] + return print_test_summary(); +} + +// --------------------------------------------------- +// Larger test functions +// --------------------------------------------------- + +bool test_heap1(void) { + mi_heap_t* heap = mi_heap_new(); + int* p1 = mi_heap_malloc_tp(heap,int); + int* p2 = mi_heap_malloc_tp(heap,int); + *p1 = *p2 = 43; + mi_heap_destroy(heap); + return true; +} + +bool test_heap2(void) { + mi_heap_t* heap = mi_heap_new(); + int* p1 = mi_heap_malloc_tp(heap,int); + int* p2 = mi_heap_malloc_tp(heap,int); + mi_heap_delete(heap); + *p1 = 42; + mi_free(p1); + mi_free(p2); + return true; +} + +bool test_stl_allocator1(void) { +#ifdef __cplusplus + std::vector<int, mi_stl_allocator<int> > vec; + vec.push_back(1); + vec.pop_back(); + return vec.size() == 0; +#else + return true; +#endif +} + +struct some_struct { int i; int j; double z; }; + +bool test_stl_allocator2(void) { +#ifdef __cplusplus + std::vector<some_struct, mi_stl_allocator<some_struct> > vec; + vec.push_back(some_struct()); + vec.pop_back(); + return vec.size() == 0; +#else + return true; +#endif +} diff --git a/lib/Utils.Memory/mimalloc/test/test-stress.c b/lib/Utils.Memory/mimalloc/test/test-stress.c new file mode 100644 index 0000000..7b74b46 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/test-stress.c @@ -0,0 +1,359 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. +-----------------------------------------------------------------------------*/ + +/* This is a stress test for the allocator, using multiple threads and + transferring objects between threads. It tries to reflect real-world workloads: + - allocation size is distributed linearly in powers of two + - with some fraction extra large (and some very large) + - the allocations are initialized and read again at free + - pointers transfer between threads + - threads are terminated and recreated with some objects surviving in between + - uses deterministic "randomness", but execution can still depend on + (random) thread scheduling. Do not use this test as a benchmark! +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <assert.h> + +// > mimalloc-test-stress [THREADS] [SCALE] [ITER] +// +// argument defaults +static int THREADS = 32; // more repeatable if THREADS <= #processors +static int SCALE = 25; // scaling factor + +#if defined(MI_TSAN) +static int ITER = 10; // N full iterations destructing and re-creating all threads (on tsan reduce for azure pipeline limits) +#else +static int ITER = 50; // N full iterations destructing and re-creating all threads +#endif + +// static int THREADS = 8; // more repeatable if THREADS <= #processors +// static int SCALE = 100; // scaling factor + +#define STRESS // undefine for leak test + +static bool allow_large_objects = true; // allow very large objects? (set to `true` if SCALE>100) +static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`? + + +// #define USE_STD_MALLOC +#ifdef USE_STD_MALLOC +#define custom_calloc(n,s) calloc(n,s) +#define custom_realloc(p,s) realloc(p,s) +#define custom_free(p) free(p) +#else +#include <mimalloc.h> +#define custom_calloc(n,s) mi_calloc(n,s) +#define custom_realloc(p,s) mi_realloc(p,s) +#define custom_free(p) mi_free(p) +#endif + +// transfer pointer between threads +#define TRANSFERS (1000) +static volatile void* transfer[TRANSFERS]; + + +#if (UINTPTR_MAX != UINT32_MAX) +const uintptr_t cookie = 0xbf58476d1ce4e5b9UL; +#else +const uintptr_t cookie = 0x1ce4e5b9UL; +#endif + +static void* atomic_exchange_ptr(volatile void** p, void* newval); + +typedef uintptr_t* random_t; + +static uintptr_t pick(random_t r) { + uintptr_t x = *r; +#if (UINTPTR_MAX > UINT32_MAX) + // by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c> + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9UL; + x ^= x >> 27; + x *= 0x94d049bb133111ebUL; + x ^= x >> 31; +#else + // by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/> + x ^= x >> 16; + x *= 0x7feb352dUL; + x ^= x >> 15; + x *= 0x846ca68bUL; + x ^= x >> 16; +#endif + *r = x; + return x; +} + +static bool chance(size_t perc, random_t r) { + return (pick(r) % 100 <= perc); +} + +static void* alloc_items(size_t items, random_t r) { + if (chance(1, r)) { + if (chance(1, r) && allow_large_objects) items *= 10000; // 0.01% giant + else if (chance(10, r) && allow_large_objects) items *= 1000; // 0.1% huge + else items *= 100; // 1% large objects; + } + if (items == 40) items++; // pthreads uses that size for stack increases + if (use_one_size > 0) items = (use_one_size / sizeof(uintptr_t)); + if (items==0) items = 1; + uintptr_t* p = (uintptr_t*)custom_calloc(items,sizeof(uintptr_t)); + if (p != NULL) { + for (uintptr_t i = 0; i < items; i++) { + assert(p[i] == 0); + p[i] = (items - i) ^ cookie; + } + } + return p; +} + +static void free_items(void* p) { + if (p != NULL) { + uintptr_t* q = (uintptr_t*)p; + uintptr_t items = (q[0] ^ cookie); + for (uintptr_t i = 0; i < items; i++) { + if ((q[i] ^ cookie) != items - i) { + fprintf(stderr, "memory corruption at block %p at %zu\n", p, i); + abort(); + } + } + } + custom_free(p); +} + + +static void stress(intptr_t tid) { + //bench_start_thread(); + uintptr_t r = ((tid + 1) * 43); // rand(); + const size_t max_item_shift = 5; // 128 + const size_t max_item_retained_shift = max_item_shift + 2; + size_t allocs = 100 * ((size_t)SCALE) * (tid % 8 + 1); // some threads do more + size_t retain = allocs / 2; + void** data = NULL; + size_t data_size = 0; + size_t data_top = 0; + void** retained = (void**)custom_calloc(retain,sizeof(void*)); + size_t retain_top = 0; + + while (allocs > 0 || retain > 0) { + if (retain == 0 || (chance(50, &r) && allocs > 0)) { + // 50%+ alloc + allocs--; + if (data_top >= data_size) { + data_size += 100000; + data = (void**)custom_realloc(data, data_size * sizeof(void*)); + } + data[data_top++] = alloc_items(1ULL << (pick(&r) % max_item_shift), &r); + } + else { + // 25% retain + retained[retain_top++] = alloc_items( 1ULL << (pick(&r) % max_item_retained_shift), &r); + retain--; + } + if (chance(66, &r) && data_top > 0) { + // 66% free previous alloc + size_t idx = pick(&r) % data_top; + free_items(data[idx]); + data[idx] = NULL; + } + if (chance(25, &r) && data_top > 0) { + // 25% exchange a local pointer with the (shared) transfer buffer. + size_t data_idx = pick(&r) % data_top; + size_t transfer_idx = pick(&r) % TRANSFERS; + void* p = data[data_idx]; + void* q = atomic_exchange_ptr(&transfer[transfer_idx], p); + data[data_idx] = q; + } + } + // free everything that is left + for (size_t i = 0; i < retain_top; i++) { + free_items(retained[i]); + } + for (size_t i = 0; i < data_top; i++) { + free_items(data[i]); + } + custom_free(retained); + custom_free(data); + //bench_end_thread(); +} + +static void run_os_threads(size_t nthreads, void (*entry)(intptr_t tid)); + +static void test_stress(void) { + uintptr_t r = rand(); + for (int n = 0; n < ITER; n++) { + run_os_threads(THREADS, &stress); + for (int i = 0; i < TRANSFERS; i++) { + if (chance(50, &r) || n + 1 == ITER) { // free all on last run, otherwise free half of the transfers + void* p = atomic_exchange_ptr(&transfer[i], NULL); + free_items(p); + } + } + #ifndef NDEBUG + //mi_collect(false); + //mi_debug_show_arenas(); + #endif + #if !defined(NDEBUG) || defined(MI_TSAN) + if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); } + #endif + } +} + +#ifndef STRESS +static void leak(intptr_t tid) { + uintptr_t r = rand(); + void* p = alloc_items(1 /*pick(&r)%128*/, &r); + if (chance(50, &r)) { + intptr_t i = (pick(&r) % TRANSFERS); + void* q = atomic_exchange_ptr(&transfer[i], p); + free_items(q); + } +} + +static void test_leak(void) { + for (int n = 0; n < ITER; n++) { + run_os_threads(THREADS, &leak); + mi_collect(false); +#ifndef NDEBUG + if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); } +#endif + } +} +#endif + +int main(int argc, char** argv) { + #ifndef USE_STD_MALLOC + mi_stats_reset(); + #endif + + // > mimalloc-test-stress [THREADS] [SCALE] [ITER] + if (argc >= 2) { + char* end; + long n = strtol(argv[1], &end, 10); + if (n > 0) THREADS = n; + } + if (argc >= 3) { + char* end; + long n = (strtol(argv[2], &end, 10)); + if (n > 0) SCALE = n; + } + if (argc >= 4) { + char* end; + long n = (strtol(argv[3], &end, 10)); + if (n > 0) ITER = n; + } + if (SCALE > 100) { + allow_large_objects = true; + } + printf("Using %d threads with a %d%% load-per-thread and %d iterations %s\n", THREADS, SCALE, ITER, (allow_large_objects ? "(allow large objects)" : "")); + //mi_reserve_os_memory(1024*1024*1024ULL, false, true); + //int res = mi_reserve_huge_os_pages(4,1); + //printf("(reserve huge: %i\n)", res); + + //bench_start_program(); + + // Run ITER full iterations where half the objects in the transfer buffer survive to the next round. + srand(0x7feb352d); + + //mi_reserve_os_memory(512ULL << 20, true, true); + +#if !defined(NDEBUG) && !defined(USE_STD_MALLOC) + mi_stats_reset(); +#endif + +#ifdef STRESS + test_stress(); +#else + test_leak(); +#endif + +#ifndef USE_STD_MALLOC + #ifndef NDEBUG + mi_collect(true); + //mi_debug_show_arenas(); + #endif + mi_stats_print(NULL); +#endif + //bench_end_program(); + return 0; +} + + +static void (*thread_entry_fun)(intptr_t) = &stress; + +#ifdef _WIN32 + +#include <Windows.h> + +static DWORD WINAPI thread_entry(LPVOID param) { + thread_entry_fun((intptr_t)param); + return 0; +} + +static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) { + thread_entry_fun = fun; + DWORD* tids = (DWORD*)custom_calloc(nthreads,sizeof(DWORD)); + HANDLE* thandles = (HANDLE*)custom_calloc(nthreads,sizeof(HANDLE)); + for (uintptr_t i = 0; i < nthreads; i++) { + thandles[i] = CreateThread(0, 8*1024, &thread_entry, (void*)(i), 0, &tids[i]); + } + for (size_t i = 0; i < nthreads; i++) { + WaitForSingleObject(thandles[i], INFINITE); + } + for (size_t i = 0; i < nthreads; i++) { + CloseHandle(thandles[i]); + } + custom_free(tids); + custom_free(thandles); +} + +static void* atomic_exchange_ptr(volatile void** p, void* newval) { +#if (INTPTR_MAX == INT32_MAX) + return (void*)InterlockedExchange((volatile LONG*)p, (LONG)newval); +#else + return (void*)InterlockedExchange64((volatile LONG64*)p, (LONG64)newval); +#endif +} +#else + +#include <pthread.h> + +static void* thread_entry(void* param) { + thread_entry_fun((uintptr_t)param); + return NULL; +} + +static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) { + thread_entry_fun = fun; + pthread_t* threads = (pthread_t*)custom_calloc(nthreads,sizeof(pthread_t)); + memset(threads, 0, sizeof(pthread_t) * nthreads); + //pthread_setconcurrency(nthreads); + for (size_t i = 0; i < nthreads; i++) { + pthread_create(&threads[i], NULL, &thread_entry, (void*)i); + } + for (size_t i = 0; i < nthreads; i++) { + pthread_join(threads[i], NULL); + } + custom_free(threads); +} + +#ifdef __cplusplus +#include <atomic> +static void* atomic_exchange_ptr(volatile void** p, void* newval) { + return std::atomic_exchange((volatile std::atomic<void*>*)p, newval); +} +#else +#include <stdatomic.h> +static void* atomic_exchange_ptr(volatile void** p, void* newval) { + return atomic_exchange((volatile _Atomic(void*)*)p, newval); +} +#endif + +#endif diff --git a/lib/Utils.Memory/mimalloc/test/test-wrong.c b/lib/Utils.Memory/mimalloc/test/test-wrong.c new file mode 100644 index 0000000..56a2339 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/test-wrong.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* test file for valgrind/asan support. + + VALGRIND: + ---------- + Compile in an "out/debug" folder: + + > cd out/debug + > cmake ../.. -DMI_TRACK_VALGRIND=1 + > make -j8 + + and then compile this file as: + + > gcc -g -o test-wrong -I../../include ../../test/test-wrong.c libmimalloc-valgrind-debug.a -lpthread + + and test as: + + > valgrind ./test-wrong + + + ASAN + ---------- + Compile in an "out/debug" folder: + + > cd out/debug + > cmake ../.. -DMI_TRACK_ASAN=1 + > make -j8 + + and then compile this file as: + + > clang -g -o test-wrong -I../../include ../../test/test-wrong.c libmimalloc-asan-debug.a -lpthread -fsanitize=address -fsanitize-recover=address + + and test as: + + > ASAN_OPTIONS=verbosity=1:halt_on_error=0 ./test-wrong + + +*/ +#include <stdio.h> +#include <stdlib.h> +#include "mimalloc.h" + +#ifdef USE_STD_MALLOC +# define mi(x) x +#else +# define mi(x) mi_##x +#endif + +int main(int argc, char** argv) { + int* p = (int*)mi(malloc)(3*sizeof(int)); + + int* r = (int*)mi_malloc_aligned(8,16); + mi_free(r); + + // illegal byte wise read + char* c = (char*)mi(malloc)(3); + printf("invalid byte: over: %d, under: %d\n", c[4], c[-1]); + mi(free)(c); + + // undefined access + int* q = (int*)mi(malloc)(sizeof(int)); + printf("undefined: %d\n", *q); + + // illegal int read + printf("invalid: over: %d, under: %d\n", q[1], q[-1]); + + *q = 42; + + // buffer overflow + q[1] = 43; + + // buffer underflow + q[-1] = 44; + + mi(free)(q); + + // double free + mi(free)(q); + + // use after free + printf("use-after-free: %d\n", *q); + + // leak p + // mi_free(p) + return 0; +}
\ No newline at end of file diff --git a/lib/Utils.Memory/mimalloc/test/testhelper.h b/lib/Utils.Memory/mimalloc/test/testhelper.h new file mode 100644 index 0000000..a972758 --- /dev/null +++ b/lib/Utils.Memory/mimalloc/test/testhelper.h @@ -0,0 +1,49 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef TESTHELPER_H_ +#define TESTHELPER_H_ + +#include <stdbool.h> +#include <stdio.h> +#include <errno.h> + +// --------------------------------------------------------------------------- +// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body) +// --------------------------------------------------------------------------- +static int ok = 0; +static int failed = 0; + +static bool check_result(bool result, const char* testname, const char* fname, long lineno) { + if (!(result)) { + failed++; + fprintf(stderr,"\n FAILED: %s: %s:%ld\n", testname, fname, lineno); + /* exit(1); */ + } + else { + ok++; + fprintf(stderr, "ok.\n"); + } + return true; +} + +#define CHECK_BODY(name) \ + fprintf(stderr,"test: %s... ", name ); \ + errno = 0; \ + for(bool done = false, result = true; !done; done = check_result(result,name,__FILE__,__LINE__)) + +#define CHECK(name,expr) CHECK_BODY(name){ result = (expr); } + +// Print summary of test. Return value can be directly use as a return value for main(). +static inline int print_test_summary(void) +{ + fprintf(stderr,"\n\n---------------------------------------------\n" + "succeeded: %i\n" + "failed : %i\n\n", ok, failed); + return failed; +} + +#endif // TESTHELPER_H_ |