aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-10-22 14:37:11 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-10-22 14:37:11 -0400
commitaef1b25aae6fc27c4557dc7e4c9d75cbe22a1f8f (patch)
tree4c7661218668933f0a27bfca04f79c89b3e81d21
parentd997950a29ec3ce29cd652298e678d708218fdad (diff)
partial mimalloc support, native source code packages, and default tasks
-rw-r--r--.gitignore3
-rw-r--r--lib/Net.Http/src/Core/ConnectionInfo.cs14
-rw-r--r--lib/Net.Http/src/IConnectionInfo.cs11
-rw-r--r--lib/Plugins.Essentials/src/Extensions/ConnectionInfoExtensions.cs19
-rw-r--r--lib/Plugins.Essentials/src/HttpEntity.cs11
-rw-r--r--lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs5
-rw-r--r--lib/Plugins.Essentials/src/Sessions/SessionInfo.cs7
-rw-r--r--lib/Utils.Memory/mimalloc/.gitattributes12
-rw-r--r--lib/Utils.Memory/mimalloc/.gitignore9
-rw-r--r--lib/Utils.Memory/mimalloc/CMakeLists.txt526
-rw-r--r--lib/Utils.Memory/mimalloc/LICENSE21
-rw-r--r--lib/Utils.Memory/mimalloc/SECURITY.md41
-rw-r--r--lib/Utils.Memory/mimalloc/azure-pipelines.yml197
-rw-r--r--lib/Utils.Memory/mimalloc/cmake/JoinPaths.cmake23
-rw-r--r--lib/Utils.Memory/mimalloc/cmake/mimalloc-config-version.cmake19
-rw-r--r--lib/Utils.Memory/mimalloc/cmake/mimalloc-config.cmake14
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg887
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg1185
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg757
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg1028
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-1.svg769
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg868
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg1157
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-2.svg983
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg683
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg854
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec-rss.svg713
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-spec.svg713
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-1.svg890
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-2.svg1146
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-1.svg796
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2020/bench-z4-rss-2.svg974
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg952
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg1255
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg955
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg1269
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg836
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg1131
-rw-r--r--lib/Utils.Memory/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg766
-rw-r--r--lib/Utils.Memory/mimalloc/doc/doxyfile2659
-rw-r--r--lib/Utils.Memory/mimalloc/doc/ds-logo.jpgbin0 -> 181497 bytes
-rw-r--r--lib/Utils.Memory/mimalloc/doc/ds-logo.pngbin0 -> 121150 bytes
-rw-r--r--lib/Utils.Memory/mimalloc/doc/mimalloc-doc.h1281
-rw-r--r--lib/Utils.Memory/mimalloc/doc/mimalloc-doxygen.css49
-rw-r--r--lib/Utils.Memory/mimalloc/doc/mimalloc-logo-100.pngbin0 -> 3532 bytes
-rw-r--r--lib/Utils.Memory/mimalloc/doc/mimalloc-logo.pngbin0 -> 73097 bytes
-rw-r--r--lib/Utils.Memory/mimalloc/doc/mimalloc-logo.svg161
-rw-r--r--lib/Utils.Memory/mimalloc/doc/spades-logo.pngbin0 -> 34583 bytes
-rw-r--r--lib/Utils.Memory/mimalloc/doc/unreal-logo.svg43
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj190
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-override.vcxproj259
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj159
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc-test.vcxproj158
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.sln71
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2017/mimalloc.vcxproj259
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj190
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-override.vcxproj259
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj155
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj159
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc-test.vcxproj158
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.sln81
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2019/mimalloc.vcxproj257
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj190
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-override.vcxproj270
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj162
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj159
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc-test.vcxproj158
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.sln81
-rw-r--r--lib/Utils.Memory/mimalloc/ide/vs2022/mimalloc.vcxproj257
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc-new-delete.h66
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc-override.h67
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc.h565
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc/atomic.h385
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc/internal.h979
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc/prim.h323
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc/track.h147
-rw-r--r--lib/Utils.Memory/mimalloc/include/mimalloc/types.h670
-rw-r--r--lib/Utils.Memory/mimalloc/mimalloc.pc.in11
-rw-r--r--lib/Utils.Memory/mimalloc/readme.md827
-rw-r--r--lib/Utils.Memory/mimalloc/src/alloc-aligned.c298
-rw-r--r--lib/Utils.Memory/mimalloc/src/alloc-override.c297
-rw-r--r--lib/Utils.Memory/mimalloc/src/alloc-posix.c185
-rw-r--r--lib/Utils.Memory/mimalloc/src/alloc.c1060
-rw-r--r--lib/Utils.Memory/mimalloc/src/arena.c936
-rw-r--r--lib/Utils.Memory/mimalloc/src/bitmap.c432
-rw-r--r--lib/Utils.Memory/mimalloc/src/bitmap.h115
-rw-r--r--lib/Utils.Memory/mimalloc/src/heap.c626
-rw-r--r--lib/Utils.Memory/mimalloc/src/init.c709
-rw-r--r--lib/Utils.Memory/mimalloc/src/options.c571
-rw-r--r--lib/Utils.Memory/mimalloc/src/os.c689
-rw-r--r--lib/Utils.Memory/mimalloc/src/page-queue.c332
-rw-r--r--lib/Utils.Memory/mimalloc/src/page.c939
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/osx/alloc-override-zone.c458
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/osx/prim.c9
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/prim.c24
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/readme.md9
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/unix/prim.c859
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/wasi/prim.c275
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/windows/etw-mimalloc.wprp61
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/windows/etw.h905
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/windows/etw.manbin0 -> 3926 bytes
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/windows/prim.c622
-rw-r--r--lib/Utils.Memory/mimalloc/src/prim/windows/readme.md17
-rw-r--r--lib/Utils.Memory/mimalloc/src/random.c254
-rw-r--r--lib/Utils.Memory/mimalloc/src/segment-map.c153
-rw-r--r--lib/Utils.Memory/mimalloc/src/segment.c1619
-rw-r--r--lib/Utils.Memory/mimalloc/src/static.c40
-rw-r--r--lib/Utils.Memory/mimalloc/src/stats.c467
-rw-r--r--lib/Utils.Memory/mimalloc/test/CMakeLists.txt54
-rw-r--r--lib/Utils.Memory/mimalloc/test/main-override-static.c415
-rw-r--r--lib/Utils.Memory/mimalloc/test/main-override.c36
-rw-r--r--lib/Utils.Memory/mimalloc/test/main-override.cpp400
-rw-r--r--lib/Utils.Memory/mimalloc/test/main.c46
-rw-r--r--lib/Utils.Memory/mimalloc/test/readme.md16
-rw-r--r--lib/Utils.Memory/mimalloc/test/test-api-fill.c343
-rw-r--r--lib/Utils.Memory/mimalloc/test/test-api.c359
-rw-r--r--lib/Utils.Memory/mimalloc/test/test-stress.c359
-rw-r--r--lib/Utils.Memory/mimalloc/test/test-wrong.c92
-rw-r--r--lib/Utils.Memory/mimalloc/test/testhelper.h49
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/CMakeLists.txt147
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/LICENSE293
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/Taskfile.yaml125
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/build.readme.txt0
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/package.json10
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.c110
-rw-r--r--lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.vcxitems28
-rw-r--r--lib/Utils.Memory/vnlib_rpmalloc/Taskfile.yaml61
-rw-r--r--lib/Utils.Memory/vnlib_rpmalloc/package.json4
128 files changed, 50223 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore
index 7221540..09999d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -363,5 +363,4 @@ MigrationBackup/
*.filters
-/lib/Net.Compression/vnlib_compress/build
-/lib/Utils.Memory/vnlib_rpmalloc/build
+**/build/*
diff --git a/lib/Net.Http/src/Core/ConnectionInfo.cs b/lib/Net.Http/src/Core/ConnectionInfo.cs
index fb22fe3..325d53d 100644
--- a/lib/Net.Http/src/Core/ConnectionInfo.cs
+++ b/lib/Net.Http/src/Core/ConnectionInfo.cs
@@ -26,7 +26,6 @@ using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
-using System.Security.Authentication;
using VNLib.Net.Http.Core;
@@ -65,19 +64,6 @@ namespace VNLib.Net.Http
public HttpVersion ProtocolVersion => Context.Request.HttpVersion;
///<inheritdoc/>
- public bool IsSecure => SecurityProtocol != SslProtocols.None;
-
- ///<inheritdoc/>
- public SslProtocols SecurityProtocol
- {
- get
- {
- ref readonly TransportSecurityInfo? securityInfo = ref Context.GetSecurityInfo();
- return securityInfo.HasValue ? securityInfo.Value.SslProtocol : SslProtocols.None;
- }
- }
-
- ///<inheritdoc/>
public Uri? Origin => Context.Request.Origin;
///<inheritdoc/>
diff --git a/lib/Net.Http/src/IConnectionInfo.cs b/lib/Net.Http/src/IConnectionInfo.cs
index 5664ac5..2549240 100644
--- a/lib/Net.Http/src/IConnectionInfo.cs
+++ b/lib/Net.Http/src/IConnectionInfo.cs
@@ -26,7 +26,6 @@ using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
-using System.Security.Authentication;
namespace VNLib.Net.Http
{
@@ -84,16 +83,6 @@ namespace VNLib.Net.Http
HttpVersion ProtocolVersion { get; }
/// <summary>
- /// Is the connection using transport security?
- /// </summary>
- bool IsSecure { get; }
-
- /// <summary>
- /// The negotiated transport protocol for the current connection
- /// </summary>
- SslProtocols SecurityProtocol { get; }
-
- /// <summary>
/// Origin header of current connection if specified, null otherwise
/// </summary>
Uri? Origin { get; }
diff --git a/lib/Plugins.Essentials/src/Extensions/ConnectionInfoExtensions.cs b/lib/Plugins.Essentials/src/Extensions/ConnectionInfoExtensions.cs
index 0039efa..5e0b04d 100644
--- a/lib/Plugins.Essentials/src/Extensions/ConnectionInfoExtensions.cs
+++ b/lib/Plugins.Essentials/src/Extensions/ConnectionInfoExtensions.cs
@@ -25,6 +25,7 @@
using System;
using System.Net;
using System.Linq;
+using System.Security.Authentication;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
@@ -419,21 +420,35 @@ namespace VNLib.Plugins.Essentials.Extensions
internal static bool IsSecure(this IConnectionInfo server, bool isTrusted)
{
+ bool isSecure = GetSslProtocol(server) != SslProtocols.None;
+
//If the connection is not trusted, then ignore header parsing
if (isTrusted)
{
//Standard https protocol header
string? protocol = server.Headers[X_FORWARDED_PROTO_HEADER];
//If the header is set and equals https then tls is being used
- return string.IsNullOrWhiteSpace(protocol) ? server.IsSecure : "https".Equals(protocol, StringComparison.OrdinalIgnoreCase);
+ return string.IsNullOrWhiteSpace(protocol) ? isSecure : "https".Equals(protocol, StringComparison.OrdinalIgnoreCase);
}
else
{
- return server.IsSecure;
+ return isSecure;
}
}
/// <summary>
+ /// Gets the ssl protocol used for the connection, or <see cref="SslProtocols.None"/>
+ /// if transport security is not being used
+ /// </summary>
+ /// <param name="server"></param>
+ /// <returns>The <see cref="SslProtocols"/> the current connection is using</returns>
+ public static SslProtocols GetSslProtocol(this IConnectionInfo server)
+ {
+ ref readonly TransportSecurityInfo? tsi = ref server.GetTransportSecurityInfo();
+ return tsi.HasValue ? tsi.Value.SslProtocol : SslProtocols.None;
+ }
+
+ /// <summary>
/// Was the connection made on a local network to the server? NOTE: Use with caution
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/lib/Plugins.Essentials/src/HttpEntity.cs b/lib/Plugins.Essentials/src/HttpEntity.cs
index 6487ca3..64f18ec 100644
--- a/lib/Plugins.Essentials/src/HttpEntity.cs
+++ b/lib/Plugins.Essentials/src/HttpEntity.cs
@@ -111,23 +111,28 @@ namespace VNLib.Plugins.Essentials
/// A token that has a scheduled timeout to signal the cancellation of the entity event
/// </summary>
public CancellationToken EventCancellation => EventCts.Token;
+
/// <summary>
/// The session associated with the event
/// </summary>
public ref readonly SessionInfo Session => ref _session;
+
/// <summary>
/// A value that indicates if the connecion came from a trusted downstream server
/// </summary>
public readonly bool IsBehindDownStreamServer;
+
/// <summary>
/// Determines if the connection came from the local network to the current server
/// </summary>
public readonly bool IsLocalConnection;
+
/// <summary>
/// Gets a value that determines if the connection is using tls, locally
/// or behind a trusted downstream server that is using tls.
/// </summary>
public readonly bool IsSecure;
+
/// <summary>
/// Caches a <see cref="DateTimeOffset"/> that was created when the connection was created.
/// The approximate current UTC time
@@ -138,26 +143,32 @@ namespace VNLib.Plugins.Essentials
/// The connection info object assocated with the entity
/// </summary>
public IConnectionInfo Server => Entity.Server;
+
/// <summary>
/// User's ip. If the connection is behind a local proxy, returns the users actual IP. Otherwise returns the connection ip.
/// </summary>
public readonly IPAddress TrustedRemoteIp;
+
/// <summary>
/// The requested web root. Provides additional site information
/// </summary>
public readonly IWebProcessor RequestedRoot;
+
/// <summary>
/// If the request has query arguments they are stored in key value format
/// </summary>
public IReadOnlyDictionary<string, string> QueryArgs => Entity.QueryArgs;
+
/// <summary>
/// If the request body has form data or url encoded arguments they are stored in key value format
/// </summary>
public IReadOnlyDictionary<string, string> RequestArgs => Entity.RequestArgs;
+
/// <summary>
/// Contains all files upladed with current request
/// </summary>
public IReadOnlyList<FileUpload> Files => Entity.Files;
+
///<inheritdoc/>
HttpServer IHttpEvent.OriginServer => Entity.OriginServer;
diff --git a/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs b/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs
index 018c9a2..d3fc475 100644
--- a/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs
+++ b/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs
@@ -29,8 +29,7 @@ using System.Runtime.CompilerServices;
using VNLib.Net.Http;
using VNLib.Utils;
using VNLib.Utils.Extensions;
-
-#nullable disable
+using VNLib.Plugins.Essentials.Extensions;
namespace VNLib.Plugins.Essentials.Sessions
{
@@ -81,7 +80,7 @@ namespace VNLib.Plugins.Essentials.Sessions
session.IsCrossOrigin(ci.CrossOrigin);
session.SetOrigin(ci.Origin?.ToString());
session.SetRefer(ci.Referer?.ToString());
- session.SetSecurityProtocol(ci.SecurityProtocol);
+ session.SetSecurityProtocol(ci.GetSslProtocol());
session.SetUserAgent(ci.UserAgent);
}
diff --git a/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs b/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs
index 527792f..7cb2783 100644
--- a/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs
+++ b/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs
@@ -30,6 +30,7 @@ using System.Runtime.CompilerServices;
using VNLib.Utils;
using VNLib.Net.Http;
+using VNLib.Plugins.Essentials.Extensions;
using static VNLib.Plugins.Essentials.Statics;
@@ -264,7 +265,7 @@ namespace VNLib.Plugins.Essentials.Sessions
//Since all values will be the same as the connection, cache the connection values
UserAgent = ci.UserAgent;
SpecifiedOrigin = ci.Origin;
- SecurityProcol = ci.SecurityProtocol;
+ SecurityProcol = ci.GetSslProtocol();
flags |= ci.CrossOrigin ? SessionFlags.IsCrossOrigin : SessionFlags.None;
}
@@ -287,12 +288,16 @@ namespace VNLib.Plugins.Essentials.Sessions
///<inheritdoc/>
public bool Equals(SessionInfo other) => SessionID.Equals(other.SessionID, StringComparison.Ordinal);
+
///<inheritdoc/>
public override bool Equals(object? obj) => obj is SessionInfo si && Equals(si);
+
///<inheritdoc/>
public override int GetHashCode() => SessionID.GetHashCode(StringComparison.Ordinal);
+
///<inheritdoc/>
public static bool operator ==(SessionInfo left, SessionInfo right) => left.Equals(right);
+
///<inheritdoc/>
public static bool operator !=(SessionInfo left, SessionInfo right) => !(left == right);
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
new file mode 100644
index 0000000..c9abb1a
--- /dev/null
+++ b/lib/Utils.Memory/mimalloc/doc/ds-logo.jpg
Binary files differ
diff --git a/lib/Utils.Memory/mimalloc/doc/ds-logo.png b/lib/Utils.Memory/mimalloc/doc/ds-logo.png
new file mode 100644
index 0000000..93b84e4
--- /dev/null
+++ b/lib/Utils.Memory/mimalloc/doc/ds-logo.png
Binary files differ
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
new file mode 100644
index 0000000..96f0825
--- /dev/null
+++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo-100.png
Binary files differ
diff --git a/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.png b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.png
new file mode 100644
index 0000000..e0a5a8c
--- /dev/null
+++ b/lib/Utils.Memory/mimalloc/doc/mimalloc-logo.png
Binary files differ
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
new file mode 100644
index 0000000..d8c73fe
--- /dev/null
+++ b/lib/Utils.Memory/mimalloc/doc/spades-logo.png
Binary files differ
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, &current, 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
+
+&nbsp;
+
+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&times; 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&times; 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&times; 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&times; 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&times;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, &microsoft_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, &microsoft_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(&microsoft_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
new file mode 100644
index 0000000..cfd1f8a
--- /dev/null
+++ b/lib/Utils.Memory/mimalloc/src/prim/windows/etw.man
Binary files differ
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, &param, 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, &current_rss, &peak_rss, &current_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, &current_rss, &peak_rss, &current_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_
diff --git a/lib/Utils.Memory/vnlib_mimalloc/CMakeLists.txt b/lib/Utils.Memory/vnlib_mimalloc/CMakeLists.txt
new file mode 100644
index 0000000..72b1e48
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/CMakeLists.txt
@@ -0,0 +1,147 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(vnlib_mimalloc C)
+
+#export header files to the main project
+file(GLOB HEADERS *.h)
+
+#Add indepednent source files to the project
+file(GLOB VNLIB_MIMALLOC_SOURCES *.c)
+
+#add heapapi includes
+include_directories(../NativeHeapApi/src)
+
+#set options for greedy allocator defaults
+option(ENABLE_GREEDY "Enable greedy allocator configuration" ON)
+
+#create my shared library
+add_library(${CMAKE_PROJECT_NAME} SHARED ${VNLIB_MIMALLOC_SOURCES} ${HEADERS})
+#also create static library
+add_library(${CMAKE_PROJECT_NAME}_static STATIC ${VNLIB_MIMALLOC_SOURCES} ${HEADERS})
+
+#if on unix lib will be appended, so we can adjust
+if(UNIX)
+ set_target_properties(${CMAKE_PROJECT_NAME} ${CMAKE_PROJECT_NAME}_static PROPERTIES OUTPUT_NAME _vnmimalloc)
+endif()
+
+#Setup the compiler options
+set(CMAKE_C_STANDARD 90)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+#enable position independent code (for shared libraries with exports)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'")
+
+#if debug
+add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
+
+if(ENABLE_GREEDY)
+ add_compile_definitions(VNLIB_MIMALLOC_GREEDY)
+endif()
+
+#setup flags for windows compilation
+if(MSVC)
+
+ #global windows cl flags
+ add_compile_options(
+ /Qspectre
+ /sdl
+ /TC
+ /GS
+ /machine:x64
+
+ $<$<CONFIG:Debug>:/FC>
+ $<$<CONFIG:Debug>:/showIncludes>
+ )
+
+ #only target our project
+ target_compile_options(
+ ${CMAKE_PROJECT_NAME}
+ PRIVATE
+
+ #disable warnings for struct padding and spectre mitigation wuen WX is enabled
+ $<$<CONFIG:Debug>:/wd5045>
+ $<$<CONFIG:Debug>:/wd4820>
+ $<$<CONFIG:Debug>:/wd4574>
+
+ #for debug configs
+ $<$<CONFIG:Debug>:/options:strict>
+ #disable warnings for struct padding and spectre mitigation wuen WX is enabled
+ $<$<CONFIG:Debug>:/Wall>
+ $<$<CONFIG:Debug>:/WX> #warnings as errors (only for our project)
+ $<$<CONFIG:Debug>:/Zi>
+ $<$<CONFIG:Debug>:/Zo>
+ )
+
+ #set build macros
+ add_compile_definitions(
+ $<$<CONFIG:DEBUG>:DEBUG>
+ $<$<CONFIG:RELEASE>:RELEASE>
+ )
+
+#configure gcc flags
+elseif(CMAKE_COMPILER_IS_GNUCC)
+
+ add_compile_options(
+ -Wextra
+ -fstack-protector
+
+ $<$<CONFIG:Debug>:-g>
+ $<$<CONFIG:Debug>:-Og>
+ $<$<CONFIG:Debug>:-Wall>
+ $<$<CONFIG:Debug>:-Werror>
+ )
+
+ #only target our project
+ target_compile_options(
+ ${CMAKE_PROJECT_NAME}
+ PRIVATE
+ $<$<CONFIG:Debug>:-Wall>
+ $<$<CONFIG:Debug>:-pedantic>
+ )
+
+endif()
+
+#include mimalloc headers
+include_directories(../mimalloc/include)
+
+if(MSVC)
+
+ #find the mimalloc static library for windows builds
+ find_library(VNLIB_MIMALLOC_DEBUG_LIB
+ NAMES mimalloc-static
+ PATHS ../mimalloc/build/Debug
+ )
+
+ find_library(VNLIB_MIMALLOC_RELEASE_LIB
+ NAMES mimalloc-static
+ PATHS ../mimalloc/build/Release
+ )
+
+ #target static libraries for all configs
+ target_link_libraries(${CMAKE_PROJECT_NAME}
+ $<$<CONFIG:Debug>:${VNLIB_MIMALLOC_DEBUG_LIB}>
+ #set release for all release configs
+ $<$<CONFIG:MinSizeRel>:${VNLIB_MIMALLOC_RELEASE_LIB}>
+ $<$<CONFIG:RelWithDepInfo>:${VNLIB_MIMALLOC_RELEASE_LIB}>
+ $<$<CONFIG:Release>:${VNLIB_MIMALLOC_RELEASE_LIB}>
+ )
+
+elseif(UNIX)
+
+ #find the mimalloc library for unix builds
+ find_library(VNLIB_MIMALLOC_LIB
+ NAMES mimalloc
+ PATHS ../mimalloc/build
+ )
+
+ #add the mimalloc library to the project
+ target_link_libraries(${CMAKE_PROJECT_NAME} ${VNLIB_MIMALLOC_LIB})
+
+else()
+
+ #failure
+ message(FATAL_ERROR "Unsupported platform configuration for mimalloc library")
+
+endif() \ No newline at end of file
diff --git a/lib/Utils.Memory/vnlib_mimalloc/LICENSE b/lib/Utils.Memory/vnlib_mimalloc/LICENSE
new file mode 100644
index 0000000..ce09686
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/LICENSE
@@ -0,0 +1,293 @@
+Copyright (c) 2023 Vaughn Nugent
+
+Contact information
+ Name: Vaughn Nugent
+ Email: vnpublic[at]proton.me
+ Website: https://www.vaughnnugent.com
+
+The software in this repository is licensed under the GNU GPL version 2.0 (or any later version).
+
+SPDX-License-Identifier: GPL-2.0-or-later
+
+License-Text:
+
+GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS \ No newline at end of file
diff --git a/lib/Utils.Memory/vnlib_mimalloc/Taskfile.yaml b/lib/Utils.Memory/vnlib_mimalloc/Taskfile.yaml
new file mode 100644
index 0000000..ddb5d0e
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/Taskfile.yaml
@@ -0,0 +1,125 @@
+# https://taskfile.dev
+
+#Called by the vnbuild system to produce builds for my website
+#https://www.vaughnnugent.com/resources/software
+
+#This taskfile is called in this directory and is specific to the vnlib_mimalloc project
+#that handles the MSBuild outside of the solution file
+
+version: '3'
+
+vars:
+ MS_ARGS: '/p:Platform=x64 /p:RunAnalyzersDuringBuild=false /p:BuildInParallel=true /p:MultiProcessorCompilation=true'
+ PROJECT_NAME: 'vnlib_mimalloc'
+ MODULE_NAME: 'vnlib.core'
+
+tasks:
+
+ default:
+ desc: "Builds the entire project from source code without using the VNBuild build system for target machines"
+ cmds:
+ #build with defaults
+ - task: build
+ - cmd: echo "Your vnlib_mimalloc dll file can be found in '{{.USER_WORKING_DIR}}/build'"
+ silent: true
+
+ build:
+ cmds:
+ #build the mimalloc library first
+ - cd ../mimalloc && cmake -B./build -DMI_BUILD_STATIC=1
+
+ #build the mimalloc library in debug mode first
+ - task: build-mimalloc-win
+ - task: build-mimalloc-gnumake
+
+
+ #build using msbuild for mimalloc libraries for debug and release modes
+ build-mimalloc-win:
+ platforms: ['windows']
+ internal: true
+ cmds:
+ - cd ../mimalloc/build && msbuild libmimalloc.sln /p:Configuration=debug {{.BUILD_FLAGS}} {{.MS_ARGS}}
+ - cd ../mimalloc/build && msbuild libmimalloc.sln /p:Configuration=release {{.BUILD_FLAGS}} {{.MS_ARGS}}
+
+ #init cmake build with greedy enabled
+ - cmake -B./build -DENABLE_GREEDY=1
+
+ #build solution in debug mode
+ - cd build && msbuild {{.PROJECT_NAME}}.sln /p:Configuration=debug {{.BUILD_FLAGS}} {{.MS_ARGS}}
+ #build in release
+ - cd build && msbuild {{.PROJECT_NAME}}.sln /p:Configuration=release {{.BUILD_FLAGS}} {{.MS_ARGS}}
+
+ #build using gnu make
+ build-mimalloc-gnumake:
+ platforms: ['linux']
+ internal: true
+ cmds:
+ - cd ../mimalloc/build && make
+
+ #init cmake build with greedy enabled
+ - cmake -B./build -DENABLE_GREEDY=1
+ #build project with make
+ - cd build && make
+
+ postbuild_success:
+ vars:
+ #required files to include in tar
+ TAR_FILES: "license.txt readme.txt mimalloc_license.txt"
+
+ cmds:
+ #make bin dir
+ - cmd: powershell -Command "New-Item -Type Directory -Force -Path './bin'"
+ ignore_error: true
+
+ #get licenses for debug
+ - task: licenses
+ vars:
+ TARGET: './build/Debug'
+
+ - task: licenses
+ vars:
+ TARGET: './build/Release'
+
+ #dynamic debug lib
+ - cd build/Debug && tar -czf '../../bin/win-x64-debug-{{.PROJECT_NAME}}.tgz' {{.PROJECT_NAME}}.dll {{.TAR_FILES}} {{.PROJECT_NAME}}.pdb
+
+ #release dll
+ - cd build/Release && tar -czf '../../bin/win-x64-release-{{.PROJECT_NAME}}.tgz' {{.PROJECT_NAME}}.dll {{.TAR_FILES}}
+
+ #source code
+ - task: pack_source
+
+
+ licenses:
+ cmds:
+ #add mimalloc license to binary output
+ - powershell -Command "Copy-Item -Path ../mimalloc/license -Destination '{{.TARGET}}/mimalloc_license.txt'"
+ #add my license file
+ - powershell -Command "Copy-Item -Path ./license -Destination '{{.TARGET}}/license.txt'"
+ #add readme file
+ - powershell -Command "Copy-Item -Path ./build.readme.txt -Destination '{{.TARGET}}/readme.txt'"
+
+ pack_source:
+ dir: '{{.USER_WORKING_DIR}}'
+ cmds:
+ #pack mimalloc source code and create the archive
+ - cd .. && powershell -Command "tar --exclude */build/* --exclude */.git/* -cvf 'vnlib_mimalloc/bin/src.tar' ./mimalloc/*"
+ #append the nativeheapapi directory
+ - cd .. && powershell -Command "tar -rvf vnlib_mimalloc/bin/src.tar ./NativeHeapApi/*"
+ #append the current directory
+ - cd .. && powershell -Command "tar --exclude */build/* --exclude */bin/* -rvf vnlib_mimalloc/bin/src.tar ./vnlib_mimalloc/*"
+ #use tar to gzip the archive
+ - cd bin && tar -czvf src.tgz src.tar
+ # delete the tar archive
+ - cmd: powershell -Command "Remove-Item bin/src.tar -Force"
+ ignore_error: true
+
+
+ clean:
+ ignore_error: true
+ cmds:
+ - cmd: powershell -Command "Remove-Item -Recurse './bin'"
+ - cmd: powershell -Command "Remove-Item -Recurse './build'"
+ - cmd: powershell -Command "Remove-Item -Recurse '../mimalloc/build'"
+
+ \ No newline at end of file
diff --git a/lib/Utils.Memory/vnlib_mimalloc/build.readme.txt b/lib/Utils.Memory/vnlib_mimalloc/build.readme.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/build.readme.txt
diff --git a/lib/Utils.Memory/vnlib_mimalloc/package.json b/lib/Utils.Memory/vnlib_mimalloc/package.json
new file mode 100644
index 0000000..0de9919
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "vnlib_mimalloc",
+ "version": "0.1.0",
+ "output_dir": "bin",
+ "author": "Vaughn Nugent",
+ "description": "A cmake cross-platform C89, NativeHeapApi compliant, mimalloc dynamic and static library. This project includes pre-build Windows x64 binaries as well as the source code for building the entire dynamic library on your system",
+ "copyright": "Copyright \u00A9 2023 Vaughn Nugent",
+ "company": "Vaughn Nugent",
+ "repository": "https://github.com/VnUgE/VNLib.Core/tree/main/lib/Utils.Memory/vnlib_mimalloc"
+} \ No newline at end of file
diff --git a/lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.c b/lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.c
new file mode 100644
index 0000000..a3a2e6b
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.c
@@ -0,0 +1,110 @@
+
+#include <NativeHeapApi.h>
+#include <mimalloc.h>
+
+#if defined(_WIN32) || defined(_WIN64)
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include <windows.h>
+
+#else
+
+#include <stddef.h>
+#define TRUE 1
+#define FALSE 0
+
+#endif
+
+
+#define SHARED_HEAP_HANDLE_VALUE ((HeapHandle)1)
+
+HEAP_METHOD_EXPORT HeapHandle HEAP_METHOD_CC heapGetSharedHeapHandle(void)
+{
+ //Return the shared heap pointer
+ return SHARED_HEAP_HANDLE_VALUE;
+}
+
+HEAP_METHOD_EXPORT ERRNO HEAP_METHOD_CC heapCreate(UnmanagedHeapDescriptor* flags)
+{
+
+ /*
+ * FIRST CLASS HEAPS ARE NOT CURRENTLY SUPPORTED
+ *
+ * The mimalloc library requires first class heaps allocate
+ * blocks on the thread that creates them. Thats not how this
+ * library works, so just pass the shared heap for now to keep
+ * things working.
+ *
+ * Always clear serialize flag and set shared heap pointer
+ */
+
+ flags->CreationFlags &= ~(HEAP_CREATION_SERIALZE_ENABLED);
+
+ flags->HeapPointer = heapGetSharedHeapHandle();
+
+ //Ignore remaining flags, zero/sync can be user optional
+
+ //Return value greater than 0
+ return flags->HeapPointer;
+}
+
+
+HEAP_METHOD_EXPORT ERRNO HEAP_METHOD_CC heapDestroy(HeapHandle heap)
+{
+ //Destroy the heap if not shared heap
+ if (heap != SHARED_HEAP_HANDLE_VALUE)
+ {
+ mi_heap_delete(heap);
+ }
+
+ return (ERRNO)TRUE;
+}
+
+
+HEAP_METHOD_EXPORT void* HEAP_METHOD_CC heapAlloc(HeapHandle heap, size_t elements, size_t alignment, int zero)
+{
+ //Check for global heap
+ if (heap == SHARED_HEAP_HANDLE_VALUE)
+ {
+ //Allocate the block
+ return zero ?
+ mi_calloc(elements, alignment) :
+ mi_mallocn(elements, alignment);
+ }
+ else
+ {
+ //First class heap, lock is held by caller, optionally zero the block
+ return zero ?
+ mi_heap_calloc(heap, elements, alignment) :
+ mi_heap_mallocn(heap, elements, alignment);
+ }
+}
+
+
+HEAP_METHOD_EXPORT void* HEAP_METHOD_CC heapRealloc(HeapHandle heap, void* block, size_t elements, size_t alignment, int zero)
+{
+ //Check for global heap
+ if (heap == SHARED_HEAP_HANDLE_VALUE)
+ {
+ //reallocate the block
+ return zero ?
+ mi_recalloc(block, elements, alignment) :
+ mi_reallocn(block, elements, alignment);
+ }
+ else
+ {
+ //First class heap realloc
+ return zero ?
+ mi_heap_recalloc(heap, block, elements, alignment) :
+ mi_heap_reallocn(heap, block, elements, alignment);
+ }
+}
+
+
+HEAP_METHOD_EXPORT ERRNO HEAP_METHOD_CC heapFree(HeapHandle heap, void* block)
+{
+ (void)heap;
+ mi_free(block);
+ return (ERRNO)TRUE;
+}
diff --git a/lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.vcxitems b/lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.vcxitems
new file mode 100644
index 0000000..2e9587f
--- /dev/null
+++ b/lib/Utils.Memory/vnlib_mimalloc/vnlib_mimalloc.vcxitems
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <ItemsProjectGuid>{62204123-3BB0-4F4D-983F-8C40C0F97297}</ItemsProjectGuid>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectCapability Include="SourceItemsFromImports" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="$(MSBuildThisFileDirectory)build.readme.txt" />
+ <Text Include="$(MSBuildThisFileDirectory)CMakeLists.txt" />
+ <Text Include="$(MSBuildThisFileDirectory)license.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(MSBuildThisFileDirectory)package.json" />
+ <None Include="$(MSBuildThisFileDirectory)Taskfile.yaml" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="$(MSBuildThisFileDirectory)vnlib_mimalloc.c" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/lib/Utils.Memory/vnlib_rpmalloc/Taskfile.yaml b/lib/Utils.Memory/vnlib_rpmalloc/Taskfile.yaml
index 481b437..af3180e 100644
--- a/lib/Utils.Memory/vnlib_rpmalloc/Taskfile.yaml
+++ b/lib/Utils.Memory/vnlib_rpmalloc/Taskfile.yaml
@@ -9,34 +9,56 @@
version: '3'
vars:
- INT_DIR: '{{.SCRATCH_DIR}}/obj/{{.MODULE_NAME}}/'
MS_ARGS: '/p:Platform=x64 /p:RunAnalyzersDuringBuild=false /p:BuildInParallel=true /p:MultiProcessorCompilation=true'
+ PROJECT_NAME: 'vnlib_rpmalloc'
+ MODULE_NAME: 'vnlib.core'
tasks:
+
+ default:
+ desc: "Builds the entire project from source code without using the VNBuild build system for target machines"
+ cmds:
+ #build with defaults
+ - task: build
+ - cmd: echo "Your vnlib_rpmalloc dll file can be found in '{{.USER_WORKING_DIR}}/build'"
+ silent: true
build:
cmds:
#init cmake build with greedy enabled
- cmake -B./build -DENABLE_GREEDY=1
+ #build the rpmalloc library in debug mode first
+ - task: build-rpmalloc-win
+ - task: build-rpmalloc-gnumake
+
+ #build using msbuild for rpmalloc libraries for debug and release modes
+ build-rpmalloc-win:
+ platforms: ['windows']
+ internal: true
+ cmds:
#build solution in debug mode
- cd build && msbuild {{.PROJECT_NAME}}.sln /p:Configuration=debug {{.BUILD_FLAGS}} {{.MS_ARGS}}
-
#build in release
- cd build && msbuild {{.PROJECT_NAME}}.sln /p:Configuration=release {{.BUILD_FLAGS}} {{.MS_ARGS}}
-
+
+ #build using gnu make
+ build-rpmalloc-gnumake:
+ platforms: ['linux']
+ internal: true
+ cmds:
+ #build project with make
+ - cd build && make
+
postbuild_success:
vars:
#required files to include in tar
TAR_FILES: "license.txt readme.txt rpmalloc_license.txt"
cmds:
- #make bin dir
+ #make bin dir
- cmd: powershell -Command "New-Item -Type Directory -Force -Path './bin'"
ignore_error: true
-
- #pack source code
- - task: packsource
#get licenses for debug
- task: licenses
@@ -46,18 +68,21 @@ tasks:
- task: licenses
vars:
TARGET: './build/Release'
-
+
#static debug lib
- cd build/Debug && tar -czf '../../bin/win-x64-debug-{{.PROJECT_NAME}}-static.tgz' {{.PROJECT_NAME}}_static.lib {{.TAR_FILES}} {{.PROJECT_NAME}}_static.pdb
#dynamic debug lib
- cd build/Debug && tar -czf '../../bin/win-x64-debug-{{.PROJECT_NAME}}.tgz' {{.PROJECT_NAME}}.dll {{.TAR_FILES}} {{.PROJECT_NAME}}.pdb
-
+
#release static lib
- cd build/Release && tar -czf '../../bin/win-x64-release-{{.PROJECT_NAME}}-static.tgz' {{.PROJECT_NAME}}_static.lib {{.TAR_FILES}}
#release dll
- cd build/Release && tar -czf '../../bin/win-x64-release-{{.PROJECT_NAME}}.tgz' {{.PROJECT_NAME}}.dll {{.TAR_FILES}}
+ #source code
+ - task: pack_source
+
licenses:
cmds:
#add rpmalloc license to binary output
@@ -66,13 +91,21 @@ tasks:
- powershell -Command "Copy-Item -Path ./license -Destination '{{.TARGET}}/license.txt'"
#add readme file
- powershell -Command "Copy-Item -Path ./build.readme.txt -Destination '{{.TARGET}}/readme.txt'"
-
- packsource:
+
+ pack_source:
dir: '{{.USER_WORKING_DIR}}'
- internal: true
cmds:
- #copy source code to target
- - powershell -Command "Get-ChildItem -Exclude *.yaml,build,bin | Resolve-Path -Relative | tar --files-from - -cvzf 'bin/src.tgz'"
+ #pack rpmalloc source code and create the archive
+ - cd .. && powershell -Command "tar --exclude */build/* --exclude */.git/* -cvf 'vnlib_rpmalloc/bin/src.tar' ./rpmalloc/*"
+ #append the nativeheapapi directory
+ - cd .. && powershell -Command "tar -rvf vnlib_rpmalloc/bin/src.tar ./NativeHeapApi/*"
+ #append the current directory
+ - cd .. && powershell -Command "tar --exclude */build/* --exclude */bin/* -rvf vnlib_rpmalloc/bin/src.tar ./vnlib_rpmalloc/*"
+ #use tar to gzip the archive
+ - cd bin && tar -czvf src.tgz src.tar
+ # delete the tar archive
+ - cmd: powershell -Command "Remove-Item bin/src.tar -Force"
+ ignore_error: true
clean:
diff --git a/lib/Utils.Memory/vnlib_rpmalloc/package.json b/lib/Utils.Memory/vnlib_rpmalloc/package.json
index 4cc7e68..5235262 100644
--- a/lib/Utils.Memory/vnlib_rpmalloc/package.json
+++ b/lib/Utils.Memory/vnlib_rpmalloc/package.json
@@ -1,9 +1,9 @@
{
"name": "vnlib_rpmalloc",
- "version": "0.1.3",
+ "version": "0.1.4",
"output_dir": "bin",
"author": "Vaughn Nugent",
- "description": "A project to maintain an x64 Windows dynamic and static library for RpMalloc by Mattias Jansson for use with the NativeHeapApi to for VNLib.Utils native heap loading.",
+ "description": "A project to maintain an x64 Windows dynamic and static library for RpMalloc by Mattias Jansson for use with the NativeHeapApi to for VNLib.Utils native heap loading. This project includes pre-build Windows x64 binaries as well as the source code for building the dynamic and static libraries on your system",
"copyright": "Copyright \u00A9 2023 Vaughn Nugent",
"company": "Vaughn Nugent",
"repository": "https://github.com/VnUgE/VNLib.Core/tree/main/lib/Utils.Memory/vnlib_rpmalloc"