aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zen/cmds/bench_cmd.cpp1381
-rw-r--r--src/zen/cmds/bench_cmd.h43
-rw-r--r--src/zen/cmds/builds_cmd.cpp1
-rw-r--r--src/zen/cmds/exec_cmd.cpp12
-rw-r--r--src/zen/cmds/exec_cmd.h1
-rw-r--r--src/zen/cmds/hub_cmd.cpp440
-rw-r--r--src/zen/cmds/hub_cmd.h118
-rw-r--r--src/zen/cmds/up_cmd.cpp175
-rw-r--r--src/zen/cmds/up_cmd.h2
-rw-r--r--src/zen/zen.cpp6
-rw-r--r--src/zen/zen.h2
-rw-r--r--src/zencompute/CLAUDE.md10
-rw-r--r--src/zencompute/computeservice.cpp269
-rw-r--r--src/zencompute/httpcomputeservice.cpp113
-rw-r--r--src/zencompute/httporchestrator.cpp3
-rw-r--r--src/zencompute/include/zencompute/computeservice.h1
-rw-r--r--src/zencompute/include/zencompute/httpcomputeservice.h2
-rw-r--r--src/zencompute/include/zencompute/httporchestrator.h2
-rw-r--r--src/zencompute/pathvalidation.h118
-rw-r--r--src/zencompute/runners/functionrunner.cpp12
-rw-r--r--src/zencompute/runners/linuxrunner.cpp2
-rw-r--r--src/zencompute/runners/localrunner.cpp17
-rw-r--r--src/zencompute/runners/localrunner.h4
-rw-r--r--src/zencompute/runners/macrunner.cpp2
-rw-r--r--src/zencompute/runners/managedrunner.cpp279
-rw-r--r--src/zencompute/runners/managedrunner.h64
-rw-r--r--src/zencompute/runners/windowsrunner.cpp99
-rw-r--r--src/zencompute/runners/windowsrunner.h1
-rw-r--r--src/zencompute/runners/winerunner.cpp2
-rw-r--r--src/zencore/compactbinarypackage.cpp122
-rw-r--r--src/zencore/filesystem.cpp71
-rw-r--r--src/zencore/include/zencore/compactbinarypackage.h19
-rw-r--r--src/zencore/include/zencore/fmtutils.h23
-rw-r--r--src/zencore/include/zencore/logging.h28
-rw-r--r--src/zencore/include/zencore/logging/broadcastsink.h86
-rw-r--r--src/zencore/include/zencore/logging/logger.h4
-rw-r--r--src/zencore/include/zencore/logging/logmsg.h12
-rw-r--r--src/zencore/include/zencore/logging/sink.h5
-rw-r--r--src/zencore/include/zencore/memory/fmalloc.h2
-rw-r--r--src/zencore/include/zencore/memory/mallocansi.h13
-rw-r--r--src/zencore/include/zencore/memory/mallocmimalloc.h19
-rw-r--r--src/zencore/include/zencore/memory/mallocrpmalloc.h19
-rw-r--r--src/zencore/include/zencore/memory/mallocstomp.h3
-rw-r--r--src/zencore/include/zencore/process.h175
-rw-r--r--src/zencore/include/zencore/system.h4
-rw-r--r--src/zencore/include/zencore/testing.h7
-rw-r--r--src/zencore/include/zencore/thread.h9
-rw-r--r--src/zencore/logging.cpp11
-rw-r--r--src/zencore/logging/logger.cpp54
-rw-r--r--src/zencore/memory/fmalloc.cpp5
-rw-r--r--src/zencore/memory/mallocansi.cpp6
-rw-r--r--src/zencore/memory/mallocmimalloc.cpp12
-rw-r--r--src/zencore/memory/mallocrpmalloc.cpp5
-rw-r--r--src/zencore/memory/mallocstomp.cpp6
-rw-r--r--src/zencore/memtrack/memorytrace.cpp1
-rw-r--r--src/zencore/memtrack/tracemalloc.h3
-rw-r--r--src/zencore/process.cpp713
-rw-r--r--src/zencore/sentryintegration.cpp2
-rw-r--r--src/zencore/system.cpp122
-rw-r--r--src/zencore/testing.cpp4
-rw-r--r--src/zencore/thread.cpp24
-rw-r--r--src/zencore/zencore.cpp2
-rw-r--r--src/zenhorde/hordeclient.cpp5
-rw-r--r--src/zenhorde/xmake.lua2
-rw-r--r--src/zenhttp/clients/httpclientcommon.h6
-rw-r--r--src/zenhttp/clients/httpclientcpr.cpp1285
-rw-r--r--src/zenhttp/clients/httpclientcpr.h188
-rw-r--r--src/zenhttp/clients/httpclientcurl.cpp4
-rw-r--r--src/zenhttp/clients/httpclientcurl.h5
-rw-r--r--src/zenhttp/httpclient.cpp116
-rw-r--r--src/zenhttp/httpclient_test.cpp11
-rw-r--r--src/zenhttp/httpclientauth.cpp42
-rw-r--r--src/zenhttp/httpserver.cpp138
-rw-r--r--src/zenhttp/include/zenhttp/auth/authservice.h4
-rw-r--r--src/zenhttp/include/zenhttp/cprutils.h98
-rw-r--r--src/zenhttp/include/zenhttp/httpclient.h9
-rw-r--r--src/zenhttp/include/zenhttp/httpclientauth.h5
-rw-r--r--src/zenhttp/include/zenhttp/httpcommon.h3
-rw-r--r--src/zenhttp/include/zenhttp/httpserver.h38
-rw-r--r--src/zenhttp/include/zenhttp/httpstats.h3
-rw-r--r--src/zenhttp/include/zenhttp/localrefpolicy.h21
-rw-r--r--src/zenhttp/include/zenhttp/packageformat.h25
-rw-r--r--src/zenhttp/include/zenhttp/websocket.h2
-rw-r--r--src/zenhttp/monitoring/httpstats.cpp186
-rw-r--r--src/zenhttp/packageformat.cpp548
-rw-r--r--src/zenhttp/servers/httpasio.cpp36
-rw-r--r--src/zenhttp/servers/httpsys.cpp26
-rw-r--r--src/zenhttp/servers/wstest.cpp3
-rw-r--r--src/zenhttp/xmake.lua7
-rw-r--r--src/zennomad/nomadprocess.cpp2
-rw-r--r--src/zenremotestore/builds/buildstorageoperations.cpp155
-rw-r--r--src/zenremotestore/builds/jupiterbuildstorage.cpp195
-rw-r--r--src/zenremotestore/include/zenremotestore/builds/buildstorageoperations.h12
-rw-r--r--src/zenremotestore/include/zenremotestore/builds/jupiterbuildstorage.h2
-rw-r--r--src/zenremotestore/jupiter/jupitersession.cpp5
-rw-r--r--src/zenremotestore/projectstore/remoteprojectstore.cpp55
-rw-r--r--src/zenremotestore/zenremotestore.cpp2
-rw-r--r--src/zens3-testbed/main.cpp2
-rw-r--r--src/zenserver-test/cache-tests.cpp31
-rw-r--r--src/zenserver-test/compute-tests.cpp636
-rw-r--r--src/zenserver-test/hub-tests.cpp737
-rw-r--r--src/zenserver-test/process-tests.cpp283
-rw-r--r--src/zenserver-test/projectstore-tests.cpp516
-rw-r--r--src/zenserver-test/zenserver-test.cpp45
-rw-r--r--src/zenserver/compute/computeserver.cpp2
-rw-r--r--src/zenserver/config/config.cpp2
-rw-r--r--src/zenserver/config/config.h2
-rw-r--r--src/zenserver/diag/diagsvcs.cpp11
-rw-r--r--src/zenserver/diag/logging.cpp40
-rw-r--r--src/zenserver/frontend/frontend.cpp65
-rw-r--r--src/zenserver/frontend/frontend.h20
-rw-r--r--src/zenserver/frontend/html/banner.js2
-rw-r--r--src/zenserver/frontend/html/compute/hub.html8
-rw-r--r--src/zenserver/frontend/html/nav.js52
-rw-r--r--src/zenserver/frontend/html/pages/builds.js88
-rw-r--r--src/zenserver/frontend/html/pages/cache.js80
-rw-r--r--src/zenserver/frontend/html/pages/compute.js69
-rw-r--r--src/zenserver/frontend/html/pages/docs.js415
-rw-r--r--src/zenserver/frontend/html/pages/entry.js2
-rw-r--r--src/zenserver/frontend/html/pages/hub.js757
-rw-r--r--src/zenserver/frontend/html/pages/info.js6
-rw-r--r--src/zenserver/frontend/html/pages/network.js247
-rw-r--r--src/zenserver/frontend/html/pages/objectstore.js210
-rw-r--r--src/zenserver/frontend/html/pages/orchestrator.js34
-rw-r--r--src/zenserver/frontend/html/pages/page.js167
-rw-r--r--src/zenserver/frontend/html/pages/projects.js128
-rw-r--r--src/zenserver/frontend/html/pages/proxy.js49
-rw-r--r--src/zenserver/frontend/html/pages/sessions.js617
-rw-r--r--src/zenserver/frontend/html/pages/start.js196
-rw-r--r--src/zenserver/frontend/html/pages/storage.js580
-rw-r--r--src/zenserver/frontend/html/pages/workspaces.js236
-rw-r--r--src/zenserver/frontend/html/thirdparty/marked.esm.js2580
-rw-r--r--src/zenserver/frontend/html/thirdparty/mermaid.min.js2607
-rw-r--r--src/zenserver/frontend/html/util/compactbinary.js41
-rw-r--r--src/zenserver/frontend/html/util/friendly.js53
-rw-r--r--src/zenserver/frontend/html/util/widgets.js18
-rw-r--r--src/zenserver/frontend/html/zen.css767
-rw-r--r--src/zenserver/frontend/zipfs.cpp67
-rw-r--r--src/zenserver/frontend/zipfs.h12
-rw-r--r--src/zenserver/frontend/zipfs_test.cpp214
-rw-r--r--src/zenserver/hub/httphubservice.cpp356
-rw-r--r--src/zenserver/hub/httphubservice.h32
-rw-r--r--src/zenserver/hub/httpproxyhandler.cpp504
-rw-r--r--src/zenserver/hub/httpproxyhandler.h52
-rw-r--r--src/zenserver/hub/hub.cpp2524
-rw-r--r--src/zenserver/hub/hub.h244
-rw-r--r--src/zenserver/hub/hubinstancestate.cpp37
-rw-r--r--src/zenserver/hub/hubinstancestate.h28
-rw-r--r--src/zenserver/hub/hydration.cpp1306
-rw-r--r--src/zenserver/hub/hydration.h10
-rw-r--r--src/zenserver/hub/storageserverinstance.cpp312
-rw-r--r--src/zenserver/hub/storageserverinstance.h114
-rw-r--r--src/zenserver/hub/zenhubserver.cpp438
-rw-r--r--src/zenserver/hub/zenhubserver.h53
-rw-r--r--src/zenserver/main.cpp28
-rw-r--r--src/zenserver/proxy/httpproxystats.cpp12
-rw-r--r--src/zenserver/proxy/zenproxyserver.cpp2
-rw-r--r--src/zenserver/sessions/httpsessions.cpp391
-rw-r--r--src/zenserver/sessions/httpsessions.h38
-rw-r--r--src/zenserver/sessions/inprocsessionlogsink.cpp39
-rw-r--r--src/zenserver/sessions/inprocsessionlogsink.h30
-rw-r--r--src/zenserver/sessions/sessions.cpp141
-rw-r--r--src/zenserver/sessions/sessions.h45
-rw-r--r--src/zenserver/stats/statsreporter.cpp4
-rw-r--r--src/zenserver/storage/admin/admin.cpp133
-rw-r--r--src/zenserver/storage/admin/admin.h4
-rw-r--r--src/zenserver/storage/buildstore/httpbuildstore.cpp40
-rw-r--r--src/zenserver/storage/buildstore/httpbuildstore.h9
-rw-r--r--src/zenserver/storage/cache/httpstructuredcache.cpp165
-rw-r--r--src/zenserver/storage/cache/httpstructuredcache.h15
-rw-r--r--src/zenserver/storage/localrefpolicy.cpp29
-rw-r--r--src/zenserver/storage/localrefpolicy.h25
-rw-r--r--src/zenserver/storage/objectstore/objectstore.cpp182
-rw-r--r--src/zenserver/storage/objectstore/objectstore.h37
-rw-r--r--src/zenserver/storage/projectstore/httpprojectstore.cpp63
-rw-r--r--src/zenserver/storage/projectstore/httpprojectstore.h15
-rw-r--r--src/zenserver/storage/storageconfig.cpp4
-rw-r--r--src/zenserver/storage/storageconfig.h3
-rw-r--r--src/zenserver/storage/upstream/upstreamservice.h4
-rw-r--r--src/zenserver/storage/workspaces/httpworkspaces.cpp38
-rw-r--r--src/zenserver/storage/workspaces/httpworkspaces.h5
-rw-r--r--src/zenserver/storage/zenstorageserver.cpp100
-rw-r--r--src/zenserver/storage/zenstorageserver.h30
-rw-r--r--src/zenserver/trace/tracerecorder.cpp1
-rw-r--r--src/zenserver/xmake.lua32
-rw-r--r--src/zenserver/zenserver.cpp48
-rw-r--r--src/zenserver/zenserver.h13
-rw-r--r--src/zenstore/include/zenstore/projectstore.h1
-rw-r--r--src/zenstore/projectstore.cpp13
-rw-r--r--src/zentelemetry/hyperloglog.cpp127
-rw-r--r--src/zentelemetry/include/zentelemetry/hyperloglog.h166
-rw-r--r--src/zentelemetry/zentelemetry.cpp2
-rw-r--r--src/zentest-appstub/zentest-appstub.cpp77
-rw-r--r--src/zenutil-test/xmake.lua1
-rw-r--r--src/zenutil/cloud/imdscredentials.cpp2
-rw-r--r--src/zenutil/cloud/minioprocess.cpp9
-rw-r--r--src/zenutil/cloud/s3client.cpp159
-rw-r--r--src/zenutil/config/loggingconfig.cpp2
-rw-r--r--src/zenutil/consul/consul.cpp386
-rw-r--r--src/zenutil/include/zenutil/cloud/s3client.h34
-rw-r--r--src/zenutil/include/zenutil/config/loggingconfig.h6
-rw-r--r--src/zenutil/include/zenutil/consul.h21
-rw-r--r--src/zenutil/include/zenutil/logging.h10
-rw-r--r--src/zenutil/include/zenutil/process/subprocessmanager.h285
-rw-r--r--src/zenutil/include/zenutil/sessionsclient.h65
-rw-r--r--src/zenutil/include/zenutil/splitconsole/logstreamlistener.h61
-rw-r--r--src/zenutil/include/zenutil/splitconsole/tcplogstreamsink.h193
-rw-r--r--src/zenutil/include/zenutil/zenserverprocess.h57
-rw-r--r--src/zenutil/logging/jsonformatter.cpp2
-rw-r--r--src/zenutil/logging/logging.cpp39
-rw-r--r--src/zenutil/process/asyncpipereader.cpp276
-rw-r--r--src/zenutil/process/asyncpipereader.h62
-rw-r--r--src/zenutil/process/exitwatcher.cpp294
-rw-r--r--src/zenutil/process/exitwatcher.h48
-rw-r--r--src/zenutil/process/subprocessmanager.cpp1838
-rw-r--r--src/zenutil/sessionsclient.cpp377
-rw-r--r--src/zenutil/splitconsole/logstreamlistener.cpp426
-rw-r--r--src/zenutil/xmake.lua4
-rw-r--r--src/zenutil/zenserverprocess.cpp186
-rw-r--r--src/zenutil/zenutil.cpp8
220 files changed, 29300 insertions, 4382 deletions
diff --git a/src/zen/cmds/bench_cmd.cpp b/src/zen/cmds/bench_cmd.cpp
index 908d62257..b1639105a 100644
--- a/src/zen/cmds/bench_cmd.cpp
+++ b/src/zen/cmds/bench_cmd.cpp
@@ -3,6 +3,7 @@
#include "bench_cmd.h"
#include "bench.h"
+#include <zencore/basicfile.h>
#include <zencore/compactbinary.h>
#include <zencore/except.h>
#include <zencore/filesystem.h>
@@ -15,10 +16,22 @@
#include <zenhttp/httpclient.h>
#include <zentelemetry/stats.h>
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+#else
+# include <errno.h>
+# include <fcntl.h>
+# include <sys/stat.h>
+# include <unistd.h>
+#endif
+
#include <algorithm>
#include <atomic>
+#include <chrono>
#include <csignal>
+#include <cstring>
#include <mutex>
+#include <random>
#include <thread>
static std::atomic<bool> s_BenchAbort{false};
@@ -488,6 +501,1373 @@ BenchHttpSubCmd::RunContinuous(const std::string& BaseUri, const std::string& Pa
}
//////////////////////////////////////////////////////////////////////////
+// DirectIoFile - thin wrapper around platform file handles for unbuffered I/O.
+// On Linux: opens with O_DIRECT, falls back gracefully if the filesystem
+// doesn't support it (e.g. tmpfs). On macOS: uses F_NOCACHE. On Windows:
+// opens with FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH.
+// Buffers, offsets and transfer sizes must all be multiples of kDirectIoAlignment.
+
+static constexpr uint64_t kDirectIoAlignment = 4096;
+
+static uint8_t*
+AlignBuffer(uint8_t* Raw, uint64_t Alignment)
+{
+ return reinterpret_cast<uint8_t*>((reinterpret_cast<uintptr_t>(Raw) + Alignment - 1) & ~(Alignment - 1));
+}
+
+static uint64_t
+AlignUp(uint64_t Value, uint64_t Alignment)
+{
+ return (Value + Alignment - 1) & ~(Alignment - 1);
+}
+
+class DirectIoFile
+{
+public:
+ DirectIoFile() = default;
+ ~DirectIoFile() { Close(); }
+ DirectIoFile(const DirectIoFile&) = delete;
+ DirectIoFile& operator=(const DirectIoFile&) = delete;
+
+ // Returns true if the file was successfully opened with direct/unbuffered I/O active.
+ // Returns false if direct I/O was requested but the filesystem doesn't support it and
+ // we fell back to buffered I/O. Throws std::system_error if the file cannot be opened.
+ bool OpenWrite(const std::filesystem::path& Path, bool RequestDirect); // create/truncate
+ bool OpenRead(const std::filesystem::path& Path, bool RequestDirect); // read-only, existing
+ bool OpenReadWrite(const std::filesystem::path& Path, bool RequestDirect); // read-write, existing, no truncate
+
+ void WriteAt(const void* Data, uint64_t Size, uint64_t Offset);
+ void ReadAt(void* Data, uint64_t Size, uint64_t Offset);
+ void Close();
+
+private:
+#if ZEN_PLATFORM_WINDOWS
+ HANDLE m_Handle = INVALID_HANDLE_VALUE;
+#else
+ int m_Fd = -1;
+#endif
+};
+
+#if ZEN_PLATFORM_WINDOWS
+
+bool
+DirectIoFile::OpenWrite(const std::filesystem::path& Path, bool RequestDirect)
+{
+ DWORD Flags = FILE_ATTRIBUTE_NORMAL;
+ if (RequestDirect)
+ {
+ Flags |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
+ }
+
+ HANDLE Handle = ::CreateFileW(Path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, Flags, nullptr);
+
+ if (Handle == INVALID_HANDLE_VALUE && RequestDirect)
+ {
+ // Fall back to buffered I/O
+ Handle = ::CreateFileW(Path.c_str(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ,
+ nullptr,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ nullptr);
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()),
+ fmt::format("Failed to open '{}' for writing", Path));
+ }
+ m_Handle = Handle;
+ return false;
+ }
+
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()),
+ fmt::format("Failed to open '{}' for writing", Path));
+ }
+
+ m_Handle = Handle;
+ return RequestDirect;
+}
+
+bool
+DirectIoFile::OpenRead(const std::filesystem::path& Path, bool RequestDirect)
+{
+ DWORD Flags = FILE_ATTRIBUTE_NORMAL;
+ if (RequestDirect)
+ {
+ Flags |= FILE_FLAG_NO_BUFFERING;
+ }
+
+ HANDLE Handle = ::CreateFileW(Path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, Flags, nullptr);
+
+ if (Handle == INVALID_HANDLE_VALUE && RequestDirect)
+ {
+ Handle = ::CreateFileW(Path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()),
+ fmt::format("Failed to open '{}' for reading", Path));
+ }
+ m_Handle = Handle;
+ return false;
+ }
+
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()),
+ fmt::format("Failed to open '{}' for reading", Path));
+ }
+
+ m_Handle = Handle;
+ return RequestDirect;
+}
+
+void
+DirectIoFile::WriteAt(const void* Data, uint64_t Size, uint64_t Offset)
+{
+ OVERLAPPED Ovl{};
+ Ovl.Offset = DWORD(Offset & 0xFFFF'FFFFu);
+ Ovl.OffsetHigh = DWORD(Offset >> 32);
+
+ DWORD BytesWritten = 0;
+ if (!::WriteFile(m_Handle, Data, static_cast<DWORD>(Size), &BytesWritten, &Ovl) || BytesWritten != Size)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()), "WriteFile failed");
+ }
+}
+
+void
+DirectIoFile::ReadAt(void* Data, uint64_t Size, uint64_t Offset)
+{
+ OVERLAPPED Ovl{};
+ Ovl.Offset = DWORD(Offset & 0xFFFF'FFFFu);
+ Ovl.OffsetHigh = DWORD(Offset >> 32);
+
+ DWORD BytesRead = 0;
+ if (!::ReadFile(m_Handle, Data, static_cast<DWORD>(Size), &BytesRead, &Ovl) || BytesRead != Size)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()), "ReadFile failed");
+ }
+}
+
+bool
+DirectIoFile::OpenReadWrite(const std::filesystem::path& Path, bool RequestDirect)
+{
+ DWORD Flags = FILE_ATTRIBUTE_NORMAL;
+ if (RequestDirect)
+ {
+ Flags |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
+ }
+
+ HANDLE Handle = ::CreateFileW(Path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, Flags, nullptr);
+
+ if (Handle == INVALID_HANDLE_VALUE && RequestDirect)
+ {
+ Handle = ::CreateFileW(Path.c_str(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ,
+ nullptr,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ nullptr);
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()),
+ fmt::format("Failed to open '{}' for read-write", Path));
+ }
+ m_Handle = Handle;
+ return false;
+ }
+
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(std::error_code(::GetLastError(), std::system_category()),
+ fmt::format("Failed to open '{}' for read-write", Path));
+ }
+
+ m_Handle = Handle;
+ return RequestDirect;
+}
+
+void
+DirectIoFile::Close()
+{
+ if (m_Handle != INVALID_HANDLE_VALUE)
+ {
+ ::CloseHandle(m_Handle);
+ m_Handle = INVALID_HANDLE_VALUE;
+ }
+}
+
+#else // Linux / macOS
+
+bool
+DirectIoFile::OpenWrite(const std::filesystem::path& Path, bool RequestDirect)
+{
+ int Flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC;
+
+# if ZEN_PLATFORM_LINUX
+ if (RequestDirect)
+ {
+ int TryFd = ::open(Path.c_str(), Flags | O_DIRECT, 0666);
+ if (TryFd >= 0)
+ {
+ ::fchmod(TryFd, 0666);
+ m_Fd = TryFd;
+ return true;
+ }
+ if (errno != EINVAL)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), fmt::format("Failed to open '{}' for writing", Path));
+ }
+ // EINVAL: filesystem doesn't support O_DIRECT, fall through to buffered open
+ }
+# endif
+
+ int Fd = ::open(Path.c_str(), Flags, 0666);
+ if (Fd < 0)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), fmt::format("Failed to open '{}' for writing", Path));
+ }
+ ::fchmod(Fd, 0666);
+
+# if ZEN_PLATFORM_MAC
+ if (RequestDirect)
+ {
+ ::fcntl(Fd, F_NOCACHE, 1);
+ }
+# endif
+
+ m_Fd = Fd;
+ return RequestDirect; // On macOS F_NOCACHE is always "accepted" (best-effort)
+}
+
+bool
+DirectIoFile::OpenRead(const std::filesystem::path& Path, bool RequestDirect)
+{
+ int Flags = O_RDONLY | O_CLOEXEC;
+
+# if ZEN_PLATFORM_LINUX
+ if (RequestDirect)
+ {
+ int TryFd = ::open(Path.c_str(), Flags | O_DIRECT);
+ if (TryFd >= 0)
+ {
+ m_Fd = TryFd;
+ return true;
+ }
+ if (errno != EINVAL)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), fmt::format("Failed to open '{}' for reading", Path));
+ }
+ }
+# endif
+
+ int Fd = ::open(Path.c_str(), Flags);
+ if (Fd < 0)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), fmt::format("Failed to open '{}' for reading", Path));
+ }
+
+# if ZEN_PLATFORM_MAC
+ if (RequestDirect)
+ {
+ ::fcntl(Fd, F_NOCACHE, 1);
+ }
+# endif
+
+ m_Fd = Fd;
+ return RequestDirect;
+}
+
+void
+DirectIoFile::WriteAt(const void* Data, uint64_t Size, uint64_t Offset)
+{
+ ssize_t Result = ::pwrite(m_Fd, Data, static_cast<size_t>(Size), static_cast<off_t>(Offset));
+ if (Result < 0 || static_cast<uint64_t>(Result) != Size)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), "pwrite failed");
+ }
+}
+
+void
+DirectIoFile::ReadAt(void* Data, uint64_t Size, uint64_t Offset)
+{
+ ssize_t Result = ::pread(m_Fd, Data, static_cast<size_t>(Size), static_cast<off_t>(Offset));
+ if (Result < 0 || static_cast<uint64_t>(Result) != Size)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), "pread failed");
+ }
+}
+
+bool
+DirectIoFile::OpenReadWrite(const std::filesystem::path& Path, bool RequestDirect)
+{
+ int Flags = O_RDWR | O_CLOEXEC;
+
+# if ZEN_PLATFORM_LINUX
+ if (RequestDirect)
+ {
+ int TryFd = ::open(Path.c_str(), Flags | O_DIRECT);
+ if (TryFd >= 0)
+ {
+ m_Fd = TryFd;
+ return true;
+ }
+ if (errno != EINVAL)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()),
+ fmt::format("Failed to open '{}' for read-write", Path));
+ }
+ }
+# endif
+
+ int Fd = ::open(Path.c_str(), Flags);
+ if (Fd < 0)
+ {
+ throw std::system_error(std::error_code(errno, std::system_category()), fmt::format("Failed to open '{}' for read-write", Path));
+ }
+
+# if ZEN_PLATFORM_MAC
+ if (RequestDirect)
+ {
+ ::fcntl(Fd, F_NOCACHE, 1);
+ }
+# endif
+
+ m_Fd = Fd;
+ return RequestDirect;
+}
+
+void
+DirectIoFile::Close()
+{
+ if (m_Fd >= 0)
+ {
+ ::close(m_Fd);
+ m_Fd = -1;
+ }
+}
+
+#endif // ZEN_PLATFORM_WINDOWS
+
+//////////////////////////////////////////////////////////////////////////
+// BenchDiskSubCmd
+
+static constexpr uint64_t kDiskBenchBlockSizes[] = {4 * 1024, 64 * 1024, 1024 * 1024, 4 * 1024 * 1024};
+
+BenchDiskSubCmd::BenchDiskSubCmd() : ZenSubCmdBase("disk", "Benchmark local disk I/O bandwidth and file operation throughput")
+{
+ SubOptions().add_option("", "p", "path", "Directory to use for benchmark files", cxxopts::value<std::string>(m_Path), "<path>");
+ SubOptions().add_option("",
+ "",
+ "run",
+ "Comma-separated list of benchmarks to run: seq, rand, ops, clone, sync (default: all except sync)",
+ cxxopts::value<std::string>(m_Run)->default_value("seq,rand,ops,clone"),
+ "<list>");
+ SubOptions().add_option("",
+ "",
+ "sync-duration",
+ "Duration of the sync latency benchmark in seconds",
+ cxxopts::value<int>(m_SyncDurationSec)->default_value("10"),
+ "<seconds>");
+ SubOptions().add_option("",
+ "c",
+ "concurrency",
+ "Number of concurrent threads",
+ cxxopts::value<int>(m_Concurrency)->default_value("1"),
+ "<threads>");
+ SubOptions().add_option("",
+ "",
+ "file-size",
+ "Size of each sequential test file in bytes (default: 268435456 = 256 MiB)",
+ cxxopts::value<uint64_t>(m_FileSize)->default_value("268435456"),
+ "<bytes>");
+ SubOptions().add_option("",
+ "",
+ "file-count",
+ "Number of small files to create/delete for the file-ops test",
+ cxxopts::value<int>(m_FileCount)->default_value("1000"),
+ "<count>");
+ SubOptions().add_option("",
+ "",
+ "rand-ops",
+ "Number of random I/O operations per thread",
+ cxxopts::value<int>(m_RandOps)->default_value("10000"),
+ "<count>");
+ SubOptions().add_options()("no-direct",
+ "Use buffered I/O instead of direct/unbuffered I/O (may inflate read results due to OS page cache)",
+ cxxopts::value<bool>(m_NoDirectIo)->default_value("false"));
+ SubOptions().parse_positional({"path"});
+}
+
+void
+BenchDiskSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ if (m_Path.empty())
+ {
+ throw OptionParseException("Path is required", SubOptions().help());
+ }
+
+ if (m_Concurrency <= 0)
+ {
+ throw OptionParseException("--concurrency must be a positive integer", SubOptions().help());
+ }
+
+ if (m_FileSize == 0)
+ {
+ throw OptionParseException("--file-size must be positive", SubOptions().help());
+ }
+
+ if (m_FileCount <= 0)
+ {
+ throw OptionParseException("--file-count must be a positive integer", SubOptions().help());
+ }
+
+ if (m_RandOps <= 0)
+ {
+ throw OptionParseException("--rand-ops must be a positive integer", SubOptions().help());
+ }
+
+ // Parse the --run list into individual flags
+ bool DoSeq = false;
+ bool DoRand = false;
+ bool DoOps = false;
+ bool DoClone = false;
+ bool DoSync = false;
+
+ {
+ std::string_view Remaining(m_Run);
+ while (!Remaining.empty())
+ {
+ size_t Comma = Remaining.find(',');
+ std::string_view Token = Remaining.substr(0, Comma);
+ if (Token == "seq")
+ {
+ DoSeq = true;
+ }
+ else if (Token == "rand")
+ {
+ DoRand = true;
+ }
+ else if (Token == "ops")
+ {
+ DoOps = true;
+ }
+ else if (Token == "clone")
+ {
+ DoClone = true;
+ }
+ else if (Token == "sync")
+ {
+ DoSync = true;
+ }
+ else
+ {
+ throw OptionParseException(fmt::format("Unknown benchmark '{}' in --run (valid: seq, rand, ops, clone, sync)", Token),
+ SubOptions().help());
+ }
+ Remaining = (Comma == std::string_view::npos) ? std::string_view{} : Remaining.substr(Comma + 1);
+ }
+ }
+
+ if (!DoSeq && !DoRand && !DoOps && !DoClone && !DoSync)
+ {
+ throw OptionParseException("--run list is empty", SubOptions().help());
+ }
+
+ std::filesystem::path Dir(m_Path);
+
+ if (!std::filesystem::is_directory(Dir))
+ {
+ throw OptionParseException(fmt::format("'{}' is not a valid directory", m_Path), SubOptions().help());
+ }
+
+ bool const DirectIo = !m_NoDirectIo;
+
+ s_BenchAbort.store(false);
+ auto PrevSigInt = std::signal(SIGINT, [](int) { s_BenchAbort.store(true); });
+ auto PrevSigTerm = std::signal(SIGTERM, [](int) { s_BenchAbort.store(true); });
+
+ uint64_t TotalSeqBytes = m_FileSize * static_cast<uint64_t>(m_Concurrency);
+
+ ZEN_CONSOLE("Disk Benchmark");
+ ZEN_CONSOLE(" Path : {}", m_Path);
+ ZEN_CONSOLE(" Concurrency : {} thread(s)", m_Concurrency);
+ ZEN_CONSOLE(" File size : {} per thread ({} total)", NiceBytes(m_FileSize), NiceBytes(TotalSeqBytes));
+ ZEN_CONSOLE(" File count : {} (file-ops test)", m_FileCount);
+ ZEN_CONSOLE(" I/O mode : {}", DirectIo ? "direct (unbuffered)" : "buffered");
+ ZEN_CONSOLE("");
+ if (DoSeq)
+ {
+ ZEN_CONSOLE("Sequential I/O");
+ ZEN_CONSOLE(" {:>10} {:>12} {:>10} {:>12} {:>10}", "Block", "Write", "W IOPS", "Read", "R IOPS");
+
+ bool WarnedAboutFallback = false;
+
+ for (uint64_t BlockSize : kDiskBenchBlockSizes)
+ {
+ if (s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ break;
+ }
+
+ SeqResult WriteResult = RunSeqWrite(Dir, BlockSize, DirectIo);
+ SeqResult ReadResult = RunSeqRead(Dir, BlockSize, DirectIo);
+
+ CleanupSeqFiles(Dir);
+
+ if (DirectIo && !WriteResult.UsedDirectIo && !WarnedAboutFallback)
+ {
+ ZEN_CONSOLE_WARN(" Note: direct I/O not supported on this filesystem, results reflect buffered I/O");
+ WarnedAboutFallback = true;
+ }
+
+ std::string WriteStr = WriteResult.ErrorCount > 0
+ ? fmt::format("{}/s ({} err)", NiceBytes(WriteResult.BytesPerSec), WriteResult.ErrorCount)
+ : fmt::format("{}/s", NiceBytes(WriteResult.BytesPerSec));
+
+ std::string ReadStr = ReadResult.ErrorCount > 0
+ ? fmt::format("{}/s ({} err)", NiceBytes(ReadResult.BytesPerSec), ReadResult.ErrorCount)
+ : fmt::format("{}/s", NiceBytes(ReadResult.BytesPerSec));
+
+ ZEN_CONSOLE(" {:>10} {:>12} {:>10L} {:>12} {:>10L}",
+ NiceBytes(BlockSize),
+ WriteStr,
+ WriteResult.Iops,
+ ReadStr,
+ ReadResult.Iops);
+ }
+ }
+
+ if (DoRand && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ if (DoSeq)
+ {
+ ZEN_CONSOLE("");
+ }
+
+ ZEN_CONSOLE("Random I/O ({:L} ops per thread)", m_RandOps);
+ ZEN_CONSOLE(" {:>10} {:>12} {:>10} {:>12} {:>10}", "Block", "Write", "W IOPS", "Read", "R IOPS");
+
+ PrefillRandFiles(Dir, DirectIo);
+
+ for (uint64_t BlockSize : kDiskBenchBlockSizes)
+ {
+ SeqResult RandWriteResult = RunRandWrite(Dir, BlockSize, DirectIo);
+ SeqResult RandReadResult = RunRandRead(Dir, BlockSize, DirectIo);
+
+ std::string WriteStr = RandWriteResult.ErrorCount > 0
+ ? fmt::format("{}/s ({} err)", NiceBytes(RandWriteResult.BytesPerSec), RandWriteResult.ErrorCount)
+ : fmt::format("{}/s", NiceBytes(RandWriteResult.BytesPerSec));
+
+ std::string ReadStr = RandReadResult.ErrorCount > 0
+ ? fmt::format("{}/s ({} err)", NiceBytes(RandReadResult.BytesPerSec), RandReadResult.ErrorCount)
+ : fmt::format("{}/s", NiceBytes(RandReadResult.BytesPerSec));
+
+ ZEN_CONSOLE(" {:>10} {:>12} {:>10L} {:>12} {:>10L}",
+ NiceBytes(BlockSize),
+ WriteStr,
+ RandWriteResult.Iops,
+ ReadStr,
+ RandReadResult.Iops);
+ }
+
+ CleanupRandFiles(Dir);
+ }
+
+ if (DoOps && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ if (DoSeq || DoRand)
+ {
+ ZEN_CONSOLE("");
+ }
+
+ RunFileOps(Dir);
+ }
+
+ if (DoClone && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ if (DoSeq || DoRand || DoOps)
+ {
+ ZEN_CONSOLE("");
+ }
+
+ RunClone(Dir);
+ }
+
+ if (DoSync && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ if (DoSeq || DoRand || DoOps || DoClone)
+ {
+ ZEN_CONSOLE("");
+ }
+
+ RunSync(Dir);
+ }
+
+ // Always clean up any leftover bench files, even if interrupted by Ctrl-C
+ CleanupSeqFiles(Dir);
+ CleanupRandFiles(Dir);
+ CleanupFileOpFiles(Dir);
+ CleanupCloneFiles(Dir);
+ CleanupSyncFiles(Dir);
+
+ std::signal(SIGINT, PrevSigInt);
+ std::signal(SIGTERM, PrevSigTerm);
+}
+
+BenchDiskSubCmd::SeqResult
+BenchDiskSubCmd::RunSeqWrite(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo)
+{
+ // When using direct I/O, the file size must be a multiple of the alignment.
+ uint64_t const EffectiveFileSize = DirectIo ? AlignUp(m_FileSize, kDirectIoAlignment) : m_FileSize;
+
+ // Shared read-only write buffer, aligned for direct I/O. Extra padding lets us
+ // hand any thread a pointer that is guaranteed kDirectIoAlignment-aligned.
+ std::vector<uint8_t> RawWriteBuf(BlockSize + kDirectIoAlignment - 1);
+ uint8_t* const WritePtr = AlignBuffer(RawWriteBuf.data(), kDirectIoAlignment);
+ for (size_t i = 0; i < BlockSize; ++i)
+ {
+ WritePtr[i] = static_cast<uint8_t>(i & 0xFF);
+ }
+
+ std::atomic<int64_t> TotalBytesWritten{0};
+ std::atomic<int64_t> TotalOps{0};
+ std::atomic<int> ErrorCount{0};
+ std::atomic<int> DirectIoCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&, i]() {
+ try
+ {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_disk_{}.tmp", i);
+ DirectIoFile File;
+ bool GotDirect = File.OpenWrite(FilePath, DirectIo);
+
+ if (GotDirect)
+ {
+ DirectIoCount.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ uint64_t Remaining = EffectiveFileSize;
+ uint64_t Offset = 0;
+ int64_t LocalOps = 0;
+
+ while (Remaining > 0 && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ uint64_t WriteSize = std::min(BlockSize, Remaining);
+ File.WriteAt(WritePtr, WriteSize, Offset);
+ Offset += WriteSize;
+ Remaining -= WriteSize;
+ ++LocalOps;
+ }
+
+ TotalBytesWritten.fetch_add(static_cast<int64_t>(EffectiveFileSize), std::memory_order_relaxed);
+ TotalOps.fetch_add(LocalOps, std::memory_order_relaxed);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ SeqResult Result;
+ Result.ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ Result.BytesPerSec = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalBytesWritten.load() / Result.ElapsedSec) : 0;
+ Result.Iops = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalOps.load() / Result.ElapsedSec) : 0;
+ Result.ErrorCount = ErrorCount.load();
+ Result.UsedDirectIo = DirectIoCount.load() > 0;
+
+ return Result;
+}
+
+BenchDiskSubCmd::SeqResult
+BenchDiskSubCmd::RunSeqRead(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo)
+{
+ uint64_t const EffectiveFileSize = DirectIo ? AlignUp(m_FileSize, kDirectIoAlignment) : m_FileSize;
+
+ std::atomic<int64_t> TotalBytesRead{0};
+ std::atomic<int64_t> TotalOps{0};
+ std::atomic<int> ErrorCount{0};
+ std::atomic<int> DirectIoCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&, i, BlockSize]() {
+ // Each thread owns its aligned read buffer
+ std::vector<uint8_t> RawReadBuf(BlockSize + kDirectIoAlignment - 1);
+ uint8_t* ReadPtr = AlignBuffer(RawReadBuf.data(), kDirectIoAlignment);
+
+ try
+ {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_disk_{}.tmp", i);
+ DirectIoFile File;
+ bool GotDirect = File.OpenRead(FilePath, DirectIo);
+
+ if (GotDirect)
+ {
+ DirectIoCount.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ uint64_t Remaining = EffectiveFileSize;
+ uint64_t Offset = 0;
+ int64_t LocalOps = 0;
+
+ while (Remaining > 0 && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ uint64_t ReadSize = std::min(BlockSize, Remaining);
+ File.ReadAt(ReadPtr, ReadSize, Offset);
+ Offset += ReadSize;
+ Remaining -= ReadSize;
+ ++LocalOps;
+ }
+
+ TotalBytesRead.fetch_add(static_cast<int64_t>(EffectiveFileSize), std::memory_order_relaxed);
+ TotalOps.fetch_add(LocalOps, std::memory_order_relaxed);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ SeqResult Result;
+ Result.ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ Result.BytesPerSec = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalBytesRead.load() / Result.ElapsedSec) : 0;
+ Result.Iops = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalOps.load() / Result.ElapsedSec) : 0;
+ Result.ErrorCount = ErrorCount.load();
+ Result.UsedDirectIo = DirectIoCount.load() > 0;
+
+ return Result;
+}
+
+void
+BenchDiskSubCmd::CleanupSeqFiles(const std::filesystem::path& Dir)
+{
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ std::error_code Ec;
+ std::filesystem::path FilePath = Dir / fmt::format("bench_disk_{}.tmp", i);
+ std::filesystem::remove(FilePath, Ec);
+ }
+}
+
+void
+BenchDiskSubCmd::PrefillRandFiles(const std::filesystem::path& Dir, bool DirectIo)
+{
+ // Write files sequentially with a large block size so the random I/O pass
+ // has data to work with. The write itself is not measured.
+ static constexpr uint64_t kPrefillBlock = 1024 * 1024;
+
+ uint64_t const EffectiveFileSize = DirectIo ? AlignUp(m_FileSize, kDirectIoAlignment) : m_FileSize;
+
+ std::vector<uint8_t> RawBuf(kPrefillBlock + kDirectIoAlignment - 1);
+ uint8_t* const WritePtr = AlignBuffer(RawBuf.data(), kDirectIoAlignment);
+ for (size_t i = 0; i < kPrefillBlock; ++i)
+ {
+ WritePtr[i] = static_cast<uint8_t>(i & 0xFF);
+ }
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&, i]() {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_rand_{}.tmp", i);
+ DirectIoFile File;
+ File.OpenWrite(FilePath, DirectIo);
+
+ uint64_t Remaining = EffectiveFileSize;
+ uint64_t Offset = 0;
+
+ while (Remaining > 0 && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ uint64_t WriteSize = std::min(kPrefillBlock, Remaining);
+ File.WriteAt(WritePtr, WriteSize, Offset);
+ Offset += WriteSize;
+ Remaining -= WriteSize;
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+}
+
+BenchDiskSubCmd::SeqResult
+BenchDiskSubCmd::RunRandWrite(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo)
+{
+ uint64_t const EffectiveFileSize = DirectIo ? AlignUp(m_FileSize, kDirectIoAlignment) : m_FileSize;
+ uint64_t const NumBlocks = EffectiveFileSize / BlockSize;
+
+ std::vector<uint8_t> RawBuf(BlockSize + kDirectIoAlignment - 1);
+ uint8_t* const WritePtr = AlignBuffer(RawBuf.data(), kDirectIoAlignment);
+ for (size_t i = 0; i < BlockSize; ++i)
+ {
+ WritePtr[i] = static_cast<uint8_t>(i & 0xFF);
+ }
+
+ std::atomic<int64_t> TotalBytesWritten{0};
+ std::atomic<int64_t> TotalOps{0};
+ std::atomic<int> ErrorCount{0};
+ std::atomic<int> DirectIoCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&, i]() {
+ std::mt19937_64 Rng(uint64_t(i) * 6364136223846793005ULL + 1442695040888963407ULL);
+ std::uniform_int_distribution<uint64_t> Dist(0, NumBlocks - 1);
+
+ try
+ {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_rand_{}.tmp", i);
+ DirectIoFile File;
+ bool GotDirect = File.OpenReadWrite(FilePath, DirectIo);
+
+ if (GotDirect)
+ {
+ DirectIoCount.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ int64_t LocalOps = 0;
+
+ for (int Op = 0; Op < m_RandOps && !s_BenchAbort.load(std::memory_order_relaxed); ++Op)
+ {
+ File.WriteAt(WritePtr, BlockSize, Dist(Rng) * BlockSize);
+ ++LocalOps;
+ }
+
+ TotalBytesWritten.fetch_add(LocalOps * static_cast<int64_t>(BlockSize), std::memory_order_relaxed);
+ TotalOps.fetch_add(LocalOps, std::memory_order_relaxed);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ SeqResult Result;
+ Result.ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ Result.BytesPerSec = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalBytesWritten.load() / Result.ElapsedSec) : 0;
+ Result.Iops = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalOps.load() / Result.ElapsedSec) : 0;
+ Result.ErrorCount = ErrorCount.load();
+ Result.UsedDirectIo = DirectIoCount.load() > 0;
+
+ return Result;
+}
+
+BenchDiskSubCmd::SeqResult
+BenchDiskSubCmd::RunRandRead(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo)
+{
+ uint64_t const EffectiveFileSize = DirectIo ? AlignUp(m_FileSize, kDirectIoAlignment) : m_FileSize;
+ uint64_t const NumBlocks = EffectiveFileSize / BlockSize;
+
+ std::atomic<int64_t> TotalBytesRead{0};
+ std::atomic<int64_t> TotalOps{0};
+ std::atomic<int> ErrorCount{0};
+ std::atomic<int> DirectIoCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&, i, BlockSize]() {
+ std::vector<uint8_t> RawBuf(BlockSize + kDirectIoAlignment - 1);
+ uint8_t* ReadPtr = AlignBuffer(RawBuf.data(), kDirectIoAlignment);
+ std::mt19937_64 Rng(uint64_t(i) * 6364136223846793005ULL + 1442695040888963407ULL);
+ std::uniform_int_distribution<uint64_t> Dist(0, NumBlocks - 1);
+
+ try
+ {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_rand_{}.tmp", i);
+ DirectIoFile File;
+ bool GotDirect = File.OpenRead(FilePath, DirectIo);
+
+ if (GotDirect)
+ {
+ DirectIoCount.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ int64_t LocalOps = 0;
+
+ for (int Op = 0; Op < m_RandOps && !s_BenchAbort.load(std::memory_order_relaxed); ++Op)
+ {
+ File.ReadAt(ReadPtr, BlockSize, Dist(Rng) * BlockSize);
+ ++LocalOps;
+ }
+
+ TotalBytesRead.fetch_add(LocalOps * static_cast<int64_t>(BlockSize), std::memory_order_relaxed);
+ TotalOps.fetch_add(LocalOps, std::memory_order_relaxed);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ SeqResult Result;
+ Result.ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ Result.BytesPerSec = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalBytesRead.load() / Result.ElapsedSec) : 0;
+ Result.Iops = Result.ElapsedSec > 0.0 ? static_cast<uint64_t>(TotalOps.load() / Result.ElapsedSec) : 0;
+ Result.ErrorCount = ErrorCount.load();
+ Result.UsedDirectIo = DirectIoCount.load() > 0;
+
+ return Result;
+}
+
+void
+BenchDiskSubCmd::CleanupRandFiles(const std::filesystem::path& Dir)
+{
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ std::error_code Ec;
+ std::filesystem::path FilePath = Dir / fmt::format("bench_rand_{}.tmp", i);
+ std::filesystem::remove(FilePath, Ec);
+ }
+}
+
+void
+BenchDiskSubCmd::CleanupFileOpFiles(const std::filesystem::path& Dir)
+{
+ for (int i = 0; i < m_FileCount; ++i)
+ {
+ std::error_code Ec;
+ std::filesystem::path FilePath = Dir / fmt::format("bench_fileop_{}.tmp", i);
+ std::filesystem::remove(FilePath, Ec);
+ }
+}
+
+void
+BenchDiskSubCmd::CleanupCloneFiles(const std::filesystem::path& Dir)
+{
+ std::error_code Ec;
+ std::filesystem::remove(Dir / "bench_clone_src.tmp", Ec);
+ for (int i = 0; i < m_FileCount; ++i)
+ {
+ std::filesystem::remove(Dir / fmt::format("bench_clone_{}.tmp", i), Ec);
+ }
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ std::filesystem::remove(Dir / fmt::format("bench_rangeclone_{}.tmp", i), Ec);
+ }
+}
+
+void
+BenchDiskSubCmd::RunFileOps(const std::filesystem::path& Dir)
+{
+ static constexpr uint64_t kSmallFileSize = 4 * 1024; // 4 KiB
+
+ std::vector<uint8_t> WriteBuffer(kSmallFileSize, 0xAB);
+
+ ZEN_CONSOLE("File Operations (4 KiB files, count={}, concurrency={})", m_FileCount, m_Concurrency);
+
+ // Create phase
+ {
+ std::atomic<int> NextFile{0};
+ std::atomic<int> ErrorCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&]() {
+ while (true)
+ {
+ int FileIndex = NextFile.fetch_add(1);
+
+ if (FileIndex >= m_FileCount || s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ break;
+ }
+
+ try
+ {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_fileop_{}.tmp", FileIndex);
+ BasicFile File(FilePath, BasicFile::Mode::kTruncate);
+ File.Write(WriteBuffer.data(), kSmallFileSize, 0);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ double ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ double FilesPerSec = ElapsedSec > 0.0 ? m_FileCount / ElapsedSec : 0.0;
+
+ ZEN_CONSOLE(" Create: {:.0f} files/s errors: {} (elapsed: {:.2f}s)", FilesPerSec, ErrorCount.load(), ElapsedSec);
+ }
+
+ // Delete phase
+ {
+ std::atomic<int> NextFile{0};
+ std::atomic<int> ErrorCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&]() {
+ while (true)
+ {
+ int FileIndex = NextFile.fetch_add(1);
+
+ if (FileIndex >= m_FileCount || s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ break;
+ }
+
+ try
+ {
+ std::filesystem::path FilePath = Dir / fmt::format("bench_fileop_{}.tmp", FileIndex);
+ std::filesystem::remove(FilePath);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ double ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ double FilesPerSec = ElapsedSec > 0.0 ? m_FileCount / ElapsedSec : 0.0;
+
+ ZEN_CONSOLE(" Delete: {:.0f} files/s errors: {} (elapsed: {:.2f}s)", FilesPerSec, ErrorCount.load(), ElapsedSec);
+ }
+}
+
+void
+BenchDiskSubCmd::RunClone(const std::filesystem::path& Dir)
+{
+ ZEN_CONSOLE("Block Clone (file-size={}, count={}, concurrency={})", NiceBytes(m_FileSize), m_FileCount, m_Concurrency);
+
+ std::unique_ptr<CloneQueryInterface> CloneIface = GetCloneQueryInterface(Dir);
+
+ if (!CloneIface)
+ {
+ ZEN_CONSOLE(" Skipped: block cloning not supported on this filesystem");
+ return;
+ }
+
+ // Write a source file used by both the file-clone and range-clone sub-tests
+ std::filesystem::path SrcPath = Dir / "bench_clone_src.tmp";
+ {
+ static constexpr uint64_t kWriteBlock = 1024 * 1024;
+ std::vector<uint8_t> WriteBuf(kWriteBlock, 0xCD);
+ BasicFile SrcFile(SrcPath, BasicFile::Mode::kTruncate);
+ uint64_t Remaining = m_FileSize;
+ uint64_t Offset = 0;
+ while (Remaining > 0)
+ {
+ uint64_t WriteSize = std::min(kWriteBlock, Remaining);
+ SrcFile.Write(WriteBuf.data(), WriteSize, Offset);
+ Offset += WriteSize;
+ Remaining -= WriteSize;
+ }
+ }
+
+ // == File Clone (whole-file CoW) ==
+ {
+ std::atomic<int> NextFile{0};
+ std::atomic<int> ErrorCount{0};
+ std::atomic<int> CloneCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&]() {
+ while (true)
+ {
+ int FileIndex = NextFile.fetch_add(1);
+
+ if (FileIndex >= m_FileCount || s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ break;
+ }
+
+ try
+ {
+ std::filesystem::path DstPath = Dir / fmt::format("bench_clone_{}.tmp", FileIndex);
+ if (TryCloneFile(SrcPath, DstPath))
+ {
+ CloneCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ else
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ double ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ int TotalClones = CloneCount.load();
+ double FilesPerSec = ElapsedSec > 0.0 ? TotalClones / ElapsedSec : 0.0;
+ double BytesPerSec = ElapsedSec > 0.0 ? TotalClones * static_cast<double>(m_FileSize) / ElapsedSec : 0.0;
+
+ ZEN_CONSOLE(" File Clone : {:.0f} files/s {}/s errors: {} (elapsed: {:.2f}s)",
+ FilesPerSec,
+ NiceBytes(static_cast<uint64_t>(BytesPerSec)),
+ ErrorCount.load(),
+ ElapsedSec);
+ }
+
+ if (s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ return;
+ }
+
+ // == Block Range Clone (sub-file FICLONERANGE / FSCTL_DUPLICATE_EXTENTS_TO_FILE) ==
+ //
+ // Measures how fast the filesystem can process individual range-clone operations.
+ // One shared source file is opened in the main thread; each worker thread opens its
+ // own destination file and issues m_RandOps FICLONERANGE calls at random aligned offsets.
+
+ // Pre-create per-thread destination files at full size so TryClone's ftruncate is a no-op
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ BasicFile DstFile(Dir / fmt::format("bench_rangeclone_{}.tmp", i), BasicFile::Mode::kTruncate);
+ DstFile.SetFileSize(m_FileSize);
+ }
+
+ BasicFile SrcFile(SrcPath, BasicFile::Mode::kRead);
+
+ ZEN_CONSOLE("");
+ ZEN_CONSOLE("Block Range Clone (rand-ops={:L}, concurrency={})", m_RandOps, m_Concurrency);
+ ZEN_CONSOLE(" {:>10} {:>12} {:>10}", "Block", "Ops/s", "Throughput");
+
+ for (uint64_t BlockSize : kDiskBenchBlockSizes)
+ {
+ if (s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ break;
+ }
+
+ uint64_t const NumBlocks = m_FileSize / BlockSize;
+ if (NumBlocks == 0)
+ {
+ continue;
+ }
+
+ std::atomic<int64_t> TotalOps{0};
+ std::atomic<int> ErrorCount{0};
+
+ Stopwatch Timer;
+
+ std::vector<std::thread> Threads;
+ Threads.reserve(m_Concurrency);
+
+ for (int i = 0; i < m_Concurrency; ++i)
+ {
+ Threads.emplace_back([&, i]() {
+ std::mt19937_64 Rng(uint64_t(i) * 6364136223846793005ULL + 1442695040888963407ULL);
+ std::uniform_int_distribution<uint64_t> Dist(0, NumBlocks - 1);
+
+ try
+ {
+ BasicFile DstFile(Dir / fmt::format("bench_rangeclone_{}.tmp", i), BasicFile::Mode::kWrite);
+ int64_t LocalOps = 0;
+
+ for (int Op = 0; Op < m_RandOps && !s_BenchAbort.load(std::memory_order_relaxed); ++Op)
+ {
+ uint64_t Offset = Dist(Rng) * BlockSize;
+ if (CloneIface->TryClone(SrcFile.Handle(), DstFile.Handle(), Offset, Offset, BlockSize, m_FileSize))
+ {
+ ++LocalOps;
+ }
+ else
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ }
+
+ TotalOps.fetch_add(LocalOps, std::memory_order_relaxed);
+ }
+ catch (const std::exception&)
+ {
+ ErrorCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ });
+ }
+
+ for (std::thread& T : Threads)
+ {
+ T.join();
+ }
+
+ double ElapsedSec = Timer.GetElapsedTimeMs() / 1000.0;
+ double OpsPerSec = ElapsedSec > 0.0 ? static_cast<double>(TotalOps.load()) / ElapsedSec : 0.0;
+ double ThroughputSec = OpsPerSec * static_cast<double>(BlockSize);
+
+ std::string ThroughputStr = ErrorCount.load() > 0
+ ? fmt::format("{}/s ({} err)", NiceBytes(static_cast<uint64_t>(ThroughputSec)), ErrorCount.load())
+ : fmt::format("{}/s", NiceBytes(static_cast<uint64_t>(ThroughputSec)));
+
+ ZEN_CONSOLE(" {:>10} {:>12L} {}", NiceBytes(BlockSize), static_cast<int64_t>(OpsPerSec), ThroughputStr);
+ }
+}
+
+void
+BenchDiskSubCmd::RunSync(const std::filesystem::path& Dir)
+{
+ // Each iteration writes one page to dirty it, then times a full fsync.
+ // Single-threaded; runs until the deadline rather than a fixed count.
+ static constexpr uint64_t kWriteSize = 4 * 1024; // bytes dirtied per sync
+ static constexpr uint64_t kFileSize = 4 * 1024 * 1024; // cycling window
+
+ ZEN_CONSOLE("Sync Latency (duration={}s, write={}/op)", m_SyncDurationSec, NiceBytes(kWriteSize));
+
+ std::filesystem::path FilePath = Dir / "bench_sync.tmp";
+ BasicFile File(FilePath, BasicFile::Mode::kTruncate);
+ File.SetFileSize(kFileSize);
+
+ static constexpr uint64_t kNumSlots = kFileSize / kWriteSize;
+ uint8_t WriteBuf[kWriteSize];
+ std::memset(WriteBuf, 0xEF, kWriteSize);
+
+ // Collect latencies in microseconds for sub-millisecond resolution
+ std::vector<uint64_t> LatenciesUs;
+
+ auto Deadline = std::chrono::steady_clock::now() + std::chrono::seconds(m_SyncDurationSec);
+ uint64_t SlotIndex = 0;
+ Stopwatch TotalTimer;
+
+ while (std::chrono::steady_clock::now() < Deadline && !s_BenchAbort.load(std::memory_order_relaxed))
+ {
+ File.Write(WriteBuf, kWriteSize, (SlotIndex % kNumSlots) * kWriteSize);
+ ++SlotIndex;
+
+ Stopwatch SyncTimer;
+ File.Flush();
+ LatenciesUs.push_back(SyncTimer.GetElapsedTimeUs());
+ }
+
+ double TotalElapsedSec = TotalTimer.GetElapsedTimeUs() / 1'000'000.0;
+
+ File.Close();
+
+ if (LatenciesUs.empty())
+ {
+ ZEN_CONSOLE(" No samples collected");
+ return;
+ }
+
+ std::sort(LatenciesUs.begin(), LatenciesUs.end());
+
+ auto PercentileMs = [&](double Pct) -> double {
+ size_t Index = std::min(static_cast<size_t>(LatenciesUs.size() * Pct / 100.0), LatenciesUs.size() - 1);
+ return LatenciesUs[Index] / 1000.0;
+ };
+
+ double SumUs = 0.0;
+ for (uint64_t L : LatenciesUs)
+ {
+ SumUs += static_cast<double>(L);
+ }
+ double MeanMs = SumUs / static_cast<double>(LatenciesUs.size()) / 1000.0;
+ double SyncsPs = TotalElapsedSec > 0.0 ? static_cast<double>(LatenciesUs.size()) / TotalElapsedSec : 0.0;
+
+ ZEN_CONSOLE(" Count : {:L} syncs ({:.1f} syncs/s)", LatenciesUs.size(), SyncsPs);
+ ZEN_CONSOLE(" Latency: min={:.3f}ms mean={:.3f}ms p50={:.3f}ms p95={:.3f}ms p99={:.3f}ms max={:.3f}ms",
+ LatenciesUs.front() / 1000.0,
+ MeanMs,
+ PercentileMs(50),
+ PercentileMs(95),
+ PercentileMs(99),
+ LatenciesUs.back() / 1000.0);
+}
+
+void
+BenchDiskSubCmd::CleanupSyncFiles(const std::filesystem::path& Dir)
+{
+ std::error_code Ec;
+ std::filesystem::remove(Dir / "bench_sync.tmp", Ec);
+}
+
+//////////////////////////////////////////////////////////////////////////
// BenchCommand
BenchCommand::BenchCommand()
@@ -498,6 +1878,7 @@ BenchCommand::BenchCommand()
AddSubCommand(m_PurgeSubCmd);
AddSubCommand(m_HttpSubCmd);
+ AddSubCommand(m_DiskSubCmd);
}
BenchCommand::~BenchCommand() = default;
diff --git a/src/zen/cmds/bench_cmd.h b/src/zen/cmds/bench_cmd.h
index 6700ee410..96f0c9616 100644
--- a/src/zen/cmds/bench_cmd.h
+++ b/src/zen/cmds/bench_cmd.h
@@ -4,6 +4,8 @@
#include "../zen.h"
+#include <filesystem>
+
namespace zen {
class BenchPurgeSubCmd : public ZenSubCmdBase
@@ -35,6 +37,46 @@ private:
bool m_Continuous = false;
};
+class BenchDiskSubCmd : public ZenSubCmdBase
+{
+public:
+ BenchDiskSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ struct SeqResult
+ {
+ uint64_t BytesPerSec = 0;
+ uint64_t Iops = 0;
+ double ElapsedSec = 0.0;
+ int ErrorCount = 0;
+ bool UsedDirectIo = false;
+ };
+
+ SeqResult RunSeqWrite(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo);
+ SeqResult RunSeqRead(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo);
+ SeqResult RunRandWrite(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo);
+ SeqResult RunRandRead(const std::filesystem::path& Dir, uint64_t BlockSize, bool DirectIo);
+ void PrefillRandFiles(const std::filesystem::path& Dir, bool DirectIo);
+ void RunFileOps(const std::filesystem::path& Dir);
+ void RunClone(const std::filesystem::path& Dir);
+ void CleanupSeqFiles(const std::filesystem::path& Dir);
+ void CleanupRandFiles(const std::filesystem::path& Dir);
+ void CleanupFileOpFiles(const std::filesystem::path& Dir);
+ void CleanupCloneFiles(const std::filesystem::path& Dir);
+ void RunSync(const std::filesystem::path& Dir);
+ void CleanupSyncFiles(const std::filesystem::path& Dir);
+
+ std::string m_Path;
+ std::string m_Run = "seq,rand,ops,clone";
+ int m_SyncDurationSec = 10;
+ int m_Concurrency = 1;
+ uint64_t m_FileSize = 256 * 1024 * 1024;
+ int m_FileCount = 1000;
+ int m_RandOps = 10000;
+ bool m_NoDirectIo = false;
+};
+
class BenchCommand : public ZenCmdWithSubCommands
{
public:
@@ -52,6 +94,7 @@ private:
std::string m_SubCommand;
BenchPurgeSubCmd m_PurgeSubCmd;
BenchHttpSubCmd m_HttpSubCmd;
+ BenchDiskSubCmd m_DiskSubCmd;
};
} // namespace zen
diff --git a/src/zen/cmds/builds_cmd.cpp b/src/zen/cmds/builds_cmd.cpp
index 93108dd47..cc8315e0b 100644
--- a/src/zen/cmds/builds_cmd.cpp
+++ b/src/zen/cmds/builds_cmd.cpp
@@ -1784,6 +1784,7 @@ namespace builds_impl {
{
OptionalStructuredOutput->AddString("path"sv, fmt::format("{}", Path));
OptionalStructuredOutput->AddInteger("rawSize"sv, RawSize);
+ OptionalStructuredOutput->AddHash("rawHash"sv, RawHash);
switch (Platform)
{
case SourcePlatform::Windows:
diff --git a/src/zen/cmds/exec_cmd.cpp b/src/zen/cmds/exec_cmd.cpp
index 30e860a3f..9719fce77 100644
--- a/src/zen/cmds/exec_cmd.cpp
+++ b/src/zen/cmds/exec_cmd.cpp
@@ -1119,6 +1119,7 @@ ExecHttpSubCmd::Run(const ZenCliOptions& /*GlobalOptions*/)
ExecInprocSubCmd::ExecInprocSubCmd(ExecCommand& Parent) : ZenSubCmdBase("inproc", "Handle execution in-process"), m_Parent(Parent)
{
+ m_SubOptions.add_option("managed", "", "managed", "Use managed local runner (if supported)", cxxopts::value(m_Managed), "<bool>");
}
void
@@ -1130,7 +1131,16 @@ ExecInprocSubCmd::Run(const ZenCliOptions& /*GlobalOptions*/)
zen::compute::ComputeServiceSession ComputeSession(Resolver);
std::filesystem::path TempPath = std::filesystem::absolute(".zen_temp");
- ComputeSession.AddLocalRunner(Resolver, TempPath);
+ if (m_Managed)
+ {
+ ZEN_CONSOLE_INFO("using managed local runner");
+ ComputeSession.AddManagedLocalRunner(Resolver, TempPath);
+ }
+ else
+ {
+ ZEN_CONSOLE_INFO("using local runner");
+ ComputeSession.AddLocalRunner(Resolver, TempPath);
+ }
Stopwatch ExecTimer;
int ReturnValue = m_Parent.RunSession(ComputeSession);
diff --git a/src/zen/cmds/exec_cmd.h b/src/zen/cmds/exec_cmd.h
index c55412780..a0bf201a1 100644
--- a/src/zen/cmds/exec_cmd.h
+++ b/src/zen/cmds/exec_cmd.h
@@ -61,6 +61,7 @@ public:
private:
ExecCommand& m_Parent;
+ bool m_Managed = false;
};
class ExecBeaconSubCmd : public ZenSubCmdBase
diff --git a/src/zen/cmds/hub_cmd.cpp b/src/zen/cmds/hub_cmd.cpp
new file mode 100644
index 000000000..5bdd3a922
--- /dev/null
+++ b/src/zen/cmds/hub_cmd.cpp
@@ -0,0 +1,440 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "hub_cmd.h"
+
+#include <zencore/compactbinary.h>
+#include <zencore/compactbinaryutil.h>
+#include <zencore/filesystem.h>
+#include <zencore/fmtutils.h>
+#include <zencore/iobuffer.h>
+#include <zencore/logging.h>
+#include <zencore/process.h>
+#include <zenhttp/httpclient.h>
+#include <zenutil/zenserverprocess.h>
+
+#include <vector>
+
+namespace zen {
+
+//////////////////////////////////////////////////////////////////////////
+// HubUpSubCmd
+
+HubUpSubCmd::HubUpSubCmd() : ZenSubCmdBase("up", "Bring hub server up")
+{
+ SubOptions().add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("0"), "<hostport>");
+ SubOptions().add_option("", "b", "base-dir", "Parent folder of server executable", cxxopts::value(m_ProgramBaseDir), "<directory>");
+ SubOptions().add_option("", "c", "show-console", "Open a console window for the zenserver process", cxxopts::value(m_ShowConsole), "");
+ SubOptions().add_option("",
+ "l",
+ "show-log",
+ "Show the output log of the zenserver process after successful start",
+ cxxopts::value(m_ShowLog),
+ "");
+}
+
+void
+HubUpSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ if (m_ShowConsole && m_ShowLog)
+ {
+ throw OptionParseException("'--show-console' conflicts with '--show-log'", SubOptions().help());
+ }
+
+ std::optional<int> StartResult = StartupZenServer(ConsoleLog(),
+ {.ProgramBaseDir = m_ProgramBaseDir,
+ .Port = m_Port,
+ .OpenConsole = m_ShowConsole,
+ .ShowLog = m_ShowLog,
+ .ExtraArgs = GlobalOptions.PassthroughCommandLine,
+ .Mode = ZenServerInstance::ServerMode::kHubServer});
+ if (!StartResult.has_value())
+ {
+ ZEN_CONSOLE("Zen server already running");
+ return;
+ }
+ if (*StartResult != 0)
+ {
+ throw ErrorWithReturnCode("Zen server failed to start", *StartResult);
+ }
+
+ ZEN_CONSOLE("Zen server up");
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubDownSubCmd
+
+HubDownSubCmd::HubDownSubCmd() : ZenSubCmdBase("down", "Bring hub server down")
+{
+ SubOptions().add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("0"), "<hostport>");
+ SubOptions().add_option("", "a", "all", "Shut down all running zen server instances", cxxopts::value(m_All), "");
+ SubOptions().add_option("", "f", "force", "Force terminate if graceful shutdown fails", cxxopts::value(m_ForceTerminate), "<force>");
+ SubOptions().add_option("", "b", "base-dir", "Parent folder of server executable", cxxopts::value(m_ProgramBaseDir), "<directory>");
+ SubOptions()
+ .add_option("", "", "data-dir", "Path to data directory to inspect for running server", cxxopts::value(m_DataDir), "<file>");
+}
+
+void
+HubDownSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ if (m_ProgramBaseDir.empty())
+ {
+ m_ProgramBaseDir = GetRunningExecutablePath().parent_path();
+ }
+
+ ZenServerState Instance;
+ Instance.Initialize();
+
+ if (m_All)
+ {
+ struct EntryInfo
+ {
+ uint16_t Port = 0;
+ uint32_t Pid = 0;
+ };
+ std::vector<EntryInfo> Entries;
+ Instance.Snapshot([&Entries](const ZenServerState::ZenServerEntry& Entry) {
+ uint16_t Port = Entry.DesiredListenPort.load();
+ uint32_t Pid = Entry.Pid.load();
+ if (Port != 0 && Pid != 0)
+ {
+ Entries.push_back({Port, Pid});
+ }
+ });
+
+ if (Entries.empty())
+ {
+ ZEN_CONSOLE("No zen server instances to bring down");
+ return;
+ }
+
+ int FailCount = 0;
+ for (const EntryInfo& Info : Entries)
+ {
+ Instance.Sweep();
+ ZenServerState::ZenServerEntry* Entry = Instance.Lookup(Info.Port);
+ if (Entry && Entry->Pid.load() == Info.Pid)
+ {
+ if (!ShutdownZenServer(ConsoleLog(), Instance, Entry, m_ProgramBaseDir))
+ {
+ ZEN_CONSOLE_WARN("Failed to shutdown server on port {} (pid {})", Info.Port, Info.Pid);
+ ++FailCount;
+ }
+ }
+ }
+
+ if (FailCount > 0 && !m_ForceTerminate)
+ {
+ throw std::runtime_error(fmt::format("Failed to shutdown {} instance(s), use --force to hard terminate", FailCount));
+ }
+ return;
+ }
+
+ ZenServerState::ZenServerEntry* Entry = Instance.Lookup(m_Port);
+
+ if (!m_DataDir.empty())
+ {
+ if (!IsFile(m_DataDir / ".lock"))
+ {
+ throw std::runtime_error(fmt::format("Lock file does not exist in directory '{}'", m_DataDir));
+ }
+ CbValidateError ValidateResult = CbValidateError::None;
+ if (CbObject LockFileObject =
+ ValidateAndReadCompactBinaryObject(IoBufferBuilder::MakeFromFile(m_DataDir / ".lock"), ValidateResult);
+ ValidateResult == CbValidateError::None && LockFileObject)
+ {
+ LockFileInfo Info = ReadLockFilePayload(LockFileObject);
+ std::string Reason;
+ if (!ValidateLockFileInfo(Info, Reason))
+ {
+ throw std::runtime_error(fmt::format("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason));
+ }
+ Entry = Instance.LookupByEffectivePort(Info.EffectiveListenPort);
+ }
+ else
+ {
+ throw std::runtime_error(
+ fmt::format("Lock file in directory '{}' is malformed. Reason: '{}'", m_DataDir, ToString(ValidateResult)));
+ }
+ }
+
+ if (Entry)
+ {
+ if (ShutdownZenServer(ConsoleLog(), Instance, Entry, m_ProgramBaseDir))
+ {
+ return;
+ }
+ }
+
+ if (m_ForceTerminate)
+ {
+ std::filesystem::path ServerExePath = m_ProgramBaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL;
+ ProcessHandle RunningProcess;
+ if (std::error_code Ec = FindProcess(ServerExePath, RunningProcess, /*IncludeSelf*/ false); !Ec)
+ {
+ ZEN_CONSOLE_WARN("Attempting hard terminate of zen process with pid ({})", RunningProcess.Pid());
+ if (RunningProcess.Terminate(0))
+ {
+ ZEN_CONSOLE("Terminate complete");
+ return;
+ }
+ throw std::runtime_error("Failed to terminate server, still running");
+ }
+ else
+ {
+ ZEN_CONSOLE_WARN("Failed to find process '{}', reason: {}", ServerExePath.string(), Ec.message());
+ }
+ }
+ else if (Entry)
+ {
+ throw std::runtime_error(
+ fmt::format("Failed to shutdown server on port {}, use --force to hard terminate process", Entry->DesiredListenPort.load()));
+ }
+
+ ZEN_CONSOLE("No zen server to bring down");
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubProvisionSubCmd
+
+HubProvisionSubCmd::HubProvisionSubCmd() : ZenSubCmdBase("provision", "Provision a hub module instance")
+{
+ SubOptions().add_option("", "u", "hosturl", ZenCmdBase::kHostUrlHelp, cxxopts::value(m_HostName)->default_value(""), "<hosturl>");
+ SubOptions().add_option("", "", "moduleid", "Module ID to provision", cxxopts::value(m_ModuleId)->default_value(""), "<moduleid>");
+ SubOptions().parse_positional({"moduleid"});
+}
+
+void
+HubProvisionSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ m_HostName = ZenCmdBase::ResolveTargetHostSpec(m_HostName);
+ if (m_HostName.empty())
+ {
+ throw OptionParseException("Unable to resolve hub host specification", SubOptions().help());
+ }
+ if (m_ModuleId.empty())
+ {
+ throw OptionParseException("moduleid is required", SubOptions().help());
+ }
+
+ HttpClient Http = ZenCmdBase::CreateHttpClient(m_HostName);
+ if (HttpClient::Response Resp =
+ Http.Post(fmt::format("/hub/modules/{}/provision", m_ModuleId), HttpClient::KeyValueMap{}, HttpClient::KeyValueMap{}))
+ {
+ CbObject Obj = Resp.AsObject();
+ std::string_view Id = Obj["moduleId"].AsString();
+ std::string_view Uri = Obj["baseUri"].AsString();
+ uint16_t Port = Obj["port"].AsUInt16();
+ ZEN_CONSOLE("module '{}' provisioned: {} (port {})", Id, Uri, Port);
+ }
+ else
+ {
+ Resp.ThrowError("Provision failed");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubDeprovisionSubCmd
+
+HubDeprovisionSubCmd::HubDeprovisionSubCmd() : ZenSubCmdBase("deprovision", "Deprovision a hub module instance")
+{
+ SubOptions().add_option("", "u", "hosturl", ZenCmdBase::kHostUrlHelp, cxxopts::value(m_HostName)->default_value(""), "<hosturl>");
+ SubOptions().add_option("", "", "moduleid", "Module ID to deprovision", cxxopts::value(m_ModuleId)->default_value(""), "<moduleid>");
+ SubOptions().parse_positional({"moduleid"});
+}
+
+void
+HubDeprovisionSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ m_HostName = ZenCmdBase::ResolveTargetHostSpec(m_HostName);
+ if (m_HostName.empty())
+ {
+ throw OptionParseException("Unable to resolve hub host specification", SubOptions().help());
+ }
+ if (m_ModuleId.empty())
+ {
+ throw OptionParseException("moduleid is required", SubOptions().help());
+ }
+
+ HttpClient Http = ZenCmdBase::CreateHttpClient(m_HostName);
+ if (HttpClient::Response Resp =
+ Http.Post(fmt::format("/hub/modules/{}/deprovision", m_ModuleId), HttpClient::KeyValueMap{}, HttpClient::KeyValueMap{}))
+ {
+ CbObject Obj = Resp.AsObject();
+ std::string_view Id = Obj["moduleId"].AsString();
+ ZEN_CONSOLE("module '{}' deprovisioned", Id);
+ }
+ else
+ {
+ Resp.ThrowError("Deprovision failed");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubHibernateSubCmd
+
+HubHibernateSubCmd::HubHibernateSubCmd() : ZenSubCmdBase("hibernate", "Hibernate a hub module instance")
+{
+ SubOptions().add_option("", "u", "hosturl", ZenCmdBase::kHostUrlHelp, cxxopts::value(m_HostName)->default_value(""), "<hosturl>");
+ SubOptions().add_option("", "", "moduleid", "Module ID to hibernate", cxxopts::value(m_ModuleId)->default_value(""), "<moduleid>");
+ SubOptions().parse_positional({"moduleid"});
+}
+
+void
+HubHibernateSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ m_HostName = ZenCmdBase::ResolveTargetHostSpec(m_HostName);
+ if (m_HostName.empty())
+ {
+ throw OptionParseException("Unable to resolve hub host specification", SubOptions().help());
+ }
+ if (m_ModuleId.empty())
+ {
+ throw OptionParseException("moduleid is required", SubOptions().help());
+ }
+
+ HttpClient Http = ZenCmdBase::CreateHttpClient(m_HostName);
+ if (HttpClient::Response Resp =
+ Http.Post(fmt::format("/hub/modules/{}/hibernate", m_ModuleId), HttpClient::KeyValueMap{}, HttpClient::KeyValueMap{}))
+ {
+ CbObject Obj = Resp.AsObject();
+ std::string_view Id = Obj["moduleId"].AsString();
+ ZEN_CONSOLE("module '{}' hibernated", Id);
+ }
+ else
+ {
+ Resp.ThrowError("Hibernate failed");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubWakeSubCmd
+
+HubWakeSubCmd::HubWakeSubCmd() : ZenSubCmdBase("wake", "Wake a hibernated hub module instance")
+{
+ SubOptions().add_option("", "u", "hosturl", ZenCmdBase::kHostUrlHelp, cxxopts::value(m_HostName)->default_value(""), "<hosturl>");
+ SubOptions().add_option("", "", "moduleid", "Module ID to wake", cxxopts::value(m_ModuleId)->default_value(""), "<moduleid>");
+ SubOptions().parse_positional({"moduleid"});
+}
+
+void
+HubWakeSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ m_HostName = ZenCmdBase::ResolveTargetHostSpec(m_HostName);
+ if (m_HostName.empty())
+ {
+ throw OptionParseException("Unable to resolve hub host specification", SubOptions().help());
+ }
+ if (m_ModuleId.empty())
+ {
+ throw OptionParseException("moduleid is required", SubOptions().help());
+ }
+
+ HttpClient Http = ZenCmdBase::CreateHttpClient(m_HostName);
+ if (HttpClient::Response Resp =
+ Http.Post(fmt::format("/hub/modules/{}/wake", m_ModuleId), HttpClient::KeyValueMap{}, HttpClient::KeyValueMap{}))
+ {
+ CbObject Obj = Resp.AsObject();
+ std::string_view Id = Obj["moduleId"].AsString();
+ ZEN_CONSOLE("module '{}' woken", Id);
+ }
+ else
+ {
+ Resp.ThrowError("Wake failed");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubStatusSubCmd
+
+HubStatusSubCmd::HubStatusSubCmd() : ZenSubCmdBase("status", "Show status of hub module instances")
+{
+ SubOptions().add_option("", "u", "hosturl", ZenCmdBase::kHostUrlHelp, cxxopts::value(m_HostName)->default_value(""), "<hosturl>");
+ SubOptions()
+ .add_option("", "", "moduleid", "Module ID (omit to list all)", cxxopts::value(m_ModuleId)->default_value(""), "<moduleid>");
+ SubOptions().parse_positional({"moduleid"});
+}
+
+void
+HubStatusSubCmd::Run(const ZenCliOptions& GlobalOptions)
+{
+ ZEN_UNUSED(GlobalOptions);
+
+ m_HostName = ZenCmdBase::ResolveTargetHostSpec(m_HostName);
+ if (m_HostName.empty())
+ {
+ throw OptionParseException("Unable to resolve hub host specification", SubOptions().help());
+ }
+
+ HttpClient Http = ZenCmdBase::CreateHttpClient(m_HostName);
+
+ if (!m_ModuleId.empty())
+ {
+ if (HttpClient::Response Resp = Http.Get(fmt::format("/hub/modules/{}", m_ModuleId)))
+ {
+ CbObject Obj = Resp.AsObject();
+ std::string_view Id = Obj["moduleId"].AsString();
+ std::string_view State = Obj["state"].AsString();
+ ZEN_CONSOLE("module '{}': {}", Id, State);
+ }
+ else
+ {
+ Resp.ThrowError("Status query failed");
+ }
+ }
+ else
+ {
+ if (HttpClient::Response Resp = Http.Get("/hub/status"))
+ {
+ CbObject Obj = Resp.AsObject();
+ CbArrayView Modules = Obj["modules"].AsArrayView();
+ if (Modules.Num() == 0)
+ {
+ ZEN_CONSOLE("No modules");
+ }
+ else
+ {
+ for (CbFieldView Module : Modules)
+ {
+ CbObjectView ModObj = Module.AsObjectView();
+ ZEN_CONSOLE("module '{}': {}", ModObj["moduleId"].AsString(), ModObj["state"].AsString());
+ }
+ }
+ }
+ else
+ {
+ Resp.ThrowError("Status query failed");
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// HubCommand
+
+HubCommand::HubCommand()
+{
+ m_Options.add_options()("h,help", "Print help");
+ m_Options.add_option("__hidden__", "", "subcommand", "", cxxopts::value<std::string>(m_SubCommand)->default_value(""), "");
+ m_Options.parse_positional({"subcommand"});
+
+ AddSubCommand(m_UpSubCmd);
+ AddSubCommand(m_DownSubCmd);
+ AddSubCommand(m_ProvisionSubCmd);
+ AddSubCommand(m_DeprovisionSubCmd);
+ AddSubCommand(m_HibernateSubCmd);
+ AddSubCommand(m_WakeSubCmd);
+ AddSubCommand(m_StatusSubCmd);
+}
+
+HubCommand::~HubCommand() = default;
+
+} // namespace zen
diff --git a/src/zen/cmds/hub_cmd.h b/src/zen/cmds/hub_cmd.h
new file mode 100644
index 000000000..e3da1ee42
--- /dev/null
+++ b/src/zen/cmds/hub_cmd.h
@@ -0,0 +1,118 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "../zen.h"
+
+#include <filesystem>
+#include <string>
+
+namespace zen {
+
+class HubUpSubCmd : public ZenSubCmdBase
+{
+public:
+ HubUpSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ uint16_t m_Port = 0;
+ bool m_ShowConsole = false;
+ bool m_ShowLog = false;
+ std::filesystem::path m_ProgramBaseDir;
+};
+
+class HubDownSubCmd : public ZenSubCmdBase
+{
+public:
+ HubDownSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ uint16_t m_Port = 0;
+ bool m_All = false;
+ bool m_ForceTerminate = false;
+ std::filesystem::path m_ProgramBaseDir;
+ std::filesystem::path m_DataDir;
+};
+
+class HubProvisionSubCmd : public ZenSubCmdBase
+{
+public:
+ HubProvisionSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ std::string m_HostName;
+ std::string m_ModuleId;
+};
+
+class HubDeprovisionSubCmd : public ZenSubCmdBase
+{
+public:
+ HubDeprovisionSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ std::string m_HostName;
+ std::string m_ModuleId;
+};
+
+class HubHibernateSubCmd : public ZenSubCmdBase
+{
+public:
+ HubHibernateSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ std::string m_HostName;
+ std::string m_ModuleId;
+};
+
+class HubWakeSubCmd : public ZenSubCmdBase
+{
+public:
+ HubWakeSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ std::string m_HostName;
+ std::string m_ModuleId;
+};
+
+class HubStatusSubCmd : public ZenSubCmdBase
+{
+public:
+ HubStatusSubCmd();
+ void Run(const ZenCliOptions& GlobalOptions) override;
+
+private:
+ std::string m_HostName;
+ std::string m_ModuleId;
+};
+
+class HubCommand : public ZenCmdWithSubCommands
+{
+public:
+ static constexpr char Name[] = "hub";
+ static constexpr char Description[] = "Manage zen hub server and its module instances";
+
+ HubCommand();
+ ~HubCommand();
+
+ cxxopts::Options& Options() override { return m_Options; }
+ ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
+
+private:
+ cxxopts::Options m_Options{Name, Description};
+ std::string m_SubCommand;
+ HubUpSubCmd m_UpSubCmd;
+ HubDownSubCmd m_DownSubCmd;
+ HubProvisionSubCmd m_ProvisionSubCmd;
+ HubDeprovisionSubCmd m_DeprovisionSubCmd;
+ HubHibernateSubCmd m_HibernateSubCmd;
+ HubWakeSubCmd m_WakeSubCmd;
+ HubStatusSubCmd m_StatusSubCmd;
+};
+
+} // namespace zen
diff --git a/src/zen/cmds/up_cmd.cpp b/src/zen/cmds/up_cmd.cpp
index db2c77b6b..809a41bb6 100644
--- a/src/zen/cmds/up_cmd.cpp
+++ b/src/zen/cmds/up_cmd.cpp
@@ -8,25 +8,21 @@
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zencore/process.h>
-#include <zencore/timer.h>
#include <zenutil/zenserverprocess.h>
-#include <memory>
-
namespace zen {
UpCommand::UpCommand()
{
m_Options.add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("0"), "<hostport>");
m_Options.add_option("", "b", "base-dir", "Parent folder of server executable", cxxopts::value(m_ProgramBaseDir), "<directory>");
- m_Options
- .add_option("", "c", "show-console", "Open a console window for the zenserver process", cxxopts::value(m_ShowConsole), "<console>");
+ m_Options.add_option("", "c", "show-console", "Open a console window for the zenserver process", cxxopts::value(m_ShowConsole), "");
m_Options.add_option("",
"l",
"show-log",
"Show the output log of the zenserver process after successful start",
cxxopts::value(m_ShowLog),
- "<showlog>");
+ "");
}
UpCommand::~UpCommand() = default;
@@ -34,10 +30,6 @@ UpCommand::~UpCommand() = default;
void
UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
- using namespace std::literals;
-
- ZEN_UNUSED(GlobalOptions);
-
if (!ParseOptions(argc, argv))
{
return;
@@ -45,91 +37,26 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (m_ShowConsole && m_ShowLog)
{
- throw OptionParseException("'--show-console' conficts with '--show-log'", m_Options.help());
- }
-
- {
- ZenServerState State;
- if (State.InitializeReadOnly())
- {
- struct EntryInfo
- {
- uint32_t Pid = 0;
- uint16_t DesiredPort = 0;
- uint16_t EffectivePort = 0;
- };
- std::vector<EntryInfo> RunningEntries;
- State.Snapshot([&RunningEntries, DesiredPort = this->m_Port](const zen::ZenServerState::ZenServerEntry& Entry) {
- if (DesiredPort == 0 || Entry.DesiredListenPort.load() == DesiredPort)
- {
- RunningEntries.push_back(EntryInfo{.Pid = Entry.Pid.load(),
- .DesiredPort = Entry.DesiredListenPort.load(),
- .EffectivePort = Entry.EffectiveListenPort.load()});
- }
- });
- if (RunningEntries.size() > 0)
- {
- ZEN_CONSOLE("Zen server already running with base port {}. First instance at port {}, pid {}",
- RunningEntries[0].DesiredPort,
- RunningEntries[0].EffectivePort,
- RunningEntries[0].Pid);
- return;
- }
- }
+ throw OptionParseException("'--show-console' conflicts with '--show-log'", m_Options.help());
}
- if (m_ProgramBaseDir.empty())
+ std::optional<int> StartResult = StartupZenServer(ConsoleLog(),
+ {.ProgramBaseDir = m_ProgramBaseDir,
+ .Port = m_Port,
+ .OpenConsole = m_ShowConsole,
+ .ShowLog = m_ShowLog,
+ .ExtraArgs = GlobalOptions.PassthroughCommandLine});
+ if (!StartResult.has_value())
{
- std::filesystem::path ExePath = zen::GetRunningExecutablePath();
- m_ProgramBaseDir = ExePath.parent_path();
+ ZEN_CONSOLE("Zen server already running");
+ return;
}
- ZenServerEnvironment ServerEnvironment;
- ServerEnvironment.Initialize(m_ProgramBaseDir);
- ZenServerInstance Server(ServerEnvironment);
- std::string ServerArguments = GlobalOptions.PassthroughCommandLine;
- if ((m_Port != 0) && (ServerArguments.find("--port"sv) == std::string::npos))
+ if (*StartResult != 0)
{
- ServerArguments.append(fmt::format(" --port {}", m_Port));
+ throw ErrorWithReturnCode("Zen server failed to start", *StartResult);
}
- Server.SpawnServer(ServerArguments, m_ShowConsole, /*WaitTimeoutMs*/ 0);
- int Timeout = 10000;
-
- if (!Server.WaitUntilReady(Timeout))
- {
- if (Server.IsRunning())
- {
- ZEN_CONSOLE_WARN("Zen server launch failed (timed out), terminating");
- Server.Terminate();
- if (!m_ShowConsole)
- {
- ZEN_CONSOLE("{}", Server.GetLogOutput());
- }
- throw std::runtime_error("Zen server launch failed (timed out), launched process was terminated");
- }
- int ServerExitCode = Server.Shutdown();
- if (!m_ShowConsole)
- {
- ZEN_CONSOLE("{}", Server.GetLogOutput());
- }
- if (ServerExitCode != 0)
- {
- throw ErrorWithReturnCode(
- fmt::format("Zen server failed to get to a ready state and exited with return code {}", ServerExitCode),
- ServerExitCode);
- }
- }
- else
- {
- if (m_ShowLog)
- {
- ZEN_CONSOLE("{}", Server.GetLogOutput());
- }
- else
- {
- ZEN_CONSOLE("Zen server up");
- }
- }
+ ZEN_CONSOLE("Zen server up");
}
//////////////////////////////////////////////////////////////////////////
@@ -211,70 +138,6 @@ DownCommand::DownCommand()
DownCommand::~DownCommand() = default;
-bool
-DownCommand::ShutdownEntry(ZenServerState& Instance, ZenServerState::ZenServerEntry* Entry)
-{
- int EntryPort = (int)Entry->DesiredListenPort.load();
- const uint32_t ServerProcessPid = Entry->Pid.load();
- try
- {
- ZenServerEnvironment ServerEnvironment;
- ServerEnvironment.Initialize(m_ProgramBaseDir);
- ZenServerInstance Server(ServerEnvironment);
- Server.AttachToRunningServer(EntryPort);
-
- ZEN_CONSOLE("attached to server on port {} (pid {}), requesting shutdown", EntryPort, ServerProcessPid);
-
- std::error_code Ec;
- if (Server.SignalShutdown(Ec) && !Ec)
- {
- Stopwatch Timer;
- while (Timer.GetElapsedTimeMs() < 10000)
- {
- if (Server.WaitUntilExited(100, Ec) && !Ec)
- {
- ZEN_CONSOLE("shutdown complete");
- return true;
- }
- else if (Ec)
- {
- ZEN_CONSOLE("Waiting for server on port {} (pid {}) failed. Reason: '{}'", EntryPort, ServerProcessPid, Ec.message());
- }
- }
- }
- else if (Ec)
- {
- ZEN_CONSOLE_WARN("Requesting shutdown of server on port {} failed. Reason: '{}'", EntryPort, Ec.message());
- }
- }
- catch (const std::exception& Ex)
- {
- ZEN_DEBUG("Exception caught when requesting shutdown: {}", Ex.what());
- }
-
- // Since we cannot obtain a handle to the process we are unable to block on the process
- // handle to determine when the server has shut down. Thus we signal that we would like
- // a shutdown via the shutdown flag and the check if the entry is still running.
-
- ZEN_CONSOLE("Requesting detached shutdown of server on port {}", EntryPort);
- Entry->SignalShutdownRequest();
-
- Stopwatch Timer;
- while (Timer.GetElapsedTimeMs() < 10000)
- {
- Instance.Sweep();
- Entry = Instance.Lookup(EntryPort);
- if (Entry == nullptr || Entry->Pid.load() != ServerProcessPid)
- {
- ZEN_CONSOLE("Shutdown complete");
- return true;
- }
- Sleep(100);
- }
-
- return false;
-}
-
void
DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
@@ -325,7 +188,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ZenServerState::ZenServerEntry* Entry = Instance.Lookup(Info.Port);
if (Entry && Entry->Pid.load() == Info.Pid)
{
- if (!ShutdownEntry(Instance, Entry))
+ if (!ShutdownZenServer(ConsoleLog(), Instance, Entry, m_ProgramBaseDir))
{
ZEN_CONSOLE_WARN("Failed to shutdown server on port {} (pid {})", Info.Port, Info.Pid);
++FailCount;
@@ -370,7 +233,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (Entry)
{
- if (ShutdownEntry(Instance, Entry))
+ if (ShutdownZenServer(ConsoleLog(), Instance, Entry, m_ProgramBaseDir))
{
return;
}
@@ -381,7 +244,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
// Try to find the running executable by path name
std::filesystem::path ServerExePath = m_ProgramBaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL;
ProcessHandle RunningProcess;
- if (std::error_code Ec = FindProcess(ServerExePath, RunningProcess); !Ec, /*IncludeSelf*/ false)
+ if (std::error_code Ec = FindProcess(ServerExePath, RunningProcess, /*IncludeSelf*/ false); !Ec)
{
ZEN_CONSOLE_WARN("Attempting hard terminate of zen process with pid ({})", RunningProcess.Pid());
if (RunningProcess.Terminate(0))
@@ -399,7 +262,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else if (Entry)
{
throw std::runtime_error(
- fmt::format("Failed to shutdown of server on port {}, use --force to hard terminate process", Entry->DesiredListenPort.load()));
+ fmt::format("Failed to shut down server on port {}, use --force to hard terminate process", Entry->DesiredListenPort.load()));
}
ZEN_CONSOLE("No zen server to bring down");
diff --git a/src/zen/cmds/up_cmd.h b/src/zen/cmds/up_cmd.h
index c88ce6bb9..f904fe0d9 100644
--- a/src/zen/cmds/up_cmd.h
+++ b/src/zen/cmds/up_cmd.h
@@ -62,8 +62,6 @@ public:
virtual cxxopts::Options& Options() override { return m_Options; }
private:
- bool ShutdownEntry(ZenServerState& Instance, ZenServerState::ZenServerEntry* Entry);
-
cxxopts::Options m_Options{Name, Description};
uint16_t m_Port = 0;
bool m_All = false;
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp
index 91cdca4a2..3277eb856 100644
--- a/src/zen/zen.cpp
+++ b/src/zen/zen.cpp
@@ -12,6 +12,7 @@
#include "cmds/copy_cmd.h"
#include "cmds/dedup_cmd.h"
#include "cmds/exec_cmd.h"
+#include "cmds/hub_cmd.h"
#include "cmds/info_cmd.h"
#include "cmds/print_cmd.h"
#include "cmds/projectstore_cmd.h"
@@ -594,6 +595,7 @@ main(int argc, char** argv)
GcCommand GcCmd;
GcStatusCommand GcStatusCmd;
GcStopCommand GcStopCmd;
+ HubCommand HubCmd;
ImportOplogCommand ImportOplogCmd;
InfoCommand InfoCmd;
JobCommand JobCmd;
@@ -652,6 +654,7 @@ main(int argc, char** argv)
{GcStatusCommand::Name, &GcStatusCmd, GcStatusCommand::Description},
{GcStopCommand::Name, &GcStopCmd, GcStopCommand::Description},
{GcCommand::Name, &GcCmd, GcCommand::Description},
+ {HubCommand::Name, &HubCmd, HubCommand::Description},
{InfoCommand::Name, &InfoCmd, InfoCommand::Description},
{JobCommand::Name, &JobCmd, JobCommand::Description},
{LoggingCommand::Name, &LoggingCmd, LoggingCommand::Description},
@@ -796,7 +799,7 @@ main(int argc, char** argv)
Options.add_options()("help", "Show command line help");
Options.add_options()("c, command", "Sub command", cxxopts::value<std::string>(SubCommand));
Options.add_options()("httpclient",
- "Select HTTP client implementation (e.g. 'curl', 'cpr')",
+ "Select HTTP client implementation",
cxxopts::value<std::string>(GlobalOptions.HttpClientBackend)->default_value("curl"));
int CoreLimit = 0;
@@ -946,6 +949,7 @@ main(int argc, char** argv)
.IsTest = false,
.NoConsoleOutput = GlobalOptions.LoggingConfig.NoConsoleOutput,
.QuietConsole = GlobalOptions.LoggingConfig.QuietConsole,
+ .ForceColor = GlobalOptions.LoggingConfig.ForceColor,
.AbsLogFile = GlobalOptions.LoggingConfig.AbsLogFile,
.LogId = GlobalOptions.LoggingConfig.LogId};
zen::InitializeLogging(LogOptions);
diff --git a/src/zen/zen.h b/src/zen/zen.h
index 97cc9af6f..64d9390a3 100644
--- a/src/zen/zen.h
+++ b/src/zen/zen.h
@@ -18,7 +18,7 @@ struct ZenCliOptions
ZenLoggingConfig LoggingConfig;
- std::string HttpClientBackend; // Choice of HTTP client implementation (e.g. "curl", "cpr")
+ std::string HttpClientBackend; // Choice of HTTP client implementation
// Arguments after " -- " on command line are passed through and not parsed
std::string PassthroughCommandLine;
diff --git a/src/zencompute/CLAUDE.md b/src/zencompute/CLAUDE.md
index a1a39fc3c..750879d5a 100644
--- a/src/zencompute/CLAUDE.md
+++ b/src/zencompute/CLAUDE.md
@@ -141,7 +141,7 @@ Actions that fail or are abandoned can be automatically retried or manually resc
**Manual retry (API path):** `POST /compute/jobs/{lsn}` calls `RescheduleAction()`, which finds the action in `m_ResultsMap`, validates state (must be Failed or Abandoned), checks the retry limit, reverses queue counters (moving the LSN from `FinishedLsns` back to `ActiveLsns`), removes from results, and calls `ResetActionStateToPending()`. Returns 200 with `{lsn, retry_count}` on success, 409 Conflict with `{error}` on failure.
-**Retry limit:** Default of 3, overridable per-queue via the `max_retries` integer field in the queue's `Config` CbObject (set at `CreateQueue` time). Both automatic and manual paths respect this limit.
+**Retry limit:** Default of 3, overridable per-queue via the `max_retries` integer field in the queue's `Config` CbObject (set at `CreateQueue` time). Setting `max_retries=0` disables automatic retry entirely; omitting the field (or setting it to a negative value) uses the default of 3. Both automatic and manual paths respect this limit.
**Retraction (API path):** `RetractAction(Lsn)` pulls a Pending/Submitting/Running action back for rescheduling on a different runner. The action transitions to Retracted, then `ResetActionStateToPending()` is called *without* incrementing `RetryCount`. Retraction is idempotent.
@@ -156,7 +156,7 @@ Queues group actions from a single client session. A `QueueEntry` (internal) tra
- `ActiveLsns` — for cancellation lookup (under `m_Lock`)
- `FinishedLsns` — moved here when actions complete
- `IdleSince` — used for 15-minute automatic expiry
-- `Config` — CbObject set at creation; supports `max_retries` (int) to override the default retry limit
+- `Config` — CbObject set at creation; supports `max_retries` (int, default 3) to override the default retry limit. `0` = no retries, negative or absent = use default
**Queue state machine (`QueueState` enum):**
```
@@ -216,11 +216,7 @@ Worker handler logic is extracted into private helpers (`HandleWorkersGet`, `Han
## Concurrency Model
-**Locking discipline:** When multiple locks must be held simultaneously, always acquire in this order to prevent deadlocks:
-1. `m_ResultsLock`
-2. `m_RunningLock` (comment in localrunner.h: "must be taken *after* m_ResultsLock")
-3. `m_PendingLock`
-4. `m_QueueLock`
+**Locking discipline:** The three action maps (`m_PendingActions`, `m_RunningMap`, `m_ResultsMap`) are guarded by a single `m_ActionMapLock`. This eliminates lock-ordering concerns between maps and prevents actions from being temporarily absent from all maps during state transitions. Runner-level `m_RunningLock` in `LocalProcessRunner` / `RemoteHttpRunner` is a separate lock on a different class — unrelated to the session-level action map lock.
**Atomic fields** for counters and simple state: queue counts, `CpuUsagePercent`, `CpuSeconds`, `RetryCount`, `RunnerAction::m_ActionState`.
diff --git a/src/zencompute/computeservice.cpp b/src/zencompute/computeservice.cpp
index 92901de64..aaf34cbe2 100644
--- a/src/zencompute/computeservice.cpp
+++ b/src/zencompute/computeservice.cpp
@@ -8,6 +8,8 @@
# include "recording/actionrecorder.h"
# include "runners/localrunner.h"
# include "runners/remotehttprunner.h"
+# include "runners/managedrunner.h"
+# include "pathvalidation.h"
# if ZEN_PLATFORM_LINUX
# include "runners/linuxrunner.h"
# elif ZEN_PLATFORM_WINDOWS
@@ -195,13 +197,9 @@ struct ComputeServiceSession::Impl
std::atomic<IComputeCompletionObserver*> m_CompletionObserver{nullptr};
- RwLock m_PendingLock;
- std::map<int, Ref<RunnerAction>> m_PendingActions;
-
- RwLock m_RunningLock;
+ RwLock m_ActionMapLock; // Guards m_PendingActions, m_RunningMap, m_ResultsMap
+ std::map<int, Ref<RunnerAction>> m_PendingActions;
std::unordered_map<int, Ref<RunnerAction>> m_RunningMap;
-
- RwLock m_ResultsLock;
std::unordered_map<int, Ref<RunnerAction>> m_ResultsMap;
metrics::Meter m_ResultRate;
std::atomic<uint64_t> m_RetiredCount{0};
@@ -343,9 +341,12 @@ struct ComputeServiceSession::Impl
ActionCounts GetActionCounts()
{
ActionCounts Counts;
- Counts.Pending = (int)m_PendingLock.WithSharedLock([&] { return m_PendingActions.size(); });
- Counts.Running = (int)m_RunningLock.WithSharedLock([&] { return m_RunningMap.size(); });
- Counts.Completed = (int)m_ResultsLock.WithSharedLock([&] { return m_ResultsMap.size(); }) + (int)m_RetiredCount.load();
+ m_ActionMapLock.WithSharedLock([&] {
+ Counts.Pending = (int)m_PendingActions.size();
+ Counts.Running = (int)m_RunningMap.size();
+ Counts.Completed = (int)m_ResultsMap.size();
+ });
+ Counts.Completed += (int)m_RetiredCount.load();
Counts.ActiveQueues = (int)m_QueueLock.WithSharedLock([&] {
size_t Count = 0;
for (const auto& [Id, Queue] : m_Queues)
@@ -364,8 +365,10 @@ struct ComputeServiceSession::Impl
{
Cbo << "session_state"sv << ToString(m_SessionState.load(std::memory_order_relaxed));
m_WorkerLock.WithSharedLock([&] { Cbo << "worker_count"sv << m_WorkerMap.size(); });
- m_ResultsLock.WithSharedLock([&] { Cbo << "actions_complete"sv << m_ResultsMap.size(); });
- m_PendingLock.WithSharedLock([&] { Cbo << "actions_pending"sv << m_PendingActions.size(); });
+ m_ActionMapLock.WithSharedLock([&] {
+ Cbo << "actions_complete"sv << m_ResultsMap.size();
+ Cbo << "actions_pending"sv << m_PendingActions.size();
+ });
Cbo << "actions_submitted"sv << GetSubmittedActionCount();
EmitSnapshot("actions_arrival"sv, m_ArrivalRate, Cbo);
EmitSnapshot("actions_retired"sv, m_ResultRate, Cbo);
@@ -450,27 +453,17 @@ ComputeServiceSession::Impl::RequestStateTransition(SessionState NewState)
void
ComputeServiceSession::Impl::AbandonAllActions()
{
- // Collect all pending actions and mark them as Abandoned
+ // Collect all pending and running actions under a single lock scope
std::vector<Ref<RunnerAction>> PendingToAbandon;
+ std::vector<Ref<RunnerAction>> RunningToAbandon;
- m_PendingLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
PendingToAbandon.reserve(m_PendingActions.size());
for (auto& [Lsn, Action] : m_PendingActions)
{
PendingToAbandon.push_back(Action);
}
- });
-
- for (auto& Action : PendingToAbandon)
- {
- Action->SetActionState(RunnerAction::State::Abandoned);
- }
- // Collect all running actions and mark them as Abandoned, then
- // best-effort cancel via the local runner group
- std::vector<Ref<RunnerAction>> RunningToAbandon;
-
- m_RunningLock.WithSharedLock([&] {
RunningToAbandon.reserve(m_RunningMap.size());
for (auto& [Lsn, Action] : m_RunningMap)
{
@@ -478,6 +471,11 @@ ComputeServiceSession::Impl::AbandonAllActions()
}
});
+ for (auto& Action : PendingToAbandon)
+ {
+ Action->SetActionState(RunnerAction::State::Abandoned);
+ }
+
for (auto& Action : RunningToAbandon)
{
Action->SetActionState(RunnerAction::State::Abandoned);
@@ -742,7 +740,7 @@ std::vector<ComputeServiceSession::RunningActionInfo>
ComputeServiceSession::Impl::GetRunningActions()
{
std::vector<ComputeServiceSession::RunningActionInfo> Result;
- m_RunningLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
Result.reserve(m_RunningMap.size());
for (const auto& [Lsn, Action] : m_RunningMap)
{
@@ -810,6 +808,11 @@ void
ComputeServiceSession::Impl::RegisterWorker(CbPackage Worker)
{
ZEN_TRACE_CPU("ComputeServiceSession::RegisterWorker");
+
+ // Validate all paths in the worker description upfront, before the worker is
+ // distributed to runners. This rejects malicious packages early at ingestion time.
+ ValidateWorkerDescriptionPaths(Worker.GetObject());
+
RwLock::ExclusiveLockScope _(m_WorkerLock);
const IoHash& WorkerId = Worker.GetObject().GetHash();
@@ -994,10 +997,15 @@ ComputeServiceSession::Impl::EnqueueResolvedAction(int QueueId, WorkerDesc Worke
Pending->ActionObj = ActionObj;
Pending->Priority = RequestPriority;
- // For now simply put action into pending state, so we can do batch scheduling
+ // Insert into the pending map immediately so the action is visible to
+ // FindActionResult/GetActionResult right away. SetActionState will call
+ // PostUpdate which adds the action to m_UpdatedActions and signals the
+ // scheduler, but the scheduler's HandleActionUpdates inserts with
+ // std::map::insert which is a no-op for existing keys.
ZEN_DEBUG("action {} ({}) PENDING", Pending->ActionId, Pending->ActionLsn);
+ m_ActionMapLock.WithExclusiveLock([&] { m_PendingActions.insert({ActionLsn, Pending}); });
Pending->SetActionState(RunnerAction::State::Pending);
if (m_Recorder)
@@ -1043,11 +1051,7 @@ ComputeServiceSession::Impl::GetSubmittedActionCount()
HttpResponseCode
ComputeServiceSession::Impl::GetActionResult(int ActionLsn, CbPackage& OutResultPackage)
{
- // This lock is held for the duration of the function since we need to
- // be sure that the action doesn't change state while we are checking the
- // different data structures
-
- RwLock::ExclusiveLockScope _(m_ResultsLock);
+ RwLock::ExclusiveLockScope _(m_ActionMapLock);
if (auto It = m_ResultsMap.find(ActionLsn); It != m_ResultsMap.end())
{
@@ -1058,25 +1062,14 @@ ComputeServiceSession::Impl::GetActionResult(int ActionLsn, CbPackage& OutResult
return HttpResponseCode::OK;
}
+ if (m_PendingActions.find(ActionLsn) != m_PendingActions.end())
{
- RwLock::SharedLockScope __(m_PendingLock);
-
- if (auto FindIt = m_PendingActions.find(ActionLsn); FindIt != m_PendingActions.end())
- {
- return HttpResponseCode::Accepted;
- }
+ return HttpResponseCode::Accepted;
}
- // Lock order is important here to avoid deadlocks, RwLock m_RunningLock must
- // always be taken after m_ResultsLock if both are needed
-
+ if (m_RunningMap.find(ActionLsn) != m_RunningMap.end())
{
- RwLock::SharedLockScope __(m_RunningLock);
-
- if (m_RunningMap.find(ActionLsn) != m_RunningMap.end())
- {
- return HttpResponseCode::Accepted;
- }
+ return HttpResponseCode::Accepted;
}
return HttpResponseCode::NotFound;
@@ -1085,11 +1078,7 @@ ComputeServiceSession::Impl::GetActionResult(int ActionLsn, CbPackage& OutResult
HttpResponseCode
ComputeServiceSession::Impl::FindActionResult(const IoHash& ActionId, CbPackage& OutResultPackage)
{
- // This lock is held for the duration of the function since we need to
- // be sure that the action doesn't change state while we are checking the
- // different data structures
-
- RwLock::ExclusiveLockScope _(m_ResultsLock);
+ RwLock::ExclusiveLockScope _(m_ActionMapLock);
for (auto It = begin(m_ResultsMap), End = end(m_ResultsMap); It != End; ++It)
{
@@ -1103,30 +1092,19 @@ ComputeServiceSession::Impl::FindActionResult(const IoHash& ActionId, CbPackage&
}
}
+ for (const auto& [K, Pending] : m_PendingActions)
{
- RwLock::SharedLockScope __(m_PendingLock);
-
- for (const auto& [K, Pending] : m_PendingActions)
+ if (Pending->ActionId == ActionId)
{
- if (Pending->ActionId == ActionId)
- {
- return HttpResponseCode::Accepted;
- }
+ return HttpResponseCode::Accepted;
}
}
- // Lock order is important here to avoid deadlocks, RwLock m_RunningLock must
- // always be taken after m_ResultsLock if both are needed
-
+ for (const auto& [K, v] : m_RunningMap)
{
- RwLock::SharedLockScope __(m_RunningLock);
-
- for (const auto& [K, v] : m_RunningMap)
+ if (v->ActionId == ActionId)
{
- if (v->ActionId == ActionId)
- {
- return HttpResponseCode::Accepted;
- }
+ return HttpResponseCode::Accepted;
}
}
@@ -1144,7 +1122,7 @@ ComputeServiceSession::Impl::GetCompleted(CbWriter& Cbo)
{
Cbo.BeginArray("completed");
- m_ResultsLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
for (auto& [Lsn, Action] : m_ResultsMap)
{
Cbo.BeginObject();
@@ -1275,20 +1253,14 @@ ComputeServiceSession::Impl::CancelQueue(int QueueId)
std::vector<Ref<RunnerAction>> PendingActionsToCancel;
std::vector<int> RunningLsnsToCancel;
- m_PendingLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
for (int Lsn : LsnsToCancel)
{
if (auto It = m_PendingActions.find(Lsn); It != m_PendingActions.end())
{
PendingActionsToCancel.push_back(It->second);
}
- }
- });
-
- m_RunningLock.WithSharedLock([&] {
- for (int Lsn : LsnsToCancel)
- {
- if (m_RunningMap.find(Lsn) != m_RunningMap.end())
+ else if (m_RunningMap.find(Lsn) != m_RunningMap.end())
{
RunningLsnsToCancel.push_back(Lsn);
}
@@ -1307,7 +1279,7 @@ ComputeServiceSession::Impl::CancelQueue(int QueueId)
// transition from the runner is blocked (Cancelled > Failed in the enum).
for (int Lsn : RunningLsnsToCancel)
{
- m_RunningLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
if (auto It = m_RunningMap.find(Lsn); It != m_RunningMap.end())
{
It->second->SetActionState(RunnerAction::State::Cancelled);
@@ -1445,7 +1417,7 @@ ComputeServiceSession::Impl::GetQueueCompleted(int QueueId, CbWriter& Cbo)
if (Queue)
{
Queue->m_Lock.WithSharedLock([&] {
- m_ResultsLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
for (int Lsn : Queue->FinishedLsns)
{
if (m_ResultsMap.contains(Lsn))
@@ -1475,15 +1447,19 @@ ComputeServiceSession::Impl::NotifyQueueActionComplete(int QueueId, int Lsn, Run
return;
}
+ bool WasActive = false;
Queue->m_Lock.WithExclusiveLock([&] {
- Queue->ActiveLsns.erase(Lsn);
+ WasActive = Queue->ActiveLsns.erase(Lsn) > 0;
Queue->FinishedLsns.insert(Lsn);
});
- const int PreviousActive = Queue->ActiveCount.fetch_sub(1, std::memory_order_relaxed);
- if (PreviousActive == 1)
+ if (WasActive)
{
- Queue->IdleSince.store(GetHifreqTimerValue(), std::memory_order_relaxed);
+ const int PreviousActive = Queue->ActiveCount.fetch_sub(1, std::memory_order_relaxed);
+ if (PreviousActive == 1)
+ {
+ Queue->IdleSince.store(GetHifreqTimerValue(), std::memory_order_relaxed);
+ }
}
switch (ActionState)
@@ -1541,9 +1517,15 @@ ComputeServiceSession::Impl::SchedulePendingActions()
{
ZEN_TRACE_CPU("ComputeServiceSession::SchedulePendingActions");
int ScheduledCount = 0;
- size_t RunningCount = m_RunningLock.WithSharedLock([&] { return m_RunningMap.size(); });
- size_t PendingCount = m_PendingLock.WithSharedLock([&] { return m_PendingActions.size(); });
- size_t ResultCount = m_ResultsLock.WithSharedLock([&] { return m_ResultsMap.size(); });
+ size_t RunningCount = 0;
+ size_t PendingCount = 0;
+ size_t ResultCount = 0;
+
+ m_ActionMapLock.WithSharedLock([&] {
+ RunningCount = m_RunningMap.size();
+ PendingCount = m_PendingActions.size();
+ ResultCount = m_ResultsMap.size();
+ });
static Stopwatch DumpRunningTimer;
@@ -1560,7 +1542,7 @@ ComputeServiceSession::Impl::SchedulePendingActions()
DumpRunningTimer.Reset();
std::set<int> RunningList;
- m_RunningLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
for (auto& [K, V] : m_RunningMap)
{
RunningList.insert(K);
@@ -1602,7 +1584,7 @@ ComputeServiceSession::Impl::SchedulePendingActions()
// Also note that the m_PendingActions list is not maintained
// here, that's done periodically in SchedulePendingActions()
- m_PendingLock.WithExclusiveLock([&] {
+ m_ActionMapLock.WithExclusiveLock([&] {
if (m_SessionState.load(std::memory_order_relaxed) >= SessionState::Paused)
{
return;
@@ -1701,7 +1683,7 @@ ComputeServiceSession::Impl::SchedulerThreadFunction()
{
int TimeoutMs = 500;
- auto PendingCount = m_PendingLock.WithSharedLock([&] { return m_PendingActions.size(); });
+ auto PendingCount = m_ActionMapLock.WithSharedLock([&] { return m_PendingActions.size(); });
if (PendingCount)
{
@@ -1720,22 +1702,22 @@ ComputeServiceSession::Impl::SchedulerThreadFunction()
m_SchedulingThreadEvent.Reset();
}
- ZEN_DEBUG("compute scheduler TICK (Pending: {} was {}, Running: {}, Results: {}) timeout: {}",
- m_PendingLock.WithSharedLock([&] { return m_PendingActions.size(); }),
- PendingCount,
- m_RunningLock.WithSharedLock([&] { return m_RunningMap.size(); }),
- m_ResultsLock.WithSharedLock([&] { return m_ResultsMap.size(); }),
- TimeoutMs);
+ m_ActionMapLock.WithSharedLock([&] {
+ ZEN_DEBUG("compute scheduler TICK (Pending: {}, Running: {}, Results: {}) timeout: {}",
+ m_PendingActions.size(),
+ m_RunningMap.size(),
+ m_ResultsMap.size(),
+ TimeoutMs);
+ });
HandleActionUpdates();
// Auto-transition Draining → Paused when all work is done
if (m_SessionState.load(std::memory_order_relaxed) == SessionState::Draining)
{
- size_t Pending = m_PendingLock.WithSharedLock([&] { return m_PendingActions.size(); });
- size_t Running = m_RunningLock.WithSharedLock([&] { return m_RunningMap.size(); });
+ bool AllDrained = m_ActionMapLock.WithSharedLock([&] { return m_PendingActions.empty() && m_RunningMap.empty(); });
- if (Pending == 0 && Running == 0)
+ if (AllDrained)
{
SessionState Expected = SessionState::Draining;
if (m_SessionState.compare_exchange_strong(Expected, SessionState::Paused, std::memory_order_acq_rel))
@@ -1776,9 +1758,9 @@ ComputeServiceSession::Impl::GetMaxRetriesForQueue(int QueueId)
if (Config)
{
- int Value = Config["max_retries"].AsInt32(0);
+ int Value = Config["max_retries"].AsInt32(-1);
- if (Value > 0)
+ if (Value >= 0)
{
return Value;
}
@@ -1797,7 +1779,7 @@ ComputeServiceSession::Impl::RescheduleAction(int ActionLsn)
// Find, validate, and remove atomically under a single lock scope to prevent
// concurrent RescheduleAction calls from double-removing the same action.
- m_ResultsLock.WithExclusiveLock([&] {
+ m_ActionMapLock.WithExclusiveLock([&] {
auto It = m_ResultsMap.find(ActionLsn);
if (It == m_ResultsMap.end())
{
@@ -1871,26 +1853,20 @@ ComputeServiceSession::Impl::RetractAction(int ActionLsn)
bool WasRunning = false;
// Look for the action in pending or running maps
- m_RunningLock.WithSharedLock([&] {
+ m_ActionMapLock.WithSharedLock([&] {
if (auto It = m_RunningMap.find(ActionLsn); It != m_RunningMap.end())
{
Action = It->second;
WasRunning = true;
}
+ else if (auto PIt = m_PendingActions.find(ActionLsn); PIt != m_PendingActions.end())
+ {
+ Action = PIt->second;
+ }
});
if (!Action)
{
- m_PendingLock.WithSharedLock([&] {
- if (auto It = m_PendingActions.find(ActionLsn); It != m_PendingActions.end())
- {
- Action = It->second;
- }
- });
- }
-
- if (!Action)
- {
return {.Success = false, .Error = "Action not found in pending or running maps"};
}
@@ -1912,18 +1888,15 @@ ComputeServiceSession::Impl::RetractAction(int ActionLsn)
void
ComputeServiceSession::Impl::RemoveActionFromActiveMaps(int ActionLsn)
{
- m_RunningLock.WithExclusiveLock([&] {
- m_PendingLock.WithExclusiveLock([&] {
- if (auto FindIt = m_RunningMap.find(ActionLsn); FindIt == m_RunningMap.end())
- {
- m_PendingActions.erase(ActionLsn);
- }
- else
- {
- m_RunningMap.erase(FindIt);
- }
- });
- });
+ // Caller must hold m_ActionMapLock exclusively.
+ if (auto FindIt = m_RunningMap.find(ActionLsn); FindIt == m_RunningMap.end())
+ {
+ m_PendingActions.erase(ActionLsn);
+ }
+ else
+ {
+ m_RunningMap.erase(FindIt);
+ }
}
void
@@ -1973,7 +1946,7 @@ ComputeServiceSession::Impl::HandleActionUpdates()
}
else
{
- m_PendingLock.WithExclusiveLock([&] { m_PendingActions.insert({ActionLsn, Action}); });
+ m_ActionMapLock.WithExclusiveLock([&] { m_PendingActions.insert({ActionLsn, Action}); });
}
break;
@@ -1983,11 +1956,9 @@ ComputeServiceSession::Impl::HandleActionUpdates()
// Dispatched to a runner — move from pending to running
case RunnerAction::State::Running:
- m_RunningLock.WithExclusiveLock([&] {
- m_PendingLock.WithExclusiveLock([&] {
- m_RunningMap.insert({ActionLsn, Action});
- m_PendingActions.erase(ActionLsn);
- });
+ m_ActionMapLock.WithExclusiveLock([&] {
+ m_RunningMap.insert({ActionLsn, Action});
+ m_PendingActions.erase(ActionLsn);
});
ZEN_DEBUG("action {} ({}) RUNNING", Action->ActionId, ActionLsn);
break;
@@ -1995,7 +1966,10 @@ ComputeServiceSession::Impl::HandleActionUpdates()
// Retracted — pull back for rescheduling without counting against retry limit
case RunnerAction::State::Retracted:
{
- RemoveActionFromActiveMaps(ActionLsn);
+ m_ActionMapLock.WithExclusiveLock([&] {
+ m_RunningMap.erase(ActionLsn);
+ m_PendingActions[ActionLsn] = Action;
+ });
Action->ResetActionStateToPending();
ZEN_INFO("action {} ({}) retracted for rescheduling", Action->ActionId, ActionLsn);
break;
@@ -2019,7 +1993,10 @@ ComputeServiceSession::Impl::HandleActionUpdates()
if (Action->RetryCount.load(std::memory_order_relaxed) < MaxRetries)
{
- RemoveActionFromActiveMaps(ActionLsn);
+ m_ActionMapLock.WithExclusiveLock([&] {
+ m_RunningMap.erase(ActionLsn);
+ m_PendingActions[ActionLsn] = Action;
+ });
// Reset triggers PostUpdate() which re-enters the action as Pending
Action->ResetActionStateToPending();
@@ -2034,16 +2011,16 @@ ComputeServiceSession::Impl::HandleActionUpdates()
}
}
- RemoveActionFromActiveMaps(ActionLsn);
+ m_ActionMapLock.WithExclusiveLock([&] {
+ RemoveActionFromActiveMaps(ActionLsn);
- // Update queue counters BEFORE publishing the result into
- // m_ResultsMap. GetActionResult erases from m_ResultsMap
- // under m_ResultsLock, so if we updated counters after
- // releasing that lock, a caller could observe ActiveCount
- // still at 1 immediately after GetActionResult returned OK.
- NotifyQueueActionComplete(Action->QueueId, ActionLsn, TerminalState);
+ // Update queue counters BEFORE publishing the result into
+ // m_ResultsMap. GetActionResult erases from m_ResultsMap
+ // under m_ActionMapLock, so if we updated counters after
+ // releasing that lock, a caller could observe ActiveCount
+ // still at 1 immediately after GetActionResult returned OK.
+ NotifyQueueActionComplete(Action->QueueId, ActionLsn, TerminalState);
- m_ResultsLock.WithExclusiveLock([&] {
m_ResultsMap[ActionLsn] = Action;
// Append to bounded action history ring
@@ -2282,6 +2259,18 @@ ComputeServiceSession::AddLocalRunner(ChunkResolver& InChunkResolver, std::files
}
void
+ComputeServiceSession::AddManagedLocalRunner(ChunkResolver& InChunkResolver, std::filesystem::path BasePath, int32_t MaxConcurrentActions)
+{
+ ZEN_TRACE_CPU("ComputeServiceSession::AddManagedLocalRunner");
+
+ auto* NewRunner =
+ new ManagedProcessRunner(InChunkResolver, BasePath, m_Impl->m_DeferredDeleter, m_Impl->m_LocalSubmitPool, MaxConcurrentActions);
+
+ m_Impl->SyncWorkersToRunner(*NewRunner);
+ m_Impl->m_LocalRunnerGroup.AddRunner(NewRunner);
+}
+
+void
ComputeServiceSession::AddRemoteRunner(ChunkResolver& InChunkResolver, std::filesystem::path BasePath, std::string_view HostName)
{
ZEN_TRACE_CPU("ComputeServiceSession::AddRemoteRunner");
diff --git a/src/zencompute/httpcomputeservice.cpp b/src/zencompute/httpcomputeservice.cpp
index bdfd9d197..1d28e7137 100644
--- a/src/zencompute/httpcomputeservice.cpp
+++ b/src/zencompute/httpcomputeservice.cpp
@@ -93,16 +93,17 @@ struct HttpComputeService::Impl
uint64_t NewBytes = 0;
};
- IngestStats IngestPackageAttachments(const CbPackage& Package);
- bool CheckAttachments(const CbObject& ActionObj, std::vector<IoHash>& NeedList);
- void HandleWorkersGet(HttpServerRequest& HttpReq);
- void HandleWorkersAllGet(HttpServerRequest& HttpReq);
- void WriteQueueDescription(CbWriter& Cbo, int QueueId, const ComputeServiceSession::QueueStatus& Status);
- void HandleWorkerRequest(HttpServerRequest& HttpReq, const IoHash& WorkerId);
- void HandleSubmitAction(HttpServerRequest& HttpReq, int QueueId, int Priority, const WorkerDesc* Worker);
+ bool IngestPackageAttachments(HttpServerRequest& HttpReq, const CbPackage& Package, IngestStats& OutStats);
+ bool CheckAttachments(const CbObject& ActionObj, std::vector<IoHash>& NeedList);
+ bool ValidateAttachmentHash(HttpServerRequest& HttpReq, const CbAttachment& Attachment);
+ void HandleWorkersGet(HttpServerRequest& HttpReq);
+ void HandleWorkersAllGet(HttpServerRequest& HttpReq);
+ void WriteQueueDescription(CbWriter& Cbo, int QueueId, const ComputeServiceSession::QueueStatus& Status);
+ void HandleWorkerRequest(HttpServerRequest& HttpReq, const IoHash& WorkerId);
+ void HandleSubmitAction(HttpServerRequest& HttpReq, int QueueId, int Priority, const WorkerDesc* Worker);
// WebSocket / observer
- void OnWebSocketOpen(Ref<WebSocketConnection> Connection);
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri);
void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code);
void OnActionsCompleted(std::span<const IComputeCompletionObserver::CompletedActionNotification> Actions);
@@ -373,7 +374,7 @@ HttpComputeService::Impl::RegisterRoutes()
if (HttpResponseCode ResponseCode = m_ComputeService.FindActionResult(ActionId, /* out */ Output);
ResponseCode != HttpResponseCode::OK)
{
- ZEN_TRACE("jobs/{}/{}: {}", Req.GetCapture(1), Req.GetCapture(2), ToString(ResponseCode))
+ ZEN_DEBUG("jobs/{}/{}: {}", Req.GetCapture(1), Req.GetCapture(2), ToString(ResponseCode))
if (ResponseCode == HttpResponseCode::NotFound)
{
@@ -1167,35 +1168,81 @@ HttpComputeService::Impl::ResolveQueueRef(HttpServerRequest& HttpReq, std::strin
return ParseInt<int>(Capture).value_or(0);
}
-HttpComputeService::Impl::IngestStats
-HttpComputeService::Impl::IngestPackageAttachments(const CbPackage& Package)
+bool
+HttpComputeService::Impl::ValidateAttachmentHash(HttpServerRequest& HttpReq, const CbAttachment& Attachment)
{
- IngestStats Stats;
+ const IoHash ClaimedHash = Attachment.GetHash();
+ CompressedBuffer Buffer = Attachment.AsCompressedBinary();
+ const IoHash HeaderHash = Buffer.DecodeRawHash();
+
+ if (HeaderHash != ClaimedHash)
+ {
+ ZEN_WARN("attachment header hash mismatch: claimed {} but header contains {}", ClaimedHash, HeaderHash);
+ HttpReq.WriteResponse(HttpResponseCode::BadRequest);
+ return false;
+ }
+
+ IoHashStream Hasher;
+
+ bool DecompressOk = Buffer.DecompressToStream(
+ 0,
+ Buffer.DecodeRawSize(),
+ [&](uint64_t /*SourceOffset*/, uint64_t /*SourceSize*/, uint64_t /*Offset*/, const CompositeBuffer& Range) -> bool {
+ for (const SharedBuffer& Segment : Range.GetSegments())
+ {
+ Hasher.Append(Segment.GetView());
+ }
+ return true;
+ });
+
+ if (!DecompressOk)
+ {
+ ZEN_WARN("attachment {}: failed to decompress", ClaimedHash);
+ HttpReq.WriteResponse(HttpResponseCode::BadRequest);
+ return false;
+ }
+
+ const IoHash ActualHash = Hasher.GetHash();
+
+ if (ActualHash != ClaimedHash)
+ {
+ ZEN_WARN("attachment hash mismatch: claimed {} but decompressed data hashes to {}", ClaimedHash, ActualHash);
+ HttpReq.WriteResponse(HttpResponseCode::BadRequest);
+ return false;
+ }
+
+ return true;
+}
+bool
+HttpComputeService::Impl::IngestPackageAttachments(HttpServerRequest& HttpReq, const CbPackage& Package, IngestStats& OutStats)
+{
for (const CbAttachment& Attachment : Package.GetAttachments())
{
ZEN_ASSERT(Attachment.IsCompressedBinary());
- const IoHash DataHash = Attachment.GetHash();
- CompressedBuffer DataView = Attachment.AsCompressedBinary();
-
- ZEN_UNUSED(DataHash);
+ if (!ValidateAttachmentHash(HttpReq, Attachment))
+ {
+ return false;
+ }
- const uint64_t CompressedSize = DataView.GetCompressedSize();
+ const IoHash DataHash = Attachment.GetHash();
+ CompressedBuffer DataView = Attachment.AsCompressedBinary();
+ const uint64_t CompressedSize = DataView.GetCompressedSize();
- Stats.Bytes += CompressedSize;
- ++Stats.Count;
+ OutStats.Bytes += CompressedSize;
+ ++OutStats.Count;
const CidStore::InsertResult InsertResult = m_CidStore.AddChunk(DataView.GetCompressed().Flatten().AsIoBuffer(), DataHash);
if (InsertResult.New)
{
- Stats.NewBytes += CompressedSize;
- ++Stats.NewCount;
+ OutStats.NewBytes += CompressedSize;
+ ++OutStats.NewCount;
}
}
- return Stats;
+ return true;
}
bool
@@ -1253,7 +1300,10 @@ HttpComputeService::Impl::HandleSubmitAction(HttpServerRequest& HttpReq, int Que
{
CbPackage Package = HttpReq.ReadPayloadPackage();
Body = Package.GetObject();
- Stats = IngestPackageAttachments(Package);
+ if (!IngestPackageAttachments(HttpReq, Package, Stats))
+ {
+ return; // validation failed, response already written
+ }
break;
}
@@ -1268,8 +1318,7 @@ HttpComputeService::Impl::HandleSubmitAction(HttpServerRequest& HttpReq, int Que
{
// --- Batch path ---
- // For CbObject payloads, check all attachments upfront before enqueuing anything
- if (HttpReq.RequestContentType() == HttpContentType::kCbObject)
+ // Verify all action attachment references exist in the store
{
std::vector<IoHash> NeedList;
@@ -1345,7 +1394,6 @@ HttpComputeService::Impl::HandleSubmitAction(HttpServerRequest& HttpReq, int Que
// --- Single-action path: Body is the action itself ---
- if (HttpReq.RequestContentType() == HttpContentType::kCbObject)
{
std::vector<IoHash> NeedList;
@@ -1491,10 +1539,14 @@ HttpComputeService::Impl::HandleWorkerRequest(HttpServerRequest& HttpReq, const
{
ZEN_ASSERT(Attachment.IsCompressedBinary());
+ if (!ValidateAttachmentHash(HttpReq, Attachment))
+ {
+ return;
+ }
+
const IoHash DataHash = Attachment.GetHash();
CompressedBuffer Buffer = Attachment.AsCompressedBinary();
- ZEN_UNUSED(DataHash);
TotalAttachmentBytes += Buffer.GetCompressedSize();
++AttachmentCount;
@@ -1537,9 +1589,9 @@ HttpComputeService::Impl::HandleWorkerRequest(HttpServerRequest& HttpReq, const
//
void
-HttpComputeService::OnWebSocketOpen(Ref<WebSocketConnection> Connection)
+HttpComputeService::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
{
- m_Impl->OnWebSocketOpen(std::move(Connection));
+ m_Impl->OnWebSocketOpen(std::move(Connection), RelativeUri);
}
void
@@ -1566,8 +1618,9 @@ HttpComputeService::OnActionsCompleted(std::span<const CompletedActionNotificati
//
void
-HttpComputeService::Impl::OnWebSocketOpen(Ref<WebSocketConnection> Connection)
+HttpComputeService::Impl::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
{
+ ZEN_UNUSED(RelativeUri);
ZEN_INFO("compute WebSocket client connected");
m_WsConnectionsLock.WithExclusiveLock([&] { m_WsConnections.push_back(std::move(Connection)); });
}
diff --git a/src/zencompute/httporchestrator.cpp b/src/zencompute/httporchestrator.cpp
index 6cbe01e04..d92af8716 100644
--- a/src/zencompute/httporchestrator.cpp
+++ b/src/zencompute/httporchestrator.cpp
@@ -418,8 +418,9 @@ HttpOrchestratorService::HandleRequest(HttpServerRequest& Request)
# if ZEN_WITH_WEBSOCKETS
void
-HttpOrchestratorService::OnWebSocketOpen(Ref<WebSocketConnection> Connection)
+HttpOrchestratorService::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
{
+ ZEN_UNUSED(RelativeUri);
if (!m_PushEnabled.load())
{
return;
diff --git a/src/zencompute/include/zencompute/computeservice.h b/src/zencompute/include/zencompute/computeservice.h
index 1ca78738a..ad556f546 100644
--- a/src/zencompute/include/zencompute/computeservice.h
+++ b/src/zencompute/include/zencompute/computeservice.h
@@ -167,6 +167,7 @@ public:
// Action runners
void AddLocalRunner(ChunkResolver& InChunkResolver, std::filesystem::path BasePath, int32_t MaxConcurrentActions = 0);
+ void AddManagedLocalRunner(ChunkResolver& InChunkResolver, std::filesystem::path BasePath, int32_t MaxConcurrentActions = 0);
void AddRemoteRunner(ChunkResolver& InChunkResolver, std::filesystem::path BasePath, std::string_view HostName);
// Action submission
diff --git a/src/zencompute/include/zencompute/httpcomputeservice.h b/src/zencompute/include/zencompute/httpcomputeservice.h
index b58e73a0d..de85a295f 100644
--- a/src/zencompute/include/zencompute/httpcomputeservice.h
+++ b/src/zencompute/include/zencompute/httpcomputeservice.h
@@ -45,7 +45,7 @@ public:
// IWebSocketHandler
- void OnWebSocketOpen(Ref<WebSocketConnection> Connection) override;
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override;
void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg) override;
void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason) override;
diff --git a/src/zencompute/include/zencompute/httporchestrator.h b/src/zencompute/include/zencompute/httporchestrator.h
index da5c5dfc3..58b2c9152 100644
--- a/src/zencompute/include/zencompute/httporchestrator.h
+++ b/src/zencompute/include/zencompute/httporchestrator.h
@@ -70,7 +70,7 @@ public:
// IWebSocketHandler
#if ZEN_WITH_WEBSOCKETS
- void OnWebSocketOpen(Ref<WebSocketConnection> Connection) override;
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override;
void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg) override;
void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason) override;
#endif
diff --git a/src/zencompute/pathvalidation.h b/src/zencompute/pathvalidation.h
new file mode 100644
index 000000000..c2e30183a
--- /dev/null
+++ b/src/zencompute/pathvalidation.h
@@ -0,0 +1,118 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/compactbinary.h>
+#include <zencore/except_fmt.h>
+#include <zencore/string.h>
+
+#include <filesystem>
+#include <string_view>
+
+namespace zen::compute {
+
+// Validate that a single path component contains only characters that are valid
+// file/directory names on all supported platforms. Uses Windows rules as the most
+// restrictive superset, since packages may be built on one platform and consumed
+// on another.
+inline void
+ValidatePathComponent(std::string_view Component, std::string_view FullPath)
+{
+ // Reject control characters (0x00-0x1F) and characters forbidden on Windows
+ for (char Ch : Component)
+ {
+ if (static_cast<unsigned char>(Ch) < 0x20 || Ch == '<' || Ch == '>' || Ch == ':' || Ch == '"' || Ch == '|' || Ch == '?' ||
+ Ch == '*')
+ {
+ throw zen::invalid_argument("invalid character in path component '{}' of '{}'", Component, FullPath);
+ }
+ }
+
+ // Reject empty components and trailing dots or spaces (silently stripped on Windows, leading to confusion)
+ if (Component.empty() || Component.back() == '.' || Component.back() == ' ')
+ {
+ throw zen::invalid_argument("path component '{}' of '{}' has trailing dot or space", Component, FullPath);
+ }
+
+ // Reject Windows reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
+ // These are reserved with or without an extension (e.g. "CON.txt" is still reserved).
+ std::string_view Stem = Component.substr(0, Component.find('.'));
+
+ static constexpr std::string_view ReservedNames[] = {
+ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
+ "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
+ };
+
+ for (std::string_view Reserved : ReservedNames)
+ {
+ if (zen::StrCaseCompare(Stem, Reserved) == 0)
+ {
+ throw zen::invalid_argument("path component '{}' of '{}' uses reserved device name '{}'", Component, FullPath, Reserved);
+ }
+ }
+}
+
+// Validate that a path extracted from a package is a safe relative path.
+// Rejects absolute paths, ".." components, and invalid platform filenames.
+inline void
+ValidateSandboxRelativePath(std::string_view Name)
+{
+ if (Name.empty())
+ {
+ throw zen::invalid_argument("path traversal detected: empty path name");
+ }
+
+ std::filesystem::path Parsed(Name);
+
+ if (Parsed.is_absolute())
+ {
+ throw zen::invalid_argument("path traversal detected: '{}' is an absolute path", Name);
+ }
+
+ for (const auto& Component : Parsed)
+ {
+ std::string ComponentStr = Component.string();
+
+ if (ComponentStr == "..")
+ {
+ throw zen::invalid_argument("path traversal detected: '{}' contains '..' component", Name);
+ }
+
+ // Skip "." (current directory) — harmless in relative paths
+ if (ComponentStr != ".")
+ {
+ ValidatePathComponent(ComponentStr, Name);
+ }
+ }
+}
+
+// Validate all path entries in a worker description CbObject.
+// Checks path, executables[].name, dirs[], and files[].name fields.
+// Throws an exception if any invalid paths are found.
+inline void
+ValidateWorkerDescriptionPaths(const CbObject& WorkerDescription)
+{
+ using namespace std::literals;
+
+ if (auto PathField = WorkerDescription["path"sv]; PathField.HasValue())
+ {
+ ValidateSandboxRelativePath(PathField.AsString());
+ }
+
+ for (auto& It : WorkerDescription["executables"sv])
+ {
+ ValidateSandboxRelativePath(It.AsObjectView()["name"sv].AsString());
+ }
+
+ for (auto& It : WorkerDescription["dirs"sv])
+ {
+ ValidateSandboxRelativePath(It.AsString());
+ }
+
+ for (auto& It : WorkerDescription["files"sv])
+ {
+ ValidateSandboxRelativePath(It.AsObjectView()["name"sv].AsString());
+ }
+}
+
+} // namespace zen::compute
diff --git a/src/zencompute/runners/functionrunner.cpp b/src/zencompute/runners/functionrunner.cpp
index 4f116e7d8..67e12b84e 100644
--- a/src/zencompute/runners/functionrunner.cpp
+++ b/src/zencompute/runners/functionrunner.cpp
@@ -164,8 +164,9 @@ BaseRunnerGroup::SubmitActions(const std::vector<Ref<RunnerAction>>& Actions)
}
}
- // Assign any remaining actions to runners with capacity (round-robin)
- for (int i = 0; ActionIdx < Actions.size(); i = (i + 1) % RunnerCount)
+ // Assign any remaining actions to runners with capacity (round-robin).
+ // Cap at TotalCapacity to avoid spinning when there are more actions than runners can accept.
+ for (int i = 0; ActionIdx < Actions.size() && ActionIdx < TotalCapacity; i = (i + 1) % RunnerCount)
{
if (Capacities[i] > PerRunnerActions[i].size())
{
@@ -186,11 +187,12 @@ BaseRunnerGroup::SubmitActions(const std::vector<Ref<RunnerAction>>& Actions)
}
}
- // Reassemble results in original action order
- std::vector<SubmitResult> Results(Actions.size());
+ // Reassemble results in original action order.
+ // Actions beyond ActionIdx were not assigned to any runner (insufficient capacity).
+ std::vector<SubmitResult> Results(Actions.size(), SubmitResult{.IsAccepted = false, .Reason = "No capacity"});
std::vector<size_t> PerRunnerIdx(RunnerCount, 0);
- for (size_t i = 0; i < Actions.size(); ++i)
+ for (size_t i = 0; i < ActionIdx; ++i)
{
size_t RunnerIdx = ActionRunnerIndex[i];
size_t Idx = PerRunnerIdx[RunnerIdx]++;
diff --git a/src/zencompute/runners/linuxrunner.cpp b/src/zencompute/runners/linuxrunner.cpp
index e79a6c90f..9055005d9 100644
--- a/src/zencompute/runners/linuxrunner.cpp
+++ b/src/zencompute/runners/linuxrunner.cpp
@@ -331,6 +331,8 @@ LinuxProcessRunner::LinuxProcessRunner(ChunkResolver& Resolver,
{
ZEN_INFO("namespace sandboxing enabled for child processes");
}
+
+ StartMonitorThread();
}
SubmitResult
diff --git a/src/zencompute/runners/localrunner.cpp b/src/zencompute/runners/localrunner.cpp
index b61e0a46f..1b748c0e5 100644
--- a/src/zencompute/runners/localrunner.cpp
+++ b/src/zencompute/runners/localrunner.cpp
@@ -4,6 +4,8 @@
#if ZEN_WITH_COMPUTE_SERVICES
+# include "pathvalidation.h"
+
# include <zencore/compactbinary.h>
# include <zencore/compactbinarybuilder.h>
# include <zencore/compactbinarypackage.h>
@@ -104,8 +106,6 @@ LocalProcessRunner::LocalProcessRunner(ChunkResolver& Resolver,
ZEN_INFO("Cleanup complete");
}
- m_MonitorThread = std::thread{&LocalProcessRunner::MonitorThreadFunction, this};
-
# if ZEN_PLATFORM_WINDOWS
// Suppress any error dialogs caused by missing dependencies
UINT OldMode = ::SetErrorMode(0);
@@ -382,6 +382,8 @@ LocalProcessRunner::DecompressAttachmentToFile(const CbPackage& FromP
const IoHash ChunkHash = FileEntry["hash"sv].AsHash();
const uint64_t Size = FileEntry["size"sv].AsUInt64();
+ ValidateSandboxRelativePath(Name);
+
CompressedBuffer Compressed;
if (const CbAttachment* Attachment = FromPackage.FindAttachment(ChunkHash))
@@ -457,7 +459,8 @@ LocalProcessRunner::ManifestWorker(const CbPackage& WorkerPackage,
for (auto& It : WorkerDescription["dirs"sv])
{
- std::string_view Name = It.AsString();
+ std::string_view Name = It.AsString();
+ ValidateSandboxRelativePath(Name);
std::filesystem::path DirPath{SandboxPath / std::filesystem::path(Name).make_preferred()};
// Validate dir path stays within sandbox
@@ -482,6 +485,8 @@ LocalProcessRunner::ManifestWorker(const CbPackage& WorkerPackage,
}
WriteFile(SandboxPath / "worker.zcb", WorkerDescription.GetBuffer().AsIoBuffer());
+
+ ZEN_INFO("manifested worker '{}' in '{}'", WorkerPackage.GetObjectHash(), SandboxPath);
}
CbPackage
@@ -540,6 +545,12 @@ LocalProcessRunner::GatherActionOutputs(std::filesystem::path SandboxPath)
}
void
+LocalProcessRunner::StartMonitorThread()
+{
+ m_MonitorThread = std::thread{&LocalProcessRunner::MonitorThreadFunction, this};
+}
+
+void
LocalProcessRunner::MonitorThreadFunction()
{
SetCurrentThreadName("LocalProcessRunner_Monitor");
diff --git a/src/zencompute/runners/localrunner.h b/src/zencompute/runners/localrunner.h
index b8cff6826..d6589db43 100644
--- a/src/zencompute/runners/localrunner.h
+++ b/src/zencompute/runners/localrunner.h
@@ -67,6 +67,7 @@ protected:
{
Ref<RunnerAction> Action;
void* ProcessHandle = nullptr;
+ int Pid = 0;
int ExitCode = 0;
std::filesystem::path SandboxPath;
@@ -83,8 +84,6 @@ protected:
std::filesystem::path m_SandboxPath;
int32_t m_MaxRunningActions = 64; // arbitrary limit for testing
- // if used in conjuction with m_ResultsLock, this lock must be taken *after*
- // m_ResultsLock to avoid deadlocks
RwLock m_RunningLock;
std::unordered_map<int, Ref<RunningAction>> m_RunningMap;
@@ -95,6 +94,7 @@ protected:
std::thread m_MonitorThread;
std::atomic<bool> m_MonitorThreadEnabled{true};
Event m_MonitorThreadEvent;
+ void StartMonitorThread();
void MonitorThreadFunction();
virtual void SweepRunningActions();
virtual void CancelRunningActions();
diff --git a/src/zencompute/runners/macrunner.cpp b/src/zencompute/runners/macrunner.cpp
index 5cec90699..c2ccca9a6 100644
--- a/src/zencompute/runners/macrunner.cpp
+++ b/src/zencompute/runners/macrunner.cpp
@@ -130,6 +130,8 @@ MacProcessRunner::MacProcessRunner(ChunkResolver& Resolver,
{
ZEN_INFO("Seatbelt sandboxing enabled for child processes");
}
+
+ StartMonitorThread();
}
SubmitResult
diff --git a/src/zencompute/runners/managedrunner.cpp b/src/zencompute/runners/managedrunner.cpp
new file mode 100644
index 000000000..e4a7ba388
--- /dev/null
+++ b/src/zencompute/runners/managedrunner.cpp
@@ -0,0 +1,279 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "managedrunner.h"
+
+#if ZEN_WITH_COMPUTE_SERVICES
+
+# include <zencore/compactbinary.h>
+# include <zencore/compactbinarypackage.h>
+# include <zencore/except_fmt.h>
+# include <zencore/filesystem.h>
+# include <zencore/fmtutils.h>
+# include <zencore/scopeguard.h>
+# include <zencore/timer.h>
+# include <zencore/trace.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+# include <asio/io_context.hpp>
+# include <asio/executor_work_guard.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+namespace zen::compute {
+
+using namespace std::literals;
+
+ManagedProcessRunner::ManagedProcessRunner(ChunkResolver& Resolver,
+ const std::filesystem::path& BaseDir,
+ DeferredDirectoryDeleter& Deleter,
+ WorkerThreadPool& WorkerPool,
+ int32_t MaxConcurrentActions)
+: LocalProcessRunner(Resolver, BaseDir, Deleter, WorkerPool, MaxConcurrentActions)
+, m_IoContext(std::make_unique<asio::io_context>())
+, m_SubprocessManager(std::make_unique<SubprocessManager>(*m_IoContext))
+{
+ m_ProcessGroup = m_SubprocessManager->CreateGroup("compute-workers");
+
+ // Run the io_context on a small thread pool so that exit callbacks and
+ // metrics sampling are dispatched without blocking each other.
+ for (int i = 0; i < kIoThreadCount; ++i)
+ {
+ m_IoThreads.emplace_back([this, i] {
+ SetCurrentThreadName(fmt::format("mrunner_{}", i));
+
+ // work_guard keeps run() alive even when there is no pending work yet
+ auto WorkGuard = asio::make_work_guard(*m_IoContext);
+
+ m_IoContext->run();
+ });
+ }
+}
+
+ManagedProcessRunner::~ManagedProcessRunner()
+{
+ try
+ {
+ Shutdown();
+ }
+ catch (std::exception& Ex)
+ {
+ ZEN_WARN("exception during managed process runner shutdown: {}", Ex.what());
+ }
+}
+
+void
+ManagedProcessRunner::Shutdown()
+{
+ ZEN_TRACE_CPU("ManagedProcessRunner::Shutdown");
+ m_AcceptNewActions = false;
+
+ CancelRunningActions();
+
+ // Tear down the SubprocessManager before stopping the io_context so that
+ // any in-flight callbacks are drained cleanly.
+ if (m_SubprocessManager)
+ {
+ m_SubprocessManager->DestroyGroup("compute-workers");
+ m_ProcessGroup = nullptr;
+ m_SubprocessManager.reset();
+ }
+
+ if (m_IoContext)
+ {
+ m_IoContext->stop();
+ }
+
+ for (std::thread& Thread : m_IoThreads)
+ {
+ if (Thread.joinable())
+ {
+ Thread.join();
+ }
+ }
+ m_IoThreads.clear();
+}
+
+SubmitResult
+ManagedProcessRunner::SubmitAction(Ref<RunnerAction> Action)
+{
+ ZEN_TRACE_CPU("ManagedProcessRunner::SubmitAction");
+ std::optional<PreparedAction> Prepared = PrepareActionSubmission(Action);
+
+ if (!Prepared)
+ {
+ return SubmitResult{.IsAccepted = false};
+ }
+
+ CbObject WorkerDescription = Prepared->WorkerPackage.GetObject();
+
+ // Parse environment variables from worker descriptor ("KEY=VALUE" strings)
+ // into the key-value pairs expected by CreateProcOptions.
+ std::vector<std::pair<std::string, std::string>> EnvPairs;
+ for (auto& It : WorkerDescription["environment"sv])
+ {
+ std::string_view Str = It.AsString();
+ size_t Eq = Str.find('=');
+ if (Eq != std::string_view::npos)
+ {
+ EnvPairs.emplace_back(std::string(Str.substr(0, Eq)), std::string(Str.substr(Eq + 1)));
+ }
+ }
+
+ // Build command line
+ std::string_view ExecPath = WorkerDescription["path"sv].AsString();
+ std::filesystem::path ExePath = Prepared->WorkerPath / std::filesystem::path(ExecPath).make_preferred();
+
+ std::string CommandLine = fmt::format("\"{}\" -Build=build.action"sv, ExePath.string());
+
+ ZEN_DEBUG("Executing (managed): '{}' (sandbox='{}')", CommandLine, Prepared->SandboxPath);
+
+ CreateProcOptions Options;
+ Options.WorkingDirectory = &Prepared->SandboxPath;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+ Options.Environment = std::move(EnvPairs);
+
+ const int32_t ActionLsn = Prepared->ActionLsn;
+
+ ManagedProcess* Proc = nullptr;
+
+ try
+ {
+ Proc = m_ProcessGroup->Spawn(ExePath, CommandLine, Options, [this, ActionLsn](ManagedProcess& /*Process*/, int ExitCode) {
+ OnProcessExit(ActionLsn, ExitCode);
+ });
+ }
+ catch (std::exception& Ex)
+ {
+ ZEN_ERROR("Failed to spawn process for action LSN {}: {}", ActionLsn, Ex.what());
+ m_DeferredDeleter.Enqueue(ActionLsn, std::move(Prepared->SandboxPath));
+ return SubmitResult{.IsAccepted = false};
+ }
+
+ {
+ Ref<RunningAction> NewAction{new RunningAction()};
+ NewAction->Action = Action;
+ NewAction->ProcessHandle = static_cast<void*>(Proc);
+ NewAction->Pid = Proc->Pid();
+ NewAction->SandboxPath = std::move(Prepared->SandboxPath);
+
+ RwLock::ExclusiveLockScope _(m_RunningLock);
+ m_RunningMap[ActionLsn] = std::move(NewAction);
+ }
+
+ Action->SetActionState(RunnerAction::State::Running);
+
+ ZEN_DEBUG("Managed runner: action LSN {} -> PID {}", ActionLsn, Proc->Pid());
+
+ return SubmitResult{.IsAccepted = true};
+}
+
+void
+ManagedProcessRunner::OnProcessExit(int ActionLsn, int ExitCode)
+{
+ ZEN_TRACE_CPU("ManagedProcessRunner::OnProcessExit");
+
+ Ref<RunningAction> Running;
+
+ m_RunningLock.WithExclusiveLock([&] {
+ auto It = m_RunningMap.find(ActionLsn);
+ if (It != m_RunningMap.end())
+ {
+ Running = std::move(It->second);
+ m_RunningMap.erase(It);
+ }
+ });
+
+ if (!Running)
+ {
+ return;
+ }
+
+ ZEN_DEBUG("Managed runner: action LSN {} + PID {} exited with code " ZEN_BRIGHT_WHITE("{}"), ActionLsn, Running->Pid, ExitCode);
+
+ Running->ExitCode = ExitCode;
+
+ // Capture final CPU metrics from the managed process before it is removed.
+ auto* Proc = static_cast<ManagedProcess*>(Running->ProcessHandle);
+ if (Proc)
+ {
+ ProcessMetrics Metrics = Proc->GetLatestMetrics();
+ float CpuMs = static_cast<float>(Metrics.UserTimeMs + Metrics.KernelTimeMs);
+ Running->Action->CpuSeconds.store(CpuMs / 1000.0f, std::memory_order_relaxed);
+
+ float CpuPct = Proc->GetCpuUsagePercent();
+ if (CpuPct >= 0.0f)
+ {
+ Running->Action->CpuUsagePercent.store(CpuPct, std::memory_order_relaxed);
+ }
+ }
+
+ Running->ProcessHandle = nullptr;
+
+ std::vector<Ref<RunningAction>> CompletedActions;
+ CompletedActions.push_back(std::move(Running));
+ ProcessCompletedActions(CompletedActions);
+}
+
+void
+ManagedProcessRunner::CancelRunningActions()
+{
+ ZEN_TRACE_CPU("ManagedProcessRunner::CancelRunningActions");
+
+ std::unordered_map<int, Ref<RunningAction>> RunningMap;
+ m_RunningLock.WithExclusiveLock([&] { std::swap(RunningMap, m_RunningMap); });
+
+ if (RunningMap.empty())
+ {
+ return;
+ }
+
+ ZEN_INFO("cancelling {} running actions via process group", RunningMap.size());
+
+ Stopwatch Timer;
+
+ // Kill all processes in the group atomically (TerminateJobObject on Windows,
+ // SIGTERM+SIGKILL on POSIX).
+ if (m_ProcessGroup)
+ {
+ m_ProcessGroup->KillAll();
+ }
+
+ for (auto& [Lsn, Running] : RunningMap)
+ {
+ m_DeferredDeleter.Enqueue(Running->Action->ActionLsn, std::move(Running->SandboxPath));
+ Running->Action->SetActionState(RunnerAction::State::Failed);
+ }
+
+ ZEN_INFO("DONE - cancelled {} running processes (took {})", RunningMap.size(), NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
+}
+
+bool
+ManagedProcessRunner::CancelAction(int ActionLsn)
+{
+ ZEN_TRACE_CPU("ManagedProcessRunner::CancelAction");
+
+ ManagedProcess* Proc = nullptr;
+
+ m_RunningLock.WithSharedLock([&] {
+ auto It = m_RunningMap.find(ActionLsn);
+ if (It != m_RunningMap.end() && It->second->ProcessHandle != nullptr)
+ {
+ Proc = static_cast<ManagedProcess*>(It->second->ProcessHandle);
+ }
+ });
+
+ if (!Proc)
+ {
+ return false;
+ }
+
+ // Terminate the process. The exit callback will handle the rest
+ // (remove from running map, gather outputs or mark failed).
+ Proc->Terminate(222);
+
+ ZEN_DEBUG("CancelAction: initiated cancellation of LSN {}", ActionLsn);
+ return true;
+}
+
+} // namespace zen::compute
+
+#endif
diff --git a/src/zencompute/runners/managedrunner.h b/src/zencompute/runners/managedrunner.h
new file mode 100644
index 000000000..21a44d43c
--- /dev/null
+++ b/src/zencompute/runners/managedrunner.h
@@ -0,0 +1,64 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "localrunner.h"
+
+#if ZEN_WITH_COMPUTE_SERVICES
+
+# include <zenutil/process/subprocessmanager.h>
+
+# include <memory>
+
+namespace asio {
+class io_context;
+}
+
+namespace zen::compute {
+
+/** Cross-platform process runner backed by SubprocessManager.
+
+ Subclasses LocalProcessRunner, reusing sandbox management, worker manifesting,
+ input/output handling, and shared action preparation. Replaces the polling-based
+ monitor thread with async exit callbacks driven by SubprocessManager, and
+ delegates CPU/memory metrics sampling to the manager's built-in round-robin
+ sampler.
+
+ A ProcessGroup (backed by a JobObject on Windows, process group on POSIX) is
+ used for bulk cancellation on shutdown.
+
+ This runner does not perform any platform-specific sandboxing (AppContainer,
+ namespaces, Seatbelt). It is intended as a simpler, cross-platform alternative
+ to the platform-specific runners for non-sandboxed workloads.
+ */
+class ManagedProcessRunner : public LocalProcessRunner
+{
+public:
+ ManagedProcessRunner(ChunkResolver& Resolver,
+ const std::filesystem::path& BaseDir,
+ DeferredDirectoryDeleter& Deleter,
+ WorkerThreadPool& WorkerPool,
+ int32_t MaxConcurrentActions = 0);
+ ~ManagedProcessRunner();
+
+ void Shutdown() override;
+ [[nodiscard]] SubmitResult SubmitAction(Ref<RunnerAction> Action) override;
+ void CancelRunningActions() override;
+ bool CancelAction(int ActionLsn) override;
+ [[nodiscard]] bool IsHealthy() override { return true; }
+
+private:
+ static constexpr int kIoThreadCount = 4;
+
+ // Exit callback posted on an io_context thread.
+ void OnProcessExit(int ActionLsn, int ExitCode);
+
+ std::unique_ptr<asio::io_context> m_IoContext;
+ std::unique_ptr<SubprocessManager> m_SubprocessManager;
+ ProcessGroup* m_ProcessGroup = nullptr;
+ std::vector<std::thread> m_IoThreads;
+};
+
+} // namespace zen::compute
+
+#endif
diff --git a/src/zencompute/runners/windowsrunner.cpp b/src/zencompute/runners/windowsrunner.cpp
index e9a1ae8b6..92ee65c2d 100644
--- a/src/zencompute/runners/windowsrunner.cpp
+++ b/src/zencompute/runners/windowsrunner.cpp
@@ -21,6 +21,12 @@ ZEN_THIRD_PARTY_INCLUDES_START
# include <sddl.h>
ZEN_THIRD_PARTY_INCLUDES_END
+// JOB_OBJECT_UILIMIT_ERRORMODE is defined in winuser.h which may be
+// excluded by WIN32_LEAN_AND_MEAN.
+# if !defined(JOB_OBJECT_UILIMIT_ERRORMODE)
+# define JOB_OBJECT_UILIMIT_ERRORMODE 0x00000400
+# endif
+
namespace zen::compute {
using namespace std::literals;
@@ -34,38 +40,65 @@ WindowsProcessRunner::WindowsProcessRunner(ChunkResolver& Resolver,
: LocalProcessRunner(Resolver, BaseDir, Deleter, WorkerPool, MaxConcurrentActions)
, m_Sandboxed(Sandboxed)
{
- if (!m_Sandboxed)
+ // Create a job object shared by all child processes. Restricting the
+ // error-mode UI prevents crash dialogs (WER / Dr. Watson) from
+ // blocking the monitor thread when a worker process terminates
+ // abnormally.
+ m_JobObject = CreateJobObjectW(nullptr, nullptr);
+ if (m_JobObject)
{
- return;
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtLimits{};
+ ExtLimits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;
+ SetInformationJobObject(m_JobObject, JobObjectExtendedLimitInformation, &ExtLimits, sizeof(ExtLimits));
+
+ JOBOBJECT_BASIC_UI_RESTRICTIONS UiRestrictions{};
+ UiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_ERRORMODE;
+ SetInformationJobObject(m_JobObject, JobObjectBasicUIRestrictions, &UiRestrictions, sizeof(UiRestrictions));
+
+ // Set error mode on this process so children inherit it. The
+ // UILIMIT_ERRORMODE restriction above prevents them from clearing
+ // SEM_NOGPFAULTERRORBOX.
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
}
- // Build a unique profile name per process to avoid collisions
- m_AppContainerName = L"zenserver-sandbox-" + std::to_wstring(GetCurrentProcessId());
+ if (m_Sandboxed)
+ {
+ // Build a unique profile name per process to avoid collisions
+ m_AppContainerName = L"zenserver-sandbox-" + std::to_wstring(GetCurrentProcessId());
- // Clean up any stale profile from a previous crash
- DeleteAppContainerProfile(m_AppContainerName.c_str());
+ // Clean up any stale profile from a previous crash
+ DeleteAppContainerProfile(m_AppContainerName.c_str());
- PSID Sid = nullptr;
+ PSID Sid = nullptr;
- HRESULT Hr = CreateAppContainerProfile(m_AppContainerName.c_str(),
- m_AppContainerName.c_str(), // display name
- m_AppContainerName.c_str(), // description
- nullptr, // no capabilities
- 0, // capability count
- &Sid);
+ HRESULT Hr = CreateAppContainerProfile(m_AppContainerName.c_str(),
+ m_AppContainerName.c_str(), // display name
+ m_AppContainerName.c_str(), // description
+ nullptr, // no capabilities
+ 0, // capability count
+ &Sid);
- if (FAILED(Hr))
- {
- throw zen::runtime_error("CreateAppContainerProfile failed: HRESULT 0x{:08X}", static_cast<uint32_t>(Hr));
- }
+ if (FAILED(Hr))
+ {
+ throw zen::runtime_error("CreateAppContainerProfile failed: HRESULT 0x{:08X}", static_cast<uint32_t>(Hr));
+ }
- m_AppContainerSid = Sid;
+ m_AppContainerSid = Sid;
+
+ ZEN_INFO("AppContainer sandboxing enabled for child processes (profile={})", WideToUtf8(m_AppContainerName));
+ }
- ZEN_INFO("AppContainer sandboxing enabled for child processes (profile={})", WideToUtf8(m_AppContainerName));
+ StartMonitorThread();
}
WindowsProcessRunner::~WindowsProcessRunner()
{
+ if (m_JobObject)
+ {
+ CloseHandle(m_JobObject);
+ m_JobObject = nullptr;
+ }
+
if (m_AppContainerSid)
{
FreeSid(m_AppContainerSid);
@@ -172,9 +205,9 @@ WindowsProcessRunner::SubmitAction(Ref<RunnerAction> Action)
LPSECURITY_ATTRIBUTES lpProcessAttributes = nullptr;
LPSECURITY_ATTRIBUTES lpThreadAttributes = nullptr;
BOOL bInheritHandles = FALSE;
- DWORD dwCreationFlags = 0;
+ DWORD dwCreationFlags = CREATE_SUSPENDED | DETACHED_PROCESS;
- ZEN_DEBUG("Executing: {} (sandboxed={})", WideToUtf8(CommandLine.c_str()), m_Sandboxed);
+ ZEN_DEBUG("{}: '{}' (sandbox='{}')", m_Sandboxed ? "Sandboxing" : "Executing", WideToUtf8(CommandLine.c_str()), Prepared->SandboxPath);
CommandLine.EnsureNulTerminated();
@@ -260,14 +293,21 @@ WindowsProcessRunner::SubmitAction(Ref<RunnerAction> Action)
}
}
- CloseHandle(ProcessInformation.hThread);
+ if (m_JobObject)
+ {
+ AssignProcessToJobObject(m_JobObject, ProcessInformation.hProcess);
+ }
- Ref<RunningAction> NewAction{new RunningAction()};
- NewAction->Action = Action;
- NewAction->ProcessHandle = ProcessInformation.hProcess;
- NewAction->SandboxPath = std::move(Prepared->SandboxPath);
+ ResumeThread(ProcessInformation.hThread);
+ CloseHandle(ProcessInformation.hThread);
{
+ Ref<RunningAction> NewAction{new RunningAction()};
+ NewAction->Action = Action;
+ NewAction->ProcessHandle = ProcessInformation.hProcess;
+ NewAction->Pid = ProcessInformation.dwProcessId;
+ NewAction->SandboxPath = std::move(Prepared->SandboxPath);
+
RwLock::ExclusiveLockScope _(m_RunningLock);
m_RunningMap[Prepared->ActionLsn] = std::move(NewAction);
@@ -275,6 +315,8 @@ WindowsProcessRunner::SubmitAction(Ref<RunnerAction> Action)
Action->SetActionState(RunnerAction::State::Running);
+ ZEN_DEBUG("Local runner: action LSN {} -> PID {}", Action->ActionLsn, ProcessInformation.dwProcessId);
+
return SubmitResult{.IsAccepted = true};
}
@@ -294,6 +336,11 @@ WindowsProcessRunner::SweepRunningActions()
if (IsSuccess && ExitCode != STILL_ACTIVE)
{
+ ZEN_DEBUG("Local runner: action LSN {} + PID {} exited with code " ZEN_BRIGHT_WHITE("{}"),
+ Running->Action->ActionLsn,
+ Running->Pid,
+ ExitCode);
+
CloseHandle(Running->ProcessHandle);
Running->ProcessHandle = INVALID_HANDLE_VALUE;
Running->ExitCode = ExitCode;
diff --git a/src/zencompute/runners/windowsrunner.h b/src/zencompute/runners/windowsrunner.h
index 9f2385cc4..adeaf02fc 100644
--- a/src/zencompute/runners/windowsrunner.h
+++ b/src/zencompute/runners/windowsrunner.h
@@ -46,6 +46,7 @@ private:
bool m_Sandboxed = false;
PSID m_AppContainerSid = nullptr;
std::wstring m_AppContainerName;
+ HANDLE m_JobObject = nullptr;
};
} // namespace zen::compute
diff --git a/src/zencompute/runners/winerunner.cpp b/src/zencompute/runners/winerunner.cpp
index 506bec73b..b4fafb467 100644
--- a/src/zencompute/runners/winerunner.cpp
+++ b/src/zencompute/runners/winerunner.cpp
@@ -36,6 +36,8 @@ WineProcessRunner::WineProcessRunner(ChunkResolver& Resolver,
sigemptyset(&Action.sa_mask);
Action.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &Action, nullptr);
+
+ StartMonitorThread();
}
SubmitResult
diff --git a/src/zencore/compactbinarypackage.cpp b/src/zencore/compactbinarypackage.cpp
index 56a292ca6..cd268745c 100644
--- a/src/zencore/compactbinarypackage.cpp
+++ b/src/zencore/compactbinarypackage.cpp
@@ -684,14 +684,22 @@ namespace legacy {
Writer.Save(Ar);
}
- bool TryLoadCbPackage(CbPackage& Package, IoBuffer InBuffer, BufferAllocator Allocator, CbPackage::AttachmentResolver* Mapper)
+ bool TryLoadCbPackage(CbPackage& Package,
+ IoBuffer InBuffer,
+ BufferAllocator Allocator,
+ CbPackage::AttachmentResolver* Mapper,
+ bool ValidateHashes)
{
BinaryReader Reader(InBuffer.Data(), InBuffer.Size());
- return TryLoadCbPackage(Package, Reader, Allocator, Mapper);
+ return TryLoadCbPackage(Package, Reader, Allocator, Mapper, ValidateHashes);
}
- bool TryLoadCbPackage(CbPackage& Package, BinaryReader& Reader, BufferAllocator Allocator, CbPackage::AttachmentResolver* Mapper)
+ bool TryLoadCbPackage(CbPackage& Package,
+ BinaryReader& Reader,
+ BufferAllocator Allocator,
+ CbPackage::AttachmentResolver* Mapper,
+ bool ValidateHashes)
{
Package = CbPackage();
for (;;)
@@ -708,7 +716,11 @@ namespace legacy {
if (ValueField.IsBinary())
{
const MemoryView View = ValueField.AsBinaryView();
- if (View.GetSize() > 0)
+ if (View.GetSize() == 0)
+ {
+ return false;
+ }
+ else
{
SharedBuffer Buffer = SharedBuffer::MakeView(View, ValueField.GetOuterBuffer()).MakeOwned();
CbField HashField = LoadCompactBinary(Reader, Allocator);
@@ -748,7 +760,11 @@ namespace legacy {
{
const IoHash Hash = ValueField.AsHash();
- ZEN_ASSERT(Mapper);
+ if (!Mapper)
+ {
+ return false;
+ }
+
if (SharedBuffer AttachmentData = (*Mapper)(Hash))
{
IoHash RawHash;
@@ -763,6 +779,10 @@ namespace legacy {
}
else
{
+ if (ValidateHashes && IoHash::HashBuffer(AttachmentData) != Hash)
+ {
+ return false;
+ }
const CbValidateError ValidationResult = ValidateCompactBinary(AttachmentData.GetView(), CbValidateMode::All);
if (ValidationResult != CbValidateError::None)
{
@@ -801,13 +821,13 @@ namespace legacy {
#if ZEN_WITH_TESTS
void
-usonpackage_forcelink()
+cbpackage_forcelink()
{
}
TEST_SUITE_BEGIN("core.compactbinarypackage");
-TEST_CASE("usonpackage")
+TEST_CASE("cbpackage")
{
using namespace std::literals;
@@ -997,7 +1017,7 @@ TEST_CASE("usonpackage")
}
}
-TEST_CASE("usonpackage.serialization")
+TEST_CASE("cbpackage.serialization")
{
using namespace std::literals;
@@ -1303,7 +1323,7 @@ TEST_CASE("usonpackage.serialization")
}
}
-TEST_CASE("usonpackage.invalidpackage")
+TEST_CASE("cbpackage.invalidpackage")
{
const auto TestLoad = [](std::initializer_list<uint8_t> RawData, BufferAllocator Allocator = UniqueBuffer::Alloc) {
const MemoryView RawView = MakeMemoryView(RawData);
@@ -1345,6 +1365,90 @@ TEST_CASE("usonpackage.invalidpackage")
}
}
+TEST_CASE("cbpackage.legacy.invalidpackage")
+{
+ const auto TestLegacyLoad = [](std::initializer_list<uint8_t> RawData) {
+ const MemoryView RawView = MakeMemoryView(RawData);
+ IoBuffer Buffer(IoBuffer::Wrap, const_cast<void*>(RawView.GetData()), RawView.GetSize());
+ CbPackage Package;
+ CHECK_FALSE(legacy::TryLoadCbPackage(Package, Buffer, &UniqueBuffer::Alloc));
+ };
+
+ SUBCASE("Empty") { TestLegacyLoad({}); }
+
+ SUBCASE("Zero size binary rejects")
+ {
+ // A binary field with zero payload size should be rejected (would desync the reader)
+ BinaryWriter Writer;
+ CbWriter Cb;
+ Cb.AddBinary(MemoryView()); // zero-size binary
+ Cb.Save(Writer);
+
+ IoBuffer Buffer(IoBuffer::Wrap, const_cast<void*>(MakeMemoryView(Writer).GetData()), MakeMemoryView(Writer).GetSize());
+ CbPackage Package;
+ CHECK_FALSE(legacy::TryLoadCbPackage(Package, Buffer, &UniqueBuffer::Alloc));
+ }
+}
+
+TEST_CASE("cbpackage.legacy.hashresolution")
+{
+ // Build a valid legacy package with an object, then round-trip it
+ CbObjectWriter RootWriter;
+ RootWriter.AddString("name", "test");
+ CbObject RootObject = RootWriter.Save();
+
+ CbAttachment ObjectAttach(RootObject);
+
+ CbPackage OriginalPkg;
+ OriginalPkg.SetObject(RootObject);
+ OriginalPkg.AddAttachment(ObjectAttach);
+
+ BinaryWriter Writer;
+ legacy::SaveCbPackage(OriginalPkg, Writer);
+
+ IoBuffer Buffer(IoBuffer::Wrap, const_cast<void*>(MakeMemoryView(Writer).GetData()), MakeMemoryView(Writer).GetSize());
+ CbPackage LoadedPkg;
+ CHECK(legacy::TryLoadCbPackage(LoadedPkg, Buffer, &UniqueBuffer::Alloc));
+
+ // The hash-only path requires a mapper — without one it should fail
+ CbWriter HashOnlyCb;
+ HashOnlyCb.AddHash(ObjectAttach.GetHash());
+ HashOnlyCb.AddNull();
+ BinaryWriter HashOnlyWriter;
+ HashOnlyCb.Save(HashOnlyWriter);
+
+ IoBuffer HashOnlyBuffer(IoBuffer::Wrap,
+ const_cast<void*>(MakeMemoryView(HashOnlyWriter).GetData()),
+ MakeMemoryView(HashOnlyWriter).GetSize());
+ CbPackage HashOnlyPkg;
+ CHECK_FALSE(legacy::TryLoadCbPackage(HashOnlyPkg, HashOnlyBuffer, &UniqueBuffer::Alloc, nullptr));
+
+ // With a mapper that returns valid data, it should succeed
+ CbPackage::AttachmentResolver Resolver = [&](const IoHash& Hash) -> SharedBuffer {
+ if (Hash == ObjectAttach.GetHash())
+ {
+ return RootObject.GetBuffer();
+ }
+ return {};
+ };
+ CHECK(legacy::TryLoadCbPackage(HashOnlyPkg, HashOnlyBuffer, &UniqueBuffer::Alloc, &Resolver));
+
+ // Build a different but structurally valid CbObject to use as mismatched data
+ CbObjectWriter DifferentWriter;
+ DifferentWriter.AddString("name", "different");
+ CbObject DifferentObject = DifferentWriter.Save();
+
+ CbPackage::AttachmentResolver BadResolver = [&](const IoHash&) -> SharedBuffer { return DifferentObject.GetBuffer(); };
+ CbPackage BadPkg;
+
+ // With ValidateHashes enabled and a mapper that returns mismatched data, it should fail
+ CHECK_FALSE(legacy::TryLoadCbPackage(BadPkg, HashOnlyBuffer, &UniqueBuffer::Alloc, &BadResolver, /*ValidateHashes*/ true));
+
+ // Without ValidateHashes, the mismatched data is accepted (structure is still valid CB)
+ CbPackage UncheckedPkg;
+ CHECK(legacy::TryLoadCbPackage(UncheckedPkg, HashOnlyBuffer, &UniqueBuffer::Alloc, &BadResolver, /*ValidateHashes*/ false));
+}
+
TEST_SUITE_END();
#endif
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index 0d361801f..a63594be9 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -3275,14 +3275,25 @@ MakeSafeAbsolutePathInPlace(std::filesystem::path& Path)
{
if (!Path.empty())
{
- std::filesystem::path AbsolutePath = std::filesystem::absolute(Path).make_preferred();
+ Path = std::filesystem::absolute(Path).make_preferred();
#if ZEN_PLATFORM_WINDOWS
- const std::string_view Prefix = "\\\\?\\";
- const std::u8string PrefixU8(Prefix.begin(), Prefix.end());
- std::u8string PathString = AbsolutePath.u8string();
- if (!PathString.empty() && !PathString.starts_with(PrefixU8))
+ const std::u8string_view LongPathPrefix = u8"\\\\?\\";
+ const std::u8string_view UncPrefix = u8"\\\\";
+ const std::u8string_view LongPathUncPrefix = u8"\\\\?\\UNC\\";
+
+ std::u8string PathString = Path.u8string();
+ if (!PathString.empty() && !PathString.starts_with(LongPathPrefix))
{
- PathString.insert(0, PrefixU8);
+ if (PathString.starts_with(UncPrefix))
+ {
+ // UNC path: \\server\share → \\?\UNC\server\share
+ PathString.replace(0, UncPrefix.size(), LongPathUncPrefix);
+ }
+ else
+ {
+ // Local path: C:\foo → \\?\C:\foo
+ PathString.insert(0, LongPathPrefix);
+ }
Path = PathString;
}
#endif // ZEN_PLATFORM_WINDOWS
@@ -4049,6 +4060,54 @@ TEST_CASE("SharedMemory")
CHECK(!OpenSharedMemory("SharedMemoryTest0", 482, false));
}
+TEST_CASE("filesystem.MakeSafeAbsolutePath")
+{
+# if ZEN_PLATFORM_WINDOWS
+ // Local path gets \\?\ prefix
+ {
+ std::filesystem::path Local = MakeSafeAbsolutePath("C:\\Users\\test");
+ CHECK(Local.u8string().starts_with(u8"\\\\?\\"));
+ CHECK(Local.u8string().find(u8"C:\\Users\\test") != std::u8string::npos);
+ }
+
+ // UNC path gets \\?\UNC\ prefix
+ {
+ std::filesystem::path Unc = MakeSafeAbsolutePath("\\\\server\\share\\path");
+ std::u8string UncStr = Unc.u8string();
+ CHECK_MESSAGE(UncStr.starts_with(u8"\\\\?\\UNC\\"), fmt::format("Expected \\\\?\\UNC\\ prefix, got '{}'", Unc));
+ CHECK_MESSAGE(UncStr.find(u8"server\\share\\path") != std::u8string::npos,
+ fmt::format("Expected server\\share\\path in '{}'", Unc));
+ // Must NOT produce \\?\\\server (double backslash after \\?\)
+ CHECK_MESSAGE(UncStr.find(u8"\\\\?\\\\\\") == std::u8string::npos,
+ fmt::format("Path contains invalid double-backslash after prefix: '{}'", Unc));
+ }
+
+ // Already-prefixed path is not double-prefixed
+ {
+ std::filesystem::path Already = MakeSafeAbsolutePath("\\\\?\\C:\\already\\prefixed");
+ size_t Count = 0;
+ std::u8string Str = Already.u8string();
+ for (size_t Pos = Str.find(u8"\\\\?\\"); Pos != std::u8string::npos; Pos = Str.find(u8"\\\\?\\", Pos + 1))
+ {
+ ++Count;
+ }
+ CHECK_EQ(Count, 1);
+ }
+
+ // Already-prefixed UNC path is not double-prefixed
+ {
+ std::filesystem::path AlreadyUnc = MakeSafeAbsolutePath("\\\\?\\UNC\\server\\share");
+ size_t Count = 0;
+ std::u8string Str = AlreadyUnc.u8string();
+ for (size_t Pos = Str.find(u8"\\\\?\\"); Pos != std::u8string::npos; Pos = Str.find(u8"\\\\?\\", Pos + 1))
+ {
+ ++Count;
+ }
+ CHECK_EQ(Count, 1);
+ }
+# endif // ZEN_PLATFORM_WINDOWS
+}
+
TEST_SUITE_END();
#endif
diff --git a/src/zencore/include/zencore/compactbinarypackage.h b/src/zencore/include/zencore/compactbinarypackage.h
index 64b62e2c0..148c0d3fd 100644
--- a/src/zencore/include/zencore/compactbinarypackage.h
+++ b/src/zencore/include/zencore/compactbinarypackage.h
@@ -278,10 +278,10 @@ public:
* @return The attachment, or null if the attachment is not found.
* @note The returned pointer is only valid until the attachments on this package are modified.
*/
- const CbAttachment* FindAttachment(const IoHash& Hash) const;
+ [[nodiscard]] const CbAttachment* FindAttachment(const IoHash& Hash) const;
/** Find an attachment if it exists in the package. */
- inline const CbAttachment* FindAttachment(const CbAttachment& Attachment) const { return FindAttachment(Attachment.GetHash()); }
+ [[nodiscard]] const CbAttachment* FindAttachment(const CbAttachment& Attachment) const { return FindAttachment(Attachment.GetHash()); }
/** Add the attachment to this package. */
inline void AddAttachment(const CbAttachment& Attachment) { AddAttachment(Attachment, nullptr); }
@@ -336,17 +336,26 @@ private:
IoHash ObjectHash;
};
+/** In addition to the above, we also support a legacy format which is used by
+ * the HTTP project store for historical reasons. Don't use the below functions
+ * for new code.
+ */
namespace legacy {
void SaveCbAttachment(const CbAttachment& Attachment, CbWriter& Writer);
void SaveCbPackage(const CbPackage& Package, CbWriter& Writer);
void SaveCbPackage(const CbPackage& Package, BinaryWriter& Ar);
- bool TryLoadCbPackage(CbPackage& Package, IoBuffer Buffer, BufferAllocator Allocator, CbPackage::AttachmentResolver* Mapper = nullptr);
+ bool TryLoadCbPackage(CbPackage& Package,
+ IoBuffer Buffer,
+ BufferAllocator Allocator,
+ CbPackage::AttachmentResolver* Mapper = nullptr,
+ bool ValidateHashes = false);
bool TryLoadCbPackage(CbPackage& Package,
BinaryReader& Reader,
BufferAllocator Allocator,
- CbPackage::AttachmentResolver* Mapper = nullptr);
+ CbPackage::AttachmentResolver* Mapper = nullptr,
+ bool ValidateHashes = false);
} // namespace legacy
-void usonpackage_forcelink(); // internal
+void cbpackage_forcelink(); // internal
} // namespace zen
diff --git a/src/zencore/include/zencore/fmtutils.h b/src/zencore/include/zencore/fmtutils.h
index 404e570fd..4ec05f901 100644
--- a/src/zencore/include/zencore/fmtutils.h
+++ b/src/zencore/include/zencore/fmtutils.h
@@ -15,6 +15,29 @@ ZEN_THIRD_PARTY_INCLUDES_END
#include <chrono>
#include <string_view>
+// Generic formatter for any type with a free ToString(T) function returning a
+// string-like type. This covers enum-to-string conversions (HttpResponseCode,
+// SessionState, etc.) without needing per-type fmt::formatter specializations.
+// ADL is used to find ToString, so it works across namespaces.
+
+template<typename T>
+concept HasFreeToString = requires(const T& v)
+{
+ {
+ ToString(v)
+ } -> std::convertible_to<std::string_view>;
+};
+
+template<HasFreeToString T>
+struct fmt::formatter<T> : fmt::formatter<std::string_view>
+{
+ template<typename FormatContext>
+ auto format(const T& Value, FormatContext& Ctx) const
+ {
+ return fmt::formatter<std::string_view>::format(ToString(Value), Ctx);
+ }
+};
+
// Custom formatting for some zencore types
template<typename T>
diff --git a/src/zencore/include/zencore/logging.h b/src/zencore/include/zencore/logging.h
index 3427991d2..1608ad523 100644
--- a/src/zencore/include/zencore/logging.h
+++ b/src/zencore/include/zencore/logging.h
@@ -90,6 +90,34 @@ using zen::ConsoleLog;
using zen::ErrorLog;
using zen::Log;
+////////////////////////////////////////////////////////////////////////
+// Color helpers
+
+#define ZEN_RED(str) "\033[31m" str "\033[0m"
+#define ZEN_GREEN(str) "\033[32m" str "\033[0m"
+#define ZEN_YELLOW(str) "\033[33m" str "\033[0m"
+#define ZEN_BLUE(str) "\033[34m" str "\033[0m"
+#define ZEN_MAGENTA(str) "\033[35m" str "\033[0m"
+#define ZEN_CYAN(str) "\033[36m" str "\033[0m"
+#define ZEN_WHITE(str) "\033[37m" str "\033[0m"
+
+#define ZEN_BRIGHT_RED(str) "\033[91m" str "\033[0m"
+#define ZEN_BRIGHT_GREEN(str) "\033[92m" str "\033[0m"
+#define ZEN_BRIGHT_YELLOW(str) "\033[93m" str "\033[0m"
+#define ZEN_BRIGHT_BLUE(str) "\033[94m" str "\033[0m"
+#define ZEN_BRIGHT_MAGENTA(str) "\033[95m" str "\033[0m"
+#define ZEN_BRIGHT_CYAN(str) "\033[96m" str "\033[0m"
+#define ZEN_BRIGHT_WHITE(str) "\033[97m" str "\033[0m"
+
+#define ZEN_BOLD(str) "\033[1m" str "\033[0m"
+#define ZEN_UNDERLINE(str) "\033[4m" str "\033[0m"
+#define ZEN_DIM(str) "\033[2m" str "\033[0m"
+#define ZEN_ITALIC(str) "\033[3m" str "\033[0m"
+#define ZEN_STRIKETHROUGH(str) "\033[9m" str "\033[0m"
+#define ZEN_INVERSE(str) "\033[7m" str "\033[0m"
+
+////////////////////////////////////////////////////////////////////////
+
#if ZEN_BUILD_DEBUG
# define ZEN_CHECK_FORMAT_STRING(fmtstr, ...) \
while (false) \
diff --git a/src/zencore/include/zencore/logging/broadcastsink.h b/src/zencore/include/zencore/logging/broadcastsink.h
new file mode 100644
index 000000000..c2709d87c
--- /dev/null
+++ b/src/zencore/include/zencore/logging/broadcastsink.h
@@ -0,0 +1,86 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/logging/sink.h>
+#include <zencore/thread.h>
+
+#include <algorithm>
+#include <vector>
+
+namespace zen::logging {
+
+/// A sink that broadcasts log messages to a dynamic list of child sinks.
+///
+/// BroadcastSink acts as a shared indirection point: multiple Loggers can
+/// reference the same BroadcastSink instance, and adding or removing a child
+/// sink is immediately visible to all of them. This is the recommended way
+/// to manage "default" sinks that should be active on most loggers.
+///
+/// Each child sink owns its own Formatter — BroadcastSink::SetFormatter() is
+/// intentionally a no-op so that per-sink formatting is not accidentally
+/// overwritten by registry-wide formatter changes.
+class BroadcastSink : public Sink
+{
+public:
+ BroadcastSink() = default;
+ explicit BroadcastSink(std::vector<SinkPtr> InSinks) : m_Sinks(std::move(InSinks)) {}
+
+ void Log(const LogMessage& Msg) override
+ {
+ RwLock::SharedLockScope Lock(m_Lock);
+ for (auto& Child : m_Sinks)
+ {
+ if (Child->ShouldLog(Msg.GetLevel()))
+ {
+ try
+ {
+ Child->Log(Msg);
+ }
+ catch (const std::exception&)
+ {
+ // logging here would be sketchy since we could cause a recursive loop
+ // if we wanted to surface this error, we would need to have some sort
+ // of internal error handling mechanism that doesn't rely on sinks
+ }
+ }
+ }
+ }
+
+ void Flush() override
+ {
+ RwLock::SharedLockScope Lock(m_Lock);
+ for (auto& Child : m_Sinks)
+ {
+ try
+ {
+ Child->Flush();
+ }
+ catch (const std::exception&)
+ {
+ // must not log here (see above)
+ }
+ }
+ }
+
+ /// No-op — child sinks manage their own formatters.
+ void SetFormatter(std::unique_ptr<Formatter> /*InFormatter*/) override {}
+
+ void AddSink(SinkPtr InSink)
+ {
+ RwLock::ExclusiveLockScope Lock(m_Lock);
+ m_Sinks.push_back(std::move(InSink));
+ }
+
+ void RemoveSink(const SinkPtr& InSink)
+ {
+ RwLock::ExclusiveLockScope Lock(m_Lock);
+ m_Sinks.erase(std::remove(m_Sinks.begin(), m_Sinks.end(), InSink), m_Sinks.end());
+ }
+
+private:
+ RwLock m_Lock;
+ std::vector<SinkPtr> m_Sinks;
+};
+
+} // namespace zen::logging
diff --git a/src/zencore/include/zencore/logging/logger.h b/src/zencore/include/zencore/logging/logger.h
index c94bc58fa..1706a4455 100644
--- a/src/zencore/include/zencore/logging/logger.h
+++ b/src/zencore/include/zencore/logging/logger.h
@@ -21,7 +21,6 @@ class Logger final : public LoggerBase
{
public:
Logger(std::string_view InName, SinkPtr InSink);
- Logger(std::string_view InName, std::span<const SinkPtr> InSinks);
~Logger();
Logger(const Logger&) = delete;
@@ -31,8 +30,7 @@ public:
std::string_view Name() const;
- void SetSinks(std::vector<SinkPtr> InSinks);
- void AddSink(SinkPtr InSink);
+ void SetSink(SinkPtr InSink);
void SetFormatter(std::unique_ptr<Formatter> InFormatter);
diff --git a/src/zencore/include/zencore/logging/logmsg.h b/src/zencore/include/zencore/logging/logmsg.h
index a1acb503b..4a777c71e 100644
--- a/src/zencore/include/zencore/logging/logmsg.h
+++ b/src/zencore/include/zencore/logging/logmsg.h
@@ -41,22 +41,14 @@ struct LogMessage
void SetSource(const SourceLocation& InSource) { m_Source = InSource; }
private:
- static constexpr LogPoint s_DefaultPoints[LogLevelCount] = {
- {{}, Trace, {}},
- {{}, Debug, {}},
- {{}, Info, {}},
- {{}, Warn, {}},
- {{}, Err, {}},
- {{}, Critical, {}},
- {{}, Off, {}},
- };
+ static constexpr LogPoint s_DefaultPoint{{}, Off, {}};
std::string_view m_LoggerName;
LogLevel m_Level = Off;
std::chrono::system_clock::time_point m_Time;
SourceLocation m_Source;
std::string_view m_Payload;
- const LogPoint* m_Point = &s_DefaultPoints[Off];
+ const LogPoint* m_Point = &s_DefaultPoint;
int m_ThreadId = 0;
};
diff --git a/src/zencore/include/zencore/logging/sink.h b/src/zencore/include/zencore/logging/sink.h
index 172176a4e..3e6a1deed 100644
--- a/src/zencore/include/zencore/logging/sink.h
+++ b/src/zencore/include/zencore/logging/sink.h
@@ -11,6 +11,11 @@
namespace zen::logging {
+/// Base class for log sinks.
+///
+/// Log() and Flush() may be called concurrently from multiple threads.
+/// Implementations must provide their own synchronization (e.g. a mutex
+/// or RwLock) to protect any mutable state including the formatter.
class Sink : public RefCounted
{
public:
diff --git a/src/zencore/include/zencore/memory/fmalloc.h b/src/zencore/include/zencore/memory/fmalloc.h
index c50a9729c..8ce4f7acd 100644
--- a/src/zencore/include/zencore/memory/fmalloc.h
+++ b/src/zencore/include/zencore/memory/fmalloc.h
@@ -151,6 +151,8 @@ public:
virtual void Trim(bool bTrimThreadCaches);
+ virtual const char* GetName() const = 0;
+
virtual void OutOfMemory(size_t Size, uint32_t Alignment);
};
diff --git a/src/zencore/include/zencore/memory/mallocansi.h b/src/zencore/include/zencore/memory/mallocansi.h
index 510695c8c..cbc69caed 100644
--- a/src/zencore/include/zencore/memory/mallocansi.h
+++ b/src/zencore/include/zencore/memory/mallocansi.h
@@ -20,12 +20,13 @@ class FMallocAnsi final : public FMalloc
public:
FMallocAnsi();
- virtual void* Malloc(size_t Size, uint32_t Alignment) override;
- virtual void* TryMalloc(size_t Size, uint32_t Alignment) override;
- virtual void* Realloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
- virtual void* TryRealloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
- virtual void Free(void* Ptr) override;
- virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
+ virtual void* Malloc(size_t Size, uint32_t Alignment) override;
+ virtual void* TryMalloc(size_t Size, uint32_t Alignment) override;
+ virtual void* Realloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
+ virtual void* TryRealloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
+ virtual void Free(void* Ptr) override;
+ virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
+ virtual const char* GetName() const override;
};
} // namespace zen
diff --git a/src/zencore/include/zencore/memory/mallocmimalloc.h b/src/zencore/include/zencore/memory/mallocmimalloc.h
index 759eeb4a6..aa11d51d7 100644
--- a/src/zencore/include/zencore/memory/mallocmimalloc.h
+++ b/src/zencore/include/zencore/memory/mallocmimalloc.h
@@ -20,15 +20,16 @@ class FMallocMimalloc final : public FMalloc
{
public:
FMallocMimalloc();
- virtual void* Malloc(size_t Size, uint32_t Alignment) override;
- virtual void* TryMalloc(size_t Size, uint32_t Alignment) override;
- virtual void* Realloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
- virtual void* TryRealloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
- virtual void Free(void* Ptr) override;
- virtual void* MallocZeroed(size_t Count, uint32_t Alignment) override;
- virtual void* TryMallocZeroed(size_t Count, uint32_t Alignment) override;
- virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
- virtual void Trim(bool bTrimThreadCaches) override;
+ virtual void* Malloc(size_t Size, uint32_t Alignment) override;
+ virtual void* TryMalloc(size_t Size, uint32_t Alignment) override;
+ virtual void* Realloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
+ virtual void* TryRealloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
+ virtual void Free(void* Ptr) override;
+ virtual void* MallocZeroed(size_t Count, uint32_t Alignment) override;
+ virtual void* TryMallocZeroed(size_t Count, uint32_t Alignment) override;
+ virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
+ virtual void Trim(bool bTrimThreadCaches) override;
+ virtual const char* GetName() const override;
};
} // namespace zen
diff --git a/src/zencore/include/zencore/memory/mallocrpmalloc.h b/src/zencore/include/zencore/memory/mallocrpmalloc.h
index be2627b2d..718b7c095 100644
--- a/src/zencore/include/zencore/memory/mallocrpmalloc.h
+++ b/src/zencore/include/zencore/memory/mallocrpmalloc.h
@@ -21,15 +21,16 @@ class FMallocRpmalloc final : public FMalloc
public:
FMallocRpmalloc();
~FMallocRpmalloc();
- virtual void* Malloc(size_t Size, uint32_t Alignment) override;
- virtual void* TryMalloc(size_t Size, uint32_t Alignment) override;
- virtual void* Realloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
- virtual void* TryRealloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
- virtual void Free(void* Ptr) override;
- virtual void* MallocZeroed(size_t Count, uint32_t Alignment) override;
- virtual void* TryMallocZeroed(size_t Count, uint32_t Alignment) override;
- virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
- virtual void Trim(bool bTrimThreadCaches) override;
+ virtual void* Malloc(size_t Size, uint32_t Alignment) override;
+ virtual void* TryMalloc(size_t Size, uint32_t Alignment) override;
+ virtual void* Realloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
+ virtual void* TryRealloc(void* Ptr, size_t NewSize, uint32_t Alignment) override;
+ virtual void Free(void* Ptr) override;
+ virtual void* MallocZeroed(size_t Count, uint32_t Alignment) override;
+ virtual void* TryMallocZeroed(size_t Count, uint32_t Alignment) override;
+ virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
+ virtual void Trim(bool bTrimThreadCaches) override;
+ virtual const char* GetName() const override;
};
} // namespace zen
diff --git a/src/zencore/include/zencore/memory/mallocstomp.h b/src/zencore/include/zencore/memory/mallocstomp.h
index 5d83868bb..ed0617c95 100644
--- a/src/zencore/include/zencore/memory/mallocstomp.h
+++ b/src/zencore/include/zencore/memory/mallocstomp.h
@@ -92,7 +92,8 @@ public:
* @param SizeOut - If possible, this value is set to the size of the passed in pointer
* @return true if succeeded
*/
- virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
+ virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override;
+ virtual const char* GetName() const override;
};
} // namespace zen
diff --git a/src/zencore/include/zencore/process.h b/src/zencore/include/zencore/process.h
index 3177f64c1..8cbed781d 100644
--- a/src/zencore/include/zencore/process.h
+++ b/src/zencore/include/zencore/process.h
@@ -16,31 +16,105 @@ namespace zen {
class JobObject;
#endif
-/** Basic process abstraction
+/** Non-copyable handle to an OS process.
+ *
+ * On Windows, wraps a HANDLE opened with PROCESS_QUERY_INFORMATION | SYNCHRONIZE.
+ * On Linux/macOS, stores the pid directly (no kernel handle).
+ *
+ * Must be Initialize()'d before use. The destructor releases the underlying
+ * OS handle (Windows) or reaps a zombie child if it has already exited (POSIX).
*/
class ProcessHandle
{
public:
ProcessHandle();
+ /// Construct by opening a handle to the process identified by @p Pid.
+ /// On Windows this calls OpenProcess(); on POSIX it simply stores the pid.
+ /// Throws std::system_error on failure.
+ explicit ProcessHandle(int Pid);
+
+ /// Construct from an existing native process handle. Takes ownership —
+ /// the caller must not close the handle afterwards. Windows only.
+#if ZEN_PLATFORM_WINDOWS
+ explicit ProcessHandle(void* NativeHandle);
+#endif
+
ProcessHandle(const ProcessHandle&) = delete;
ProcessHandle& operator=(const ProcessHandle&) = delete;
+ ProcessHandle(ProcessHandle&& Other) noexcept;
+ ProcessHandle& operator=(ProcessHandle&& Other) noexcept;
+
~ProcessHandle();
- void Initialize(int Pid);
- void Initialize(int Pid, std::error_code& OutEc);
- void Initialize(void* ProcessHandle); /// Initialize with an existing handle - takes ownership of the handle
- [[nodiscard]] bool IsRunning() const;
- [[nodiscard]] bool IsValid() const;
- bool Wait(int TimeoutMs = -1);
- bool Wait(int TimeoutMs, std::error_code& OutEc);
- int WaitExitCode();
- int GetExitCode();
- bool Kill();
- bool Terminate(int ExitCode);
- void Reset();
- [[nodiscard]] inline int Pid() const { return m_Pid; }
+ /// Open a handle to the process identified by @p Pid.
+ /// On Windows this calls OpenProcess(); on POSIX it simply stores the pid.
+ /// Throws std::system_error on failure.
+ void Initialize(int Pid);
+
+ /// Same as Initialize(int) but reports errors via @p OutEc instead of throwing.
+ void Initialize(int Pid, std::error_code& OutEc);
+
+ /// Initialize from an existing native process handle. Takes ownership —
+ /// the caller must not close the handle afterwards. Windows only.
+#if ZEN_PLATFORM_WINDOWS
+ void Initialize(void* ProcessHandle);
+#endif
+
+ /// Returns true if the process is still alive.
+ /// On Windows, queries the exit code (STILL_ACTIVE check).
+ /// On POSIX, probes via kill(pid, 0) or equivalent.
+ [[nodiscard]] bool IsRunning() const;
+
+ /// Returns true if the handle has been successfully initialized.
+ [[nodiscard]] bool IsValid() const;
+
+ /// Block until the process exits or @p TimeoutMs elapses (-1 = infinite).
+ /// Returns true if the process exited, false on timeout.
+ /// Throws std::system_error on OS-level failure.
+ bool Wait(int TimeoutMs = -1);
+
+ /// Same as Wait(int) but reports errors via @p OutEc instead of throwing.
+ bool Wait(int TimeoutMs, std::error_code& OutEc);
+
+ /// Block until the process exits (indefinite wait), then return its exit code.
+ int WaitExitCode();
+
+ /// Return the process exit code. The process must have already exited
+ /// (asserts on Windows if still active). On POSIX the exit code is
+ /// captured during Wait().
+ int GetExitCode();
+
+ /// Attempt a graceful shutdown, falling back to a forced kill.
+ ///
+ /// On Windows: sends CTRL_BREAK_EVENT and waits up to 5 seconds; if the
+ /// process is still alive, calls TerminateProcess().
+ /// On POSIX: sends SIGTERM and waits up to 5 seconds; if the process is
+ /// still alive, sends SIGKILL.
+ ///
+ /// Calls Reset() before returning. Returns true on success.
+ bool Kill();
+
+ /// Immediately and unconditionally terminate the process.
+ ///
+ /// On Windows: calls TerminateProcess() with the given @p ExitCode and
+ /// waits for the process to fully exit.
+ /// On POSIX: sends SIGKILL (ExitCode is ignored) and waits up to 5 seconds
+ /// for the child to be reaped.
+ ///
+ /// Unlike Kill(), this does not attempt a graceful shutdown first.
+ /// Calls Reset() before returning. Returns true on success.
+ bool Terminate(int ExitCode);
+
+ /// Release the OS handle (Windows) or reap a zombie child (POSIX).
+ /// After this call, IsValid() returns false.
+ void Reset();
+
+ /// Return the process id.
+ [[nodiscard]] inline int Pid() const { return m_Pid; }
+
+ /// Return the native OS handle. HANDLE on Windows, pid cast to void* on POSIX.
[[nodiscard]] inline void* Handle() const { return m_ProcessHandle; }
private:
@@ -54,23 +128,68 @@ private:
/** Basic process creation
*/
+// Platform-agnostic RAII pipe handles for capturing child stdout/stderr.
+// The destructor closes any open handles/fds automatically.
+struct StdoutPipeHandles
+{
+ StdoutPipeHandles() = default;
+ ~StdoutPipeHandles();
+
+ StdoutPipeHandles(const StdoutPipeHandles&) = delete;
+ StdoutPipeHandles& operator=(const StdoutPipeHandles&) = delete;
+
+ StdoutPipeHandles(StdoutPipeHandles&& Other) noexcept;
+ StdoutPipeHandles& operator=(StdoutPipeHandles&& Other) noexcept;
+
+ // Close only the write end (call after child is launched so parent doesn't hold it open).
+ void CloseWriteEnd();
+
+ // Close both ends of the pipe.
+ void Close();
+
+#if ZEN_PLATFORM_WINDOWS
+ void* ReadHandle = nullptr; // HANDLE for reading (parent side)
+ void* WriteHandle = nullptr; // HANDLE for writing (child side)
+#else
+ int ReadFd = -1;
+ int WriteFd = -1;
+#endif
+};
+
+// Create a pipe suitable for capturing child process stdout.
+// The write end is inheritable; the read end is not.
+bool CreateStdoutPipe(StdoutPipeHandles& OutPipe);
+
struct CreateProcOptions
{
enum
{
+ // Allocate a new console for the child (CREATE_NEW_CONSOLE on Windows).
Flag_NewConsole = 1 << 0,
- Flag_Elevated = 1 << 1,
+ // Launch the child with elevated (administrator) privileges via ShellExecuteEx/runas.
+ Flag_Elevated = 1 << 1,
+ // Launch the child without elevation from an elevated parent, using a medium-integrity token.
Flag_Unelevated = 1 << 2,
- Flag_NoConsole = 1 << 3,
- // This flag creates the new process in a new process group. This is relevant only on Windows, and
- // allows sending ctrl-break events to the new process group without also sending it to the current
- // process.
- Flag_Windows_NewProcessGroup = 1 << 4,
+ // Detach the child from all consoles (DETACHED_PROCESS on Windows). No console is
+ // allocated and no conhost.exe is spawned. Stdout/stderr still work when redirected
+ // via pipes. Prefer this for headless worker processes.
+ Flag_NoConsole = 1 << 3,
+ // Spawn the child as a new process group leader (its pgid = its own pid).
+ // On Windows: CREATE_NEW_PROCESS_GROUP, enables CTRL_BREAK_EVENT targeting.
+ // On POSIX: child calls setpgid(0,0) / posix_spawn with POSIX_SPAWN_SETPGROUP+pgid=0.
+ // Mutually exclusive with ProcessGroupId > 0.
+ Flag_NewProcessGroup = 1 << 4,
+ // Allocate a hidden console for the child (CREATE_NO_WINDOW on Windows). Unlike
+ // Flag_NoConsole the child still gets a console (and a conhost.exe) but no visible
+ // window. Use this when the child needs a console for stdio but should not show a window.
+ Flag_NoWindow = 1 << 5,
};
const std::filesystem::path* WorkingDirectory = nullptr;
uint32_t Flags = 0;
std::filesystem::path StdoutFile;
+ StdoutPipeHandles* StdoutPipe = nullptr; // Mutually exclusive with StdoutFile. Parent reads from ReadHandle after launch.
+ StdoutPipeHandles* StderrPipe = nullptr; // Optional separate pipe for stderr. When null, stderr shares StdoutPipe.
/// Additional environment variables for the child process. These are merged
/// with the parent's environment — existing variables are inherited, and
@@ -79,9 +198,16 @@ struct CreateProcOptions
#if ZEN_PLATFORM_WINDOWS
JobObject* AssignToJob = nullptr; // When set, the process is created suspended, assigned to the job, then resumed
+#else
+ /// When > 0, child joins this existing process group. Mutually exclusive with
+ /// Flag_NewProcessGroup; use that flag on the first spawn to create the group,
+ /// then pass the resulting pid here for subsequent spawns to join it.
+ int ProcessGroupId = 0;
#endif
};
+// TODO: this should really be replaced with ProcessHandle
+
#if ZEN_PLATFORM_WINDOWS
using CreateProcResult = void*; // handle to the process
#else
@@ -132,9 +258,10 @@ public:
JobObject(const JobObject&) = delete;
JobObject& operator=(const JobObject&) = delete;
- void Initialize();
- bool AssignProcess(void* ProcessHandle);
- [[nodiscard]] bool IsValid() const;
+ void Initialize();
+ bool AssignProcess(void* ProcessHandle);
+ [[nodiscard]] bool IsValid() const;
+ [[nodiscard]] void* Handle() const { return m_JobHandle; }
private:
void* m_JobHandle = nullptr;
@@ -176,7 +303,7 @@ struct ProcessMetrics
uint64_t PeakPagefileUsage = 0;
};
-void GetProcessMetrics(ProcessHandle& Handle, ProcessMetrics& OutMetrics);
+void GetProcessMetrics(const ProcessHandle& Handle, ProcessMetrics& OutMetrics);
void process_forcelink(); // internal
diff --git a/src/zencore/include/zencore/system.h b/src/zencore/include/zencore/system.h
index 2e39cc660..52dafc18b 100644
--- a/src/zencore/include/zencore/system.h
+++ b/src/zencore/include/zencore/system.h
@@ -7,6 +7,7 @@
#include <chrono>
#include <memory>
#include <string>
+#include <vector>
namespace zen {
@@ -19,6 +20,9 @@ std::string_view GetRuntimePlatformName(); // "windows", "wine", "linux", or "ma
std::string_view GetCpuName();
std::string_view GetCompilerName();
+/// Returns the IPv4 addresses of non-loopback network interfaces.
+std::vector<std::string> GetLocalIpAddresses();
+
struct SystemMetrics
{
uint32_t CpuCount = 1;
diff --git a/src/zencore/include/zencore/testing.h b/src/zencore/include/zencore/testing.h
index 01356fa00..6b37cd6da 100644
--- a/src/zencore/include/zencore/testing.h
+++ b/src/zencore/include/zencore/testing.h
@@ -52,13 +52,6 @@ private:
std::unique_ptr<Impl> m_Impl;
};
-# define ZEN_RUN_TESTS(argC, argV) \
- [&] { \
- zen::testing::TestRunner Runner; \
- Runner.ApplyCommandLine(argC, argV); \
- return Runner.Run(); \
- }()
-
int RunTestMain(int Argc, char* Argv[], const char* ExecutableName, void (*ForceLink)());
} // namespace zen::testing
diff --git a/src/zencore/include/zencore/thread.h b/src/zencore/include/zencore/thread.h
index d0d710ee8..56ce5904b 100644
--- a/src/zencore/include/zencore/thread.h
+++ b/src/zencore/include/zencore/thread.h
@@ -28,9 +28,11 @@ class RwLock
{
public:
void AcquireShared() noexcept;
+ bool TryAcquireShared() noexcept;
void ReleaseShared() noexcept;
void AcquireExclusive() noexcept;
+ bool TryAcquireExclusive() noexcept;
void ReleaseExclusive() noexcept;
struct SharedLockScope
@@ -188,6 +190,13 @@ class Latch
public:
Latch(std::ptrdiff_t Count) : Counter(Count) {}
+ void Reset(std::ptrdiff_t Count)
+ {
+ ZEN_ASSERT(Counter.load() == 0);
+ Complete.Reset();
+ Counter.store(Count);
+ }
+
void CountDown()
{
std::ptrdiff_t Old = Counter.fetch_sub(1);
diff --git a/src/zencore/logging.cpp b/src/zencore/logging.cpp
index 3206e380b..5ada0cac7 100644
--- a/src/zencore/logging.cpp
+++ b/src/zencore/logging.cpp
@@ -345,7 +345,7 @@ SuppressConsoleLog()
}
SinkPtr NullSinkPtr(new NullSink());
- ConLogger = Ref<Logger>(new Logger("console", std::vector<SinkPtr>{NullSinkPtr}));
+ ConLogger = Ref<Logger>(new Logger("console", NullSinkPtr));
Registry::Instance().Register(ConLogger);
}
@@ -391,7 +391,7 @@ ConsoleLog()
{
SinkPtr ConsoleSink(new AnsiColorStdoutSink());
ConsoleSink->SetFormatter(std::make_unique<ConsoleFormatter>());
- ConLogger = Ref<Logger>(new Logger("console", std::vector<SinkPtr>{ConsoleSink}));
+ ConLogger = Ref<Logger>(new Logger("console", ConsoleSink));
Registry::Instance().Register(ConLogger);
}
});
@@ -414,6 +414,13 @@ InitializeLogging()
{
ZEN_MEMSCOPE(ELLMTag::Logging);
+ EnableVTMode();
+
+#if ZEN_PLATFORM_WINDOWS
+ // Enable UTF-8 output so multi-byte characters render correctly via WriteFile
+ SetConsoleOutputCP(CP_UTF8);
+#endif
+
TheDefaultLogger = LoggerRef(*Registry::Instance().DefaultLoggerRaw());
g_LoggingInitialized = true;
}
diff --git a/src/zencore/logging/logger.cpp b/src/zencore/logging/logger.cpp
index dd1675bb1..ff1db3edc 100644
--- a/src/zencore/logging/logger.cpp
+++ b/src/zencore/logging/logger.cpp
@@ -4,27 +4,20 @@
#include <zencore/thread.h>
#include <string>
-#include <vector>
namespace zen::logging {
struct Logger::Impl
{
- std::string m_Name;
- std::vector<SinkPtr> m_Sinks;
- ErrorHandler* m_ErrorHandler = nullptr;
+ std::string m_Name;
+ SinkPtr m_Sink;
+ ErrorHandler* m_ErrorHandler = nullptr;
};
Logger::Logger(std::string_view InName, SinkPtr InSink) : m_Impl(std::make_unique<Impl>())
{
m_Impl->m_Name = InName;
- m_Impl->m_Sinks.push_back(std::move(InSink));
-}
-
-Logger::Logger(std::string_view InName, std::span<const SinkPtr> InSinks) : m_Impl(std::make_unique<Impl>())
-{
- m_Impl->m_Name = InName;
- m_Impl->m_Sinks.assign(InSinks.begin(), InSinks.end());
+ m_Impl->m_Sink = std::move(InSink);
}
Logger::~Logger() = default;
@@ -49,20 +42,17 @@ Logger::Log(const LogPoint& Point, fmt::format_args Args)
void
Logger::SinkIt(const LogMessage& Msg)
{
- for (auto& CurrentSink : m_Impl->m_Sinks)
+ if (m_Impl->m_Sink && m_Impl->m_Sink->ShouldLog(Msg.GetLevel()))
{
- if (CurrentSink->ShouldLog(Msg.GetLevel()))
+ try
{
- try
- {
- CurrentSink->Log(Msg);
- }
- catch (const std::exception& Ex)
+ m_Impl->m_Sink->Log(Msg);
+ }
+ catch (const std::exception& Ex)
+ {
+ if (m_Impl->m_ErrorHandler)
{
- if (m_Impl->m_ErrorHandler)
- {
- m_Impl->m_ErrorHandler->HandleError(Ex.what());
- }
+ m_Impl->m_ErrorHandler->HandleError(Ex.what());
}
}
}
@@ -80,11 +70,11 @@ Logger::FlushIfNeeded(LogLevel InLevel)
void
Logger::Flush()
{
- for (auto& CurrentSink : m_Impl->m_Sinks)
+ if (m_Impl->m_Sink)
{
try
{
- CurrentSink->Flush();
+ m_Impl->m_Sink->Flush();
}
catch (const std::exception& Ex)
{
@@ -97,15 +87,9 @@ Logger::Flush()
}
void
-Logger::SetSinks(std::vector<SinkPtr> InSinks)
-{
- m_Impl->m_Sinks = std::move(InSinks);
-}
-
-void
-Logger::AddSink(SinkPtr InSink)
+Logger::SetSink(SinkPtr InSink)
{
- m_Impl->m_Sinks.push_back(std::move(InSink));
+ m_Impl->m_Sink = std::move(InSink);
}
void
@@ -117,9 +101,9 @@ Logger::SetErrorHandler(ErrorHandler* Handler)
void
Logger::SetFormatter(std::unique_ptr<Formatter> InFormatter)
{
- for (auto& CurrentSink : m_Impl->m_Sinks)
+ if (m_Impl->m_Sink)
{
- CurrentSink->SetFormatter(InFormatter->Clone());
+ m_Impl->m_Sink->SetFormatter(std::move(InFormatter));
}
}
@@ -132,7 +116,7 @@ Logger::Name() const
Ref<Logger>
Logger::Clone(std::string_view NewName) const
{
- Ref<Logger> Cloned(new Logger(NewName, m_Impl->m_Sinks));
+ Ref<Logger> Cloned(new Logger(NewName, m_Impl->m_Sink));
Cloned->SetLevel(m_Level.load(std::memory_order_relaxed));
Cloned->SetFlushLevel(m_FlushLevel.load(std::memory_order_relaxed));
Cloned->SetErrorHandler(m_Impl->m_ErrorHandler);
diff --git a/src/zencore/memory/fmalloc.cpp b/src/zencore/memory/fmalloc.cpp
index 3e96003f5..b64fe1f2e 100644
--- a/src/zencore/memory/fmalloc.cpp
+++ b/src/zencore/memory/fmalloc.cpp
@@ -56,8 +56,9 @@ class FInitialMalloc : public FMalloc
Memory::Initialize();
return GMalloc->GetAllocationSize(Original, SizeOut);
}
- virtual void OnMallocInitialized() override {}
- virtual void Trim(bool bTrimThreadCaches) override { ZEN_UNUSED(bTrimThreadCaches); }
+ virtual void OnMallocInitialized() override {}
+ virtual void Trim(bool bTrimThreadCaches) override { ZEN_UNUSED(bTrimThreadCaches); }
+ virtual const char* GetName() const override { return "initial"; }
} GInitialMalloc;
FMalloc* GMalloc = &GInitialMalloc; /* Memory allocator */
diff --git a/src/zencore/memory/mallocansi.cpp b/src/zencore/memory/mallocansi.cpp
index 9c3936172..e9465b46b 100644
--- a/src/zencore/memory/mallocansi.cpp
+++ b/src/zencore/memory/mallocansi.cpp
@@ -248,4 +248,10 @@ FMallocAnsi::GetAllocationSize(void* Original, size_t& SizeOut)
#endif
}
+const char*
+FMallocAnsi::GetName() const
+{
+ return "ansi";
+}
+
} // namespace zen
diff --git a/src/zencore/memory/mallocmimalloc.cpp b/src/zencore/memory/mallocmimalloc.cpp
index 1f9aff404..1679eebde 100644
--- a/src/zencore/memory/mallocmimalloc.cpp
+++ b/src/zencore/memory/mallocmimalloc.cpp
@@ -191,6 +191,18 @@ FMallocMimalloc::Trim(bool bTrimThreadCaches)
mi_collect(bTrimThreadCaches);
}
+const char*
+FMallocMimalloc::GetName() const
+{
+ static char Name[32] = {};
+ if (Name[0] == '\0')
+ {
+ int Ver = mi_version();
+ snprintf(Name, sizeof(Name), "mimalloc %d.%d.%d", Ver / 100, (Ver / 10) % 10, Ver % 10);
+ }
+ return Name;
+}
+
# undef DEBUG_FILL_FREED
# undef DEBUG_FILL_NEW
diff --git a/src/zencore/memory/mallocrpmalloc.cpp b/src/zencore/memory/mallocrpmalloc.cpp
index c45186b77..6c7bfe4f5 100644
--- a/src/zencore/memory/mallocrpmalloc.cpp
+++ b/src/zencore/memory/mallocrpmalloc.cpp
@@ -186,5 +186,10 @@ FMallocRpmalloc::Trim(bool bTrimThreadCaches)
{
ZEN_UNUSED(bTrimThreadCaches);
}
+const char*
+FMallocRpmalloc::GetName() const
+{
+ return "rpmalloc 1.5.0-dev.20250810";
+}
} // namespace zen
#endif
diff --git a/src/zencore/memory/mallocstomp.cpp b/src/zencore/memory/mallocstomp.cpp
index db9e1535e..54153cbd4 100644
--- a/src/zencore/memory/mallocstomp.cpp
+++ b/src/zencore/memory/mallocstomp.cpp
@@ -278,6 +278,12 @@ FMallocStomp::GetAllocationSize(void* Original, size_t& SizeOut)
return true;
}
+const char*
+FMallocStomp::GetName() const
+{
+ return "stomp";
+}
+
} // namespace zen
#endif // WITH_MALLOC_STOMP
diff --git a/src/zencore/memtrack/memorytrace.cpp b/src/zencore/memtrack/memorytrace.cpp
index 065a6f8ec..13abf7275 100644
--- a/src/zencore/memtrack/memorytrace.cpp
+++ b/src/zencore/memtrack/memorytrace.cpp
@@ -201,6 +201,7 @@ private:
virtual void Free(void* Address) override;
virtual bool GetAllocationSize(void* Address, SIZE_T& SizeOut) override { return InnerMalloc->GetAllocationSize(Address, SizeOut); }
virtual void OnMallocInitialized() override { InnerMalloc->OnMallocInitialized(); }
+ virtual const char* GetName() const override { return InnerMalloc->GetName(); }
FMalloc* InnerMalloc;
};
diff --git a/src/zencore/memtrack/tracemalloc.h b/src/zencore/memtrack/tracemalloc.h
index f82d630d7..017962d08 100644
--- a/src/zencore/memtrack/tracemalloc.h
+++ b/src/zencore/memtrack/tracemalloc.h
@@ -16,7 +16,8 @@ public:
virtual void* Realloc(void* Original, size_t Count, uint32_t Alignment) override;
virtual void Free(void* Original) override;
- virtual void OnMallocInitialized() override { WrappedMalloc->OnMallocInitialized(); }
+ virtual void OnMallocInitialized() override { WrappedMalloc->OnMallocInitialized(); }
+ virtual const char* GetName() const override { return WrappedMalloc->GetName(); }
FMalloc* WrappedMalloc;
};
diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp
index 0c55e6c7e..ee821944a 100644
--- a/src/zencore/process.cpp
+++ b/src/zencore/process.cpp
@@ -37,7 +37,9 @@ ZEN_THIRD_PARTY_INCLUDES_START
#endif
#if ZEN_PLATFORM_MAC
+# include <crt_externs.h>
# include <libproc.h>
+# include <spawn.h>
# include <sys/types.h>
# include <sys/sysctl.h>
#endif
@@ -135,10 +137,248 @@ IsZombieProcess(int pid, std::error_code& OutEc)
}
return false;
}
+
+static char**
+GetEnviron()
+{
+ return *_NSGetEnviron();
+}
#endif // ZEN_PLATFORM_MAC
+#if ZEN_PLATFORM_LINUX
+static char**
+GetEnviron()
+{
+ return environ;
+}
+#endif // ZEN_PLATFORM_LINUX
+
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+// Holds a null-terminated envp array built by merging the current process environment with
+// a set of overrides. When Overrides is empty, Data points directly to environ (no allocation).
+// Must outlive any posix_spawn / execve call that receives Data.
+struct EnvpHolder
+{
+ char** Data = GetEnviron();
+
+ explicit EnvpHolder(const std::vector<std::pair<std::string, std::string>>& Overrides)
+ {
+ if (Overrides.empty())
+ {
+ return;
+ }
+ std::map<std::string, std::string> EnvMap;
+ for (char** E = GetEnviron(); *E; ++E)
+ {
+ std::string_view Entry(*E);
+ const size_t EqPos = Entry.find('=');
+ if (EqPos != std::string_view::npos)
+ {
+ EnvMap[std::string(Entry.substr(0, EqPos))] = std::string(Entry.substr(EqPos + 1));
+ }
+ }
+ for (const auto& [Key, Value] : Overrides)
+ {
+ EnvMap[Key] = Value;
+ }
+ for (const auto& [Key, Value] : EnvMap)
+ {
+ m_Strings.push_back(Key + "=" + Value);
+ }
+ for (std::string& S : m_Strings)
+ {
+ m_Ptrs.push_back(S.data());
+ }
+ m_Ptrs.push_back(nullptr);
+ Data = m_Ptrs.data();
+ }
+
+private:
+ std::vector<std::string> m_Strings;
+ std::vector<char*> m_Ptrs;
+};
+#endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+
+//////////////////////////////////////////////////////////////////////////
+// Pipe creation for child process stdout capture
+
+#if ZEN_PLATFORM_WINDOWS
+
+StdoutPipeHandles::~StdoutPipeHandles()
+{
+ Close();
+}
+
+StdoutPipeHandles::StdoutPipeHandles(StdoutPipeHandles&& Other) noexcept
+: ReadHandle(std::exchange(Other.ReadHandle, nullptr))
+, WriteHandle(std::exchange(Other.WriteHandle, nullptr))
+{
+}
+
+StdoutPipeHandles&
+StdoutPipeHandles::operator=(StdoutPipeHandles&& Other) noexcept
+{
+ if (this != &Other)
+ {
+ Close();
+ ReadHandle = std::exchange(Other.ReadHandle, nullptr);
+ WriteHandle = std::exchange(Other.WriteHandle, nullptr);
+ }
+ return *this;
+}
+
+void
+StdoutPipeHandles::CloseWriteEnd()
+{
+ if (WriteHandle)
+ {
+ CloseHandle(WriteHandle);
+ WriteHandle = nullptr;
+ }
+}
+
+void
+StdoutPipeHandles::Close()
+{
+ if (ReadHandle)
+ {
+ CloseHandle(ReadHandle);
+ ReadHandle = nullptr;
+ }
+ CloseWriteEnd();
+}
+
+bool
+CreateStdoutPipe(StdoutPipeHandles& OutPipe)
+{
+ SECURITY_ATTRIBUTES Sa;
+ Sa.nLength = sizeof(Sa);
+ Sa.lpSecurityDescriptor = nullptr;
+ Sa.bInheritHandle = TRUE;
+
+ HANDLE ReadHandle = nullptr;
+ HANDLE WriteHandle = nullptr;
+ if (!::CreatePipe(&ReadHandle, &WriteHandle, &Sa, 0))
+ {
+ return false;
+ }
+
+ // The read end should not be inherited by the child
+ SetHandleInformation(ReadHandle, HANDLE_FLAG_INHERIT, 0);
+
+ OutPipe.ReadHandle = ReadHandle;
+ OutPipe.WriteHandle = WriteHandle;
+ return true;
+}
+
+#else
+
+StdoutPipeHandles::~StdoutPipeHandles()
+{
+ Close();
+}
+
+StdoutPipeHandles::StdoutPipeHandles(StdoutPipeHandles&& Other) noexcept
+: ReadFd(std::exchange(Other.ReadFd, -1))
+, WriteFd(std::exchange(Other.WriteFd, -1))
+{
+}
+
+StdoutPipeHandles&
+StdoutPipeHandles::operator=(StdoutPipeHandles&& Other) noexcept
+{
+ if (this != &Other)
+ {
+ Close();
+ ReadFd = std::exchange(Other.ReadFd, -1);
+ WriteFd = std::exchange(Other.WriteFd, -1);
+ }
+ return *this;
+}
+
+void
+StdoutPipeHandles::CloseWriteEnd()
+{
+ if (WriteFd >= 0)
+ {
+ close(WriteFd);
+ WriteFd = -1;
+ }
+}
+
+void
+StdoutPipeHandles::Close()
+{
+ if (ReadFd >= 0)
+ {
+ close(ReadFd);
+ ReadFd = -1;
+ }
+ CloseWriteEnd();
+}
+
+bool
+CreateStdoutPipe(StdoutPipeHandles& OutPipe)
+{
+ int Fds[2];
+ if (pipe(Fds) != 0)
+ {
+ return false;
+ }
+ OutPipe.ReadFd = Fds[0];
+ OutPipe.WriteFd = Fds[1];
+
+ // Set close-on-exec on the read end so the child doesn't inherit it
+ fcntl(OutPipe.ReadFd, F_SETFD, FD_CLOEXEC);
+ return true;
+}
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+
ProcessHandle::ProcessHandle() = default;
+ProcessHandle::ProcessHandle(int Pid)
+{
+ Initialize(Pid);
+}
+
+#if ZEN_PLATFORM_WINDOWS
+ProcessHandle::ProcessHandle(void* NativeHandle)
+{
+ Initialize(NativeHandle);
+}
+#endif
+
+ProcessHandle::ProcessHandle(ProcessHandle&& Other) noexcept
+: m_ProcessHandle(Other.m_ProcessHandle)
+, m_Pid(Other.m_Pid)
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+, m_ExitCode(Other.m_ExitCode)
+#endif
+{
+ Other.m_ProcessHandle = nullptr;
+ Other.m_Pid = 0;
+}
+
+ProcessHandle&
+ProcessHandle::operator=(ProcessHandle&& Other) noexcept
+{
+ if (this != &Other)
+ {
+ Reset();
+ m_ProcessHandle = Other.m_ProcessHandle;
+ m_Pid = Other.m_Pid;
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+ m_ExitCode = Other.m_ExitCode;
+#endif
+ Other.m_ProcessHandle = nullptr;
+ Other.m_Pid = 0;
+ }
+ return *this;
+}
+
#if ZEN_PLATFORM_WINDOWS
void
ProcessHandle::Initialize(void* ProcessHandle)
@@ -259,6 +499,17 @@ ProcessHandle::Kill()
return false;
}
}
+
+ // Wait for the process to exit after SIGTERM, matching the Windows path
+ // which waits up to 5 seconds for graceful shutdown. Without this wait
+ // the child becomes a zombie and may hold resources (e.g. TCP ports).
+ std::error_code Ec;
+ if (!Wait(5000, Ec))
+ {
+ // Graceful shutdown timed out — force-kill
+ kill(pid_t(m_Pid), SIGKILL);
+ Wait(1000, Ec);
+ }
#endif
Reset();
@@ -297,6 +548,11 @@ ProcessHandle::Terminate(int ExitCode)
return false;
}
}
+
+ // Wait for the process to be reaped after SIGKILL so it doesn't linger
+ // as a zombie holding resources (e.g. TCP ports).
+ std::error_code Ec;
+ Wait(5000, Ec);
#endif
Reset();
return true;
@@ -309,6 +565,10 @@ ProcessHandle::Reset()
{
#if ZEN_PLATFORM_WINDOWS
CloseHandle(m_ProcessHandle);
+#elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+ // Reap the child if it has already exited to prevent zombies.
+ // If still running, it will be reparented to init on our exit.
+ waitpid(m_Pid, nullptr, WNOHANG);
#endif
m_ProcessHandle = nullptr;
m_Pid = 0;
@@ -350,17 +610,26 @@ ProcessHandle::Wait(int TimeoutMs, std::error_code& OutEc)
timespec SleepTime = {0, SleepMs * 1000 * 1000};
for (int SleepedTimeMS = 0;; SleepedTimeMS += SleepMs)
{
- int WaitState = 0;
- if (waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED) != -1)
+ int WaitState = 0;
+ pid_t WaitResult = waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED);
+ if (WaitResult > 0 && WIFEXITED(WaitState))
{
- if (WIFEXITED(WaitState))
- {
- m_ExitCode = WEXITSTATUS(WaitState);
- }
+ m_ExitCode = WEXITSTATUS(WaitState);
}
if (!IsProcessRunning(m_Pid, OutEc))
{
+ // Process is gone but waitpid(WNOHANG) may have missed the exit status
+ // due to a TOCTOU race (process became a zombie between waitpid and
+ // IsProcessRunning). Do a blocking reap now to capture the exit code.
+ if (WaitResult <= 0)
+ {
+ WaitState = 0;
+ if (waitpid(m_Pid, &WaitState, 0) > 0 && WIFEXITED(WaitState))
+ {
+ m_ExitCode = WEXITSTATUS(WaitState);
+ }
+ }
return true;
}
else if (OutEc)
@@ -381,6 +650,12 @@ ProcessHandle::Wait(int TimeoutMs, std::error_code& OutEc)
else if (IsZombieProcess(m_Pid, OutEc))
{
ZEN_INFO("Found process {} in zombie state, treating as not running", m_Pid);
+ // Reap the zombie to capture its exit code.
+ WaitState = 0;
+ if (waitpid(m_Pid, &WaitState, 0) > 0 && WIFEXITED(WaitState))
+ {
+ m_ExitCode = WEXITSTATUS(WaitState);
+ }
return true;
}
@@ -478,6 +753,7 @@ BuildArgV(std::vector<char*>& Out, char* CommandLine)
++Cursor;
}
}
+
#endif // !WINDOWS || TESTS
#if ZEN_PLATFORM_WINDOWS
@@ -547,9 +823,13 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma
}
if (Options.Flags & CreateProcOptions::Flag_NoConsole)
{
+ CreationFlags |= DETACHED_PROCESS;
+ }
+ if (Options.Flags & CreateProcOptions::Flag_NoWindow)
+ {
CreationFlags |= CREATE_NO_WINDOW;
}
- if (Options.Flags & CreateProcOptions::Flag_Windows_NewProcessGroup)
+ if (Options.Flags & CreateProcOptions::Flag_NewProcessGroup)
{
CreationFlags |= CREATE_NEW_PROCESS_GROUP;
}
@@ -567,7 +847,40 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma
ExtendableWideStringBuilder<256> CommandLineZ;
CommandLineZ << CommandLine;
- if (!Options.StdoutFile.empty())
+ bool DuplicatedStdErr = false;
+
+ if (Options.StdoutPipe != nullptr && Options.StdoutPipe->WriteHandle != nullptr)
+ {
+ StartupInfo.hStdInput = nullptr;
+ StartupInfo.hStdOutput = (HANDLE)Options.StdoutPipe->WriteHandle;
+
+ if (Options.StderrPipe != nullptr && Options.StderrPipe->WriteHandle != nullptr)
+ {
+ // Use separate pipe for stderr
+ StartupInfo.hStdError = (HANDLE)Options.StderrPipe->WriteHandle;
+ StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+ InheritHandles = true;
+ }
+ else
+ {
+ // Duplicate stdout handle for stderr (both go to same pipe)
+ const BOOL DupSuccess = DuplicateHandle(GetCurrentProcess(),
+ StartupInfo.hStdOutput,
+ GetCurrentProcess(),
+ &StartupInfo.hStdError,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
+
+ if (DupSuccess)
+ {
+ DuplicatedStdErr = true;
+ StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+ InheritHandles = true;
+ }
+ }
+ }
+ else if (!Options.StdoutFile.empty())
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof sa;
@@ -593,6 +906,7 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma
if (Success)
{
+ DuplicatedStdErr = true;
StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
InheritHandles = true;
}
@@ -616,8 +930,16 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma
if (StartupInfo.dwFlags & STARTF_USESTDHANDLES)
{
- CloseHandle(StartupInfo.hStdError);
- CloseHandle(StartupInfo.hStdOutput);
+ // Only close hStdError if we duplicated it (caller-owned pipe handles are not ours to close)
+ if (DuplicatedStdErr)
+ {
+ CloseHandle(StartupInfo.hStdError);
+ }
+ // Only close hStdOutput if it was a file handle we created (not a pipe handle owned by caller)
+ if (Options.StdoutPipe == nullptr || Options.StdoutPipe->WriteHandle == nullptr)
+ {
+ CloseHandle(StartupInfo.hStdOutput);
+ }
}
if (!Success)
@@ -715,6 +1037,10 @@ CreateProcUnelevated(const std::filesystem::path& Executable, std::string_view C
}
if (Options.Flags & CreateProcOptions::Flag_NoConsole)
{
+ CreateProcFlags |= DETACHED_PROCESS;
+ }
+ if (Options.Flags & CreateProcOptions::Flag_NoWindow)
+ {
CreateProcFlags |= CREATE_NO_WINDOW;
}
if (AssignToJob)
@@ -807,26 +1133,51 @@ CreateProc(const std::filesystem::path& Executable, std::string_view CommandLine
}
return CreateProcNormal(Executable, CommandLine, Options);
-#else
+#elif ZEN_PLATFORM_LINUX
+ // vfork uses CLONE_VM|CLONE_VFORK: the child shares the parent's address space and the
+ // parent is suspended until the child calls exec or _exit. This avoids page-table duplication
+ // and the ENOMEM that fork() produces on systems with strict overcommit (vm.overcommit_memory=2).
+ // All child-side setup uses only syscalls that do not modify user-space memory.
+ // Environment overrides are merged into envp before vfork so that setenv() is never called
+ // from the child (which would corrupt the shared address space).
std::vector<char*> ArgV;
std::string CommandLineZ(CommandLine);
BuildArgV(ArgV, CommandLineZ.data());
ArgV.push_back(nullptr);
- int ChildPid = fork();
+ EnvpHolder Envp(Options.Environment);
+
+ int ChildPid = vfork();
if (ChildPid < 0)
{
- ThrowLastError("Failed to fork a new child process");
+ ThrowLastError("Failed to vfork a new child process");
}
else if (ChildPid == 0)
{
if (Options.WorkingDirectory != nullptr)
{
- int Result = chdir(Options.WorkingDirectory->c_str());
- ZEN_UNUSED(Result);
+ chdir(Options.WorkingDirectory->c_str());
}
- if (!Options.StdoutFile.empty())
+ if (Options.StdoutPipe != nullptr && Options.StdoutPipe->WriteFd >= 0)
+ {
+ dup2(Options.StdoutPipe->WriteFd, STDOUT_FILENO);
+
+ if (Options.StderrPipe != nullptr && Options.StderrPipe->WriteFd >= 0)
+ {
+ dup2(Options.StderrPipe->WriteFd, STDERR_FILENO);
+ close(Options.StderrPipe->WriteFd);
+ // StderrPipe ReadFd has FD_CLOEXEC so it's auto-closed on exec
+ }
+ else
+ {
+ dup2(Options.StdoutPipe->WriteFd, STDERR_FILENO);
+ }
+
+ close(Options.StdoutPipe->WriteFd);
+ // ReadFd has FD_CLOEXEC so it's auto-closed on exec
+ }
+ else if (!Options.StdoutFile.empty())
{
int Fd = open(Options.StdoutFile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (Fd >= 0)
@@ -837,18 +1188,99 @@ CreateProc(const std::filesystem::path& Executable, std::string_view CommandLine
}
}
- for (const auto& [Key, Value] : Options.Environment)
+ if (Options.Flags & CreateProcOptions::Flag_NewProcessGroup)
{
- setenv(Key.c_str(), Value.c_str(), 1);
+ setpgid(0, 0);
}
-
- if (execv(Executable.c_str(), ArgV.data()) < 0)
+ else if (Options.ProcessGroupId > 0)
{
- ThrowLastError("Failed to exec() a new process image");
+ setpgid(0, Options.ProcessGroupId);
}
+
+ execve(Executable.c_str(), ArgV.data(), Envp.Data);
+ _exit(127);
}
return ChildPid;
+#else // macOS
+ std::vector<char*> ArgV;
+ std::string CommandLineZ(CommandLine);
+ BuildArgV(ArgV, CommandLineZ.data());
+ ArgV.push_back(nullptr);
+
+ posix_spawn_file_actions_t FileActions;
+ posix_spawnattr_t Attr;
+
+ int Err = posix_spawn_file_actions_init(&FileActions);
+ if (Err != 0)
+ {
+ ThrowSystemError(Err, "posix_spawn_file_actions_init failed");
+ }
+ auto FileActionsGuard = MakeGuard([&] { posix_spawn_file_actions_destroy(&FileActions); });
+
+ Err = posix_spawnattr_init(&Attr);
+ if (Err != 0)
+ {
+ ThrowSystemError(Err, "posix_spawnattr_init failed");
+ }
+ auto AttrGuard = MakeGuard([&] { posix_spawnattr_destroy(&Attr); });
+
+ if (Options.WorkingDirectory != nullptr)
+ {
+ Err = posix_spawn_file_actions_addchdir_np(&FileActions, Options.WorkingDirectory->c_str());
+ if (Err != 0)
+ {
+ ThrowSystemError(Err, "posix_spawn_file_actions_addchdir_np failed");
+ }
+ }
+
+ if (Options.StdoutPipe != nullptr && Options.StdoutPipe->WriteFd >= 0)
+ {
+ const int StdoutWriteFd = Options.StdoutPipe->WriteFd;
+ ZEN_ASSERT(StdoutWriteFd > STDERR_FILENO);
+ posix_spawn_file_actions_adddup2(&FileActions, StdoutWriteFd, STDOUT_FILENO);
+
+ if (Options.StderrPipe != nullptr && Options.StderrPipe->WriteFd >= 0)
+ {
+ const int StderrWriteFd = Options.StderrPipe->WriteFd;
+ ZEN_ASSERT(StderrWriteFd > STDERR_FILENO && StderrWriteFd != StdoutWriteFd);
+ posix_spawn_file_actions_adddup2(&FileActions, StderrWriteFd, STDERR_FILENO);
+ posix_spawn_file_actions_addclose(&FileActions, StderrWriteFd);
+ }
+ else
+ {
+ posix_spawn_file_actions_adddup2(&FileActions, StdoutWriteFd, STDERR_FILENO);
+ }
+
+ posix_spawn_file_actions_addclose(&FileActions, StdoutWriteFd);
+ }
+ else if (!Options.StdoutFile.empty())
+ {
+ posix_spawn_file_actions_addopen(&FileActions, STDOUT_FILENO, Options.StdoutFile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ posix_spawn_file_actions_adddup2(&FileActions, STDOUT_FILENO, STDERR_FILENO);
+ }
+
+ if (Options.Flags & CreateProcOptions::Flag_NewProcessGroup)
+ {
+ posix_spawnattr_setflags(&Attr, POSIX_SPAWN_SETPGROUP);
+ posix_spawnattr_setpgroup(&Attr, 0);
+ }
+ else if (Options.ProcessGroupId > 0)
+ {
+ posix_spawnattr_setflags(&Attr, POSIX_SPAWN_SETPGROUP);
+ posix_spawnattr_setpgroup(&Attr, Options.ProcessGroupId);
+ }
+
+ EnvpHolder Envp(Options.Environment);
+
+ pid_t ChildPid = 0;
+ Err = posix_spawn(&ChildPid, Executable.c_str(), &FileActions, &Attr, ArgV.data(), Envp.Data);
+ if (Err != 0)
+ {
+ ThrowSystemError(Err, "Failed to posix_spawn a new child process");
+ }
+
+ return int(ChildPid);
#endif
}
@@ -966,14 +1398,28 @@ JobObject::Initialize()
}
JOBOBJECT_EXTENDED_LIMIT_INFORMATION LimitInfo = {};
- LimitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+ LimitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;
if (!SetInformationJobObject(m_JobHandle, JobObjectExtendedLimitInformation, &LimitInfo, sizeof(LimitInfo)))
{
ZEN_WARN("Failed to set job object limits: {}", zen::GetLastError());
CloseHandle(m_JobHandle);
m_JobHandle = nullptr;
+ return;
}
+
+ // Prevent child processes from clearing SEM_NOGPFAULTERRORBOX, which
+ // suppresses WER/Dr. Watson crash dialogs. Without this, a crashing
+ // child can pop a modal dialog and block the monitor thread.
+# if !defined(JOB_OBJECT_UILIMIT_ERRORMODE)
+# define JOB_OBJECT_UILIMIT_ERRORMODE 0x00000400
+# endif
+ JOBOBJECT_BASIC_UI_RESTRICTIONS UiRestrictions{};
+ UiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_ERRORMODE;
+ SetInformationJobObject(m_JobHandle, JobObjectBasicUIRestrictions, &UiRestrictions, sizeof(UiRestrictions));
+
+ // Set error mode on the current process so children inherit it.
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
}
bool
@@ -1431,47 +1877,60 @@ FindProcess(const std::filesystem::path& ExecutableImage, ProcessHandle& OutHand
return MakeErrorCodeFromLastError();
#endif // ZEN_PLATFORM_WINDOWS
#if ZEN_PLATFORM_MAC
- int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
- size_t BufferSize = 0;
-
- struct kinfo_proc* Processes = nullptr;
- uint32_t ProcCount = 0;
+ int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
const pid_t ThisProcessId = getpid();
- if (sysctl(Mib, 4, NULL, &BufferSize, NULL, 0) != -1 && BufferSize > 0)
+ // The process list can change between the sizing sysctl call and the data sysctl call.
+ // Retry with padding to handle this race.
+ struct kinfo_proc* Processes = nullptr;
+ size_t BufferSize = 0;
+ bool Fetched = false;
+ auto _ = MakeGuard([&]() { free(Processes); });
+
+ for (int Attempt = 0; Attempt < 3; Attempt++)
+ {
+ if (sysctl(Mib, 4, nullptr, &BufferSize, nullptr, 0) == -1 || BufferSize == 0)
+ {
+ break;
+ }
+ BufferSize += BufferSize / 4;
+ free(Processes);
+ Processes = (struct kinfo_proc*)malloc(BufferSize);
+ if (sysctl(Mib, 4, Processes, &BufferSize, nullptr, 0) != -1)
+ {
+ Fetched = true;
+ break;
+ }
+ }
+
+ if (!Fetched)
+ {
+ return MakeErrorCodeFromLastError();
+ }
+
+ uint32_t ProcCount = (uint32_t)(BufferSize / sizeof(struct kinfo_proc));
+ for (uint32_t ProcIndex = 0; ProcIndex < ProcCount; ProcIndex++)
{
- struct kinfo_proc* Processes = (struct kinfo_proc*)malloc(BufferSize);
- auto _ = MakeGuard([&]() { free(Processes); });
- if (sysctl(Mib, 4, Processes, &BufferSize, NULL, 0) != -1)
+ pid_t Pid = Processes[ProcIndex].kp_proc.p_pid;
+ if (IncludeSelf || (Pid != ThisProcessId))
{
- ProcCount = (uint32_t)(BufferSize / sizeof(struct kinfo_proc));
- char Buffer[PROC_PIDPATHINFO_MAXSIZE];
- for (uint32_t ProcIndex = 0; ProcIndex < ProcCount; ProcIndex++)
+ std::error_code Ec;
+ std::filesystem::path EntryPath = GetProcessExecutablePath(Pid, Ec);
+ if (!Ec)
{
- pid_t Pid = Processes[ProcIndex].kp_proc.p_pid;
- if (IncludeSelf || (Pid != ThisProcessId))
+ if (EntryPath == ExecutableImage)
{
- std::error_code Ec;
- std::filesystem::path EntryPath = GetProcessExecutablePath(Pid, Ec);
- if (!Ec)
+ if (Processes[ProcIndex].kp_proc.p_stat != SZOMB)
{
- if (EntryPath == ExecutableImage)
- {
- if (Processes[ProcIndex].kp_proc.p_stat != SZOMB)
- {
- OutHandle.Initialize(Pid, Ec);
- return Ec;
- }
- }
+ OutHandle.Initialize(Pid, Ec);
+ return Ec;
}
- Ec.clear();
}
}
- return {};
}
}
- return MakeErrorCodeFromLastError();
+ return {};
#endif // ZEN_PLATFORM_MAC
#if ZEN_PLATFORM_LINUX
const pid_t ThisProcessId = getpid();
@@ -1564,7 +2023,7 @@ WaitForThreads(uint64_t WaitTimeMs)
}
void
-GetProcessMetrics(ProcessHandle& Handle, ProcessMetrics& OutMetrics)
+GetProcessMetrics(const ProcessHandle& Handle, ProcessMetrics& OutMetrics)
{
#if ZEN_PLATFORM_WINDOWS
FILETIME CreationTime;
@@ -1593,11 +2052,137 @@ GetProcessMetrics(ProcessHandle& Handle, ProcessMetrics& OutMetrics)
OutMetrics.PeakWorkingSetSize = MemCounters.PeakWorkingSetSize;
OutMetrics.PagefileUsage = MemCounters.PagefileUsage;
OutMetrics.PeakPagefileUsage = MemCounters.PeakPagefileUsage;
+ OutMetrics.MemoryBytes = MemCounters.WorkingSetSize;
}
-#else
- // TODO: implement for Linux and Mac
- ZEN_UNUSED(Handle);
- ZEN_UNUSED(OutMetrics);
+#elif ZEN_PLATFORM_LINUX
+
+ const pid_t Pid = static_cast<pid_t>(Handle.Pid());
+
+ // Read CPU times from /proc/{pid}/stat
+ {
+ char Path[64];
+ snprintf(Path, sizeof(Path), "/proc/%d/stat", static_cast<int>(Pid));
+
+ char Buf[256];
+ int Fd = open(Path, O_RDONLY);
+ if (Fd >= 0)
+ {
+ ssize_t Len = read(Fd, Buf, sizeof(Buf) - 1);
+ close(Fd);
+
+ if (Len > 0)
+ {
+ Buf[Len] = '\0';
+
+ // Skip past "pid (name) " — find last ')' to handle names containing spaces or parens
+ const char* P = strrchr(Buf, ')');
+ if (P)
+ {
+ P += 2; // skip ') '
+
+ // Fields after (name): 0:state 1:ppid ... 11:utime 12:stime
+ unsigned long UTime = 0;
+ unsigned long STime = 0;
+ if (sscanf(P, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &UTime, &STime) == 2)
+ {
+ static const long ClkTck = std::max(sysconf(_SC_CLK_TCK), 1L);
+ OutMetrics.KernelTimeMs = STime * 1000 / ClkTck;
+ OutMetrics.UserTimeMs = UTime * 1000 / ClkTck;
+ }
+ }
+ }
+ }
+ }
+
+ // Read memory metrics from /proc/{pid}/statm (values in pages)
+ {
+ char Path[64];
+ snprintf(Path, sizeof(Path), "/proc/%d/statm", static_cast<int>(Pid));
+
+ char Buf[128];
+ int Fd = open(Path, O_RDONLY);
+ if (Fd >= 0)
+ {
+ ssize_t Len = read(Fd, Buf, sizeof(Buf) - 1);
+ close(Fd);
+
+ if (Len > 0)
+ {
+ Buf[Len] = '\0';
+
+ // Fields: size resident shared text lib data dt
+ unsigned long VmSize = 0;
+ unsigned long Resident = 0;
+ if (sscanf(Buf, "%lu %lu", &VmSize, &Resident) == 2)
+ {
+ static const long PageSize = sysconf(_SC_PAGESIZE);
+ OutMetrics.WorkingSetSize = Resident * PageSize;
+ OutMetrics.PagefileUsage = VmSize * PageSize;
+ }
+ }
+ }
+ }
+
+ // Read peak RSS from /proc/{pid}/status (VmHWM line)
+ {
+ char Path[64];
+ snprintf(Path, sizeof(Path), "/proc/%d/status", static_cast<int>(Pid));
+
+ char Buf[2048];
+ int Fd = open(Path, O_RDONLY);
+ if (Fd >= 0)
+ {
+ ssize_t Len = read(Fd, Buf, sizeof(Buf) - 1);
+ close(Fd);
+
+ if (Len > 0)
+ {
+ Buf[Len] = '\0';
+
+ const char* VmHWM = strstr(Buf, "VmHWM:");
+ if (VmHWM)
+ {
+ unsigned long PeakRssKb = 0;
+ if (sscanf(VmHWM + 6, "%lu", &PeakRssKb) == 1)
+ {
+ OutMetrics.PeakWorkingSetSize = PeakRssKb * 1024;
+ }
+ }
+
+ const char* VmPeak = strstr(Buf, "VmPeak:");
+ if (VmPeak)
+ {
+ unsigned long PeakVmKb = 0;
+ if (sscanf(VmPeak + 7, "%lu", &PeakVmKb) == 1)
+ {
+ OutMetrics.PeakPagefileUsage = PeakVmKb * 1024;
+ }
+ }
+ }
+ }
+ }
+
+ OutMetrics.MemoryBytes = OutMetrics.WorkingSetSize;
+
+#elif ZEN_PLATFORM_MAC
+
+ const pid_t Pid = static_cast<pid_t>(Handle.Pid());
+
+ struct proc_taskinfo Info;
+ if (proc_pidinfo(Pid, PROC_PIDTASKINFO, 0, &Info, sizeof(Info)) > 0)
+ {
+ // pti_total_user and pti_total_system are in nanoseconds
+ OutMetrics.UserTimeMs = Info.pti_total_user / 1'000'000;
+ OutMetrics.KernelTimeMs = Info.pti_total_system / 1'000'000;
+
+ OutMetrics.WorkingSetSize = Info.pti_resident_size;
+ OutMetrics.PeakWorkingSetSize = Info.pti_resident_size; // macOS doesn't track peak RSS directly
+ OutMetrics.PagefileUsage = Info.pti_virtual_size;
+ OutMetrics.PeakPagefileUsage = Info.pti_virtual_size;
+ }
+
+ OutMetrics.MemoryBytes = OutMetrics.WorkingSetSize;
+
#endif
}
@@ -1639,6 +2224,24 @@ TEST_CASE("FindProcess")
}
}
+TEST_CASE("GetProcessMetrics")
+{
+ ProcessHandle Handle;
+ Handle.Initialize(GetCurrentProcessId());
+ REQUIRE(Handle.IsValid());
+
+ ProcessMetrics Metrics;
+ GetProcessMetrics(Handle, Metrics);
+
+ // The current process should have non-zero memory usage
+ CHECK(Metrics.WorkingSetSize > 0);
+ CHECK(Metrics.MemoryBytes > 0);
+ CHECK(Metrics.MemoryBytes == Metrics.WorkingSetSize);
+
+ // CPU time should be non-zero for a running test process
+ CHECK((Metrics.UserTimeMs + Metrics.KernelTimeMs) > 0);
+}
+
TEST_CASE("BuildArgV")
{
const char* Words[] = {"one", "two", "three", "four", "five"};
diff --git a/src/zencore/sentryintegration.cpp b/src/zencore/sentryintegration.cpp
index c9c843dd6..8491bef64 100644
--- a/src/zencore/sentryintegration.cpp
+++ b/src/zencore/sentryintegration.cpp
@@ -341,7 +341,7 @@ SentryIntegration::Initialize(const Config& Conf, const std::string& CommandLine
sentry_set_user(SentryUserObject);
logging::SinkPtr SentrySink(new sentry::SentrySink());
- m_SentryLogger = Ref<logging::Logger>(new logging::Logger("sentry", std::vector<logging::SinkPtr>{SentrySink}));
+ m_SentryLogger = Ref<logging::Logger>(new logging::Logger("sentry", SentrySink));
logging::Registry::Instance().Register(m_SentryLogger);
logging::SetErrorLog("sentry");
diff --git a/src/zencore/system.cpp b/src/zencore/system.cpp
index 8985a8a76..6909e1a9b 100644
--- a/src/zencore/system.cpp
+++ b/src/zencore/system.cpp
@@ -14,20 +14,27 @@
# include <zencore/windows.h>
ZEN_THIRD_PARTY_INCLUDES_START
-# include <iphlpapi.h>
# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <iphlpapi.h>
# include <pdh.h>
# pragma comment(lib, "pdh.lib")
ZEN_THIRD_PARTY_INCLUDES_END
#elif ZEN_PLATFORM_LINUX
# include <sys/utsname.h>
# include <unistd.h>
+# include <ifaddrs.h>
+# include <arpa/inet.h>
+# include <net/if.h>
#elif ZEN_PLATFORM_MAC
# include <unistd.h>
# include <mach/mach.h>
# include <mach/mach_host.h>
# include <sys/types.h>
# include <sys/sysctl.h>
+# include <ifaddrs.h>
+# include <arpa/inet.h>
+# include <net/if.h>
#endif
namespace zen {
@@ -140,6 +147,51 @@ GetSystemMetrics()
return Metrics;
}
+
+std::vector<std::string>
+GetLocalIpAddresses()
+{
+ std::vector<std::string> Result;
+
+ ULONG BufSize = 15000;
+ auto* Addresses = static_cast<IP_ADAPTER_ADDRESSES*>(Memory::Alloc(BufSize));
+
+ ULONG Flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST;
+ ULONG Ret = GetAdaptersAddresses(AF_INET, Flags, nullptr, Addresses, &BufSize);
+ if (Ret == ERROR_BUFFER_OVERFLOW)
+ {
+ Memory::Free(Addresses);
+ Addresses = static_cast<IP_ADAPTER_ADDRESSES*>(Memory::Alloc(BufSize));
+ Ret = GetAdaptersAddresses(AF_INET, Flags, nullptr, Addresses, &BufSize);
+ }
+
+ if (Ret == NO_ERROR)
+ {
+ for (IP_ADAPTER_ADDRESSES* Adapter = Addresses; Adapter != nullptr; Adapter = Adapter->Next)
+ {
+ if (Adapter->OperStatus != IfOperStatusUp)
+ {
+ continue;
+ }
+ if (Adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
+ {
+ continue;
+ }
+ for (IP_ADAPTER_UNICAST_ADDRESS* Unicast = Adapter->FirstUnicastAddress; Unicast != nullptr; Unicast = Unicast->Next)
+ {
+ sockaddr_in* SockAddr = reinterpret_cast<sockaddr_in*>(Unicast->Address.lpSockaddr);
+ char AddrBuf[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, &SockAddr->sin_addr, AddrBuf, sizeof(AddrBuf)))
+ {
+ Result.emplace_back(AddrBuf);
+ }
+ }
+ }
+ }
+
+ Memory::Free(Addresses);
+ return Result;
+}
#elif ZEN_PLATFORM_LINUX
std::string
GetMachineName()
@@ -350,6 +402,42 @@ GetSystemMetrics()
# error "Unknown platform"
#endif
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+std::vector<std::string>
+GetLocalIpAddresses()
+{
+ std::vector<std::string> Result;
+
+ ifaddrs* Interfaces = nullptr;
+ if (getifaddrs(&Interfaces) != 0)
+ {
+ return Result;
+ }
+
+ for (ifaddrs* Iface = Interfaces; Iface != nullptr; Iface = Iface->ifa_next)
+ {
+ if (Iface->ifa_addr == nullptr || Iface->ifa_addr->sa_family != AF_INET)
+ {
+ continue;
+ }
+ if ((Iface->ifa_flags & IFF_LOOPBACK) != 0 || (Iface->ifa_flags & IFF_UP) == 0)
+ {
+ continue;
+ }
+
+ sockaddr_in* SockAddr = reinterpret_cast<sockaddr_in*>(Iface->ifa_addr);
+ char AddrBuf[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, &SockAddr->sin_addr, AddrBuf, sizeof(AddrBuf)))
+ {
+ Result.emplace_back(AddrBuf);
+ }
+ }
+
+ freeifaddrs(Interfaces);
+ return Result;
+}
+#endif
+
ExtendedSystemMetrics
ApplyReportingOverrides(ExtendedSystemMetrics Metrics)
{
@@ -445,23 +533,15 @@ struct CpuSampler
PDH_HQUERY QueryHandle = nullptr;
PDH_HCOUNTER CounterHandle = nullptr;
bool HasPreviousSample = false;
+ bool IsInitialized = false;
bool IsWine = false;
ProcStatCpuSampler ProcStat{"Z:\\proc\\stat"};
CpuSampler()
{
IsWine = zen::windows::IsRunningOnWine();
-
- if (!IsWine)
- {
- if (PdhOpenQueryW(nullptr, 0, &QueryHandle) == ERROR_SUCCESS)
- {
- if (PdhAddEnglishCounterW(QueryHandle, L"\\Processor(_Total)\\% Processor Time", 0, &CounterHandle) != ERROR_SUCCESS)
- {
- CounterHandle = nullptr;
- }
- }
- }
+ // PDH initialization is deferred to the first Sample() call because
+ // PdhAddEnglishCounterW can take hundreds of milliseconds on first invocation.
}
~CpuSampler()
@@ -472,6 +552,22 @@ struct CpuSampler
}
}
+ void InitializePdh()
+ {
+ if (IsInitialized)
+ {
+ return;
+ }
+ IsInitialized = true;
+ if (PdhOpenQueryW(nullptr, 0, &QueryHandle) == ERROR_SUCCESS)
+ {
+ if (PdhAddEnglishCounterW(QueryHandle, L"\\Processor(_Total)\\% Processor Time", 0, &CounterHandle) != ERROR_SUCCESS)
+ {
+ CounterHandle = nullptr;
+ }
+ }
+ }
+
float Sample()
{
if (IsWine)
@@ -479,6 +575,8 @@ struct CpuSampler
return ProcStat.Sample();
}
+ InitializePdh();
+
if (!QueryHandle || !CounterHandle)
{
return 0.0f;
diff --git a/src/zencore/testing.cpp b/src/zencore/testing.cpp
index c6ee5ee6b..9f88a3365 100644
--- a/src/zencore/testing.cpp
+++ b/src/zencore/testing.cpp
@@ -309,10 +309,6 @@ RunTestMain(int Argc, char* Argv[], const char* ExecutableName, void (*ForceLink
ForceLink();
-# if ZEN_PLATFORM_LINUX
- zen::IgnoreChildSignals();
-# endif
-
# if ZEN_WITH_TRACE
zen::TraceInit(ExecutableName);
zen::TraceOptions TraceCommandlineOptions;
diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp
index 54459cbaa..067e66c0d 100644
--- a/src/zencore/thread.cpp
+++ b/src/zencore/thread.cpp
@@ -146,6 +146,12 @@ RwLock::AcquireShared() noexcept
m_Mutex.lock_shared();
}
+bool
+RwLock::TryAcquireShared() noexcept
+{
+ return m_Mutex.try_lock_shared();
+}
+
void
RwLock::ReleaseShared() noexcept
{
@@ -158,6 +164,12 @@ RwLock::AcquireExclusive() noexcept
m_Mutex.lock();
}
+bool
+RwLock::TryAcquireExclusive() noexcept
+{
+ return m_Mutex.try_lock();
+}
+
void
RwLock::ReleaseExclusive() noexcept
{
@@ -491,6 +503,18 @@ NamedMutex::~NamedMutex()
if (m_MutexHandle)
{
int Inner = int(intptr_t(m_MutexHandle));
+
+ // Remove the backing file before releasing the lock so that new callers
+ // of Create()/Exists() won't find a stale entry. Other processes that
+ // already have the file open still hold valid fds (unlink only removes
+ // the directory entry; the inode lives until the last fd is closed).
+ std::error_code Ec;
+ std::filesystem::path Name = PathFromHandle((void*)(intptr_t(Inner)), Ec);
+ if (!Ec)
+ {
+ unlink(Name.c_str());
+ }
+
flock(Inner, LOCK_UN);
close(Inner);
}
diff --git a/src/zencore/zencore.cpp b/src/zencore/zencore.cpp
index 8c29a8962..c1ac63621 100644
--- a/src/zencore/zencore.cpp
+++ b/src/zencore/zencore.cpp
@@ -273,7 +273,7 @@ zencore_forcelinktests()
zen::uid_forcelink();
zen::uson_forcelink();
zen::usonbuilder_forcelink();
- zen::usonpackage_forcelink();
+ zen::cbpackage_forcelink();
zen::cbjson_forcelink();
zen::cbyaml_forcelink();
zen::workthreadpool_forcelink();
diff --git a/src/zenhorde/hordeclient.cpp b/src/zenhorde/hordeclient.cpp
index fb981f0ba..0eefc57c6 100644
--- a/src/zenhorde/hordeclient.cpp
+++ b/src/zenhorde/hordeclient.cpp
@@ -35,10 +35,7 @@ HordeClient::Initialize()
if (!m_Config.AuthToken.empty())
{
Settings.AccessTokenProvider = [token = m_Config.AuthToken]() -> HttpClientAccessToken {
- HttpClientAccessToken Token;
- Token.Value = token;
- Token.ExpireTime = HttpClientAccessToken::Clock::now() + std::chrono::hours{24};
- return Token;
+ return HttpClientAccessToken(token, HttpClientAccessToken::Clock::now() + std::chrono::hours{24});
};
}
diff --git a/src/zenhorde/xmake.lua b/src/zenhorde/xmake.lua
index 48d028e86..0e69e9c5f 100644
--- a/src/zenhorde/xmake.lua
+++ b/src/zenhorde/xmake.lua
@@ -14,7 +14,7 @@ target('zenhorde')
end
if is_plat("linux") or is_plat("macosx") then
- add_packages("openssl")
+ add_packages("openssl3")
end
if is_os("macosx") then
diff --git a/src/zenhttp/clients/httpclientcommon.h b/src/zenhttp/clients/httpclientcommon.h
index e8d969cc8..078d4a52f 100644
--- a/src/zenhttp/clients/httpclientcommon.h
+++ b/src/zenhttp/clients/httpclientcommon.h
@@ -21,7 +21,10 @@ public:
using Response = HttpClient::Response;
using KeyValueMap = HttpClient::KeyValueMap;
- [[nodiscard]] virtual Response Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) = 0;
+ [[nodiscard]] virtual Response Put(std::string_view Url,
+ const IoBuffer& Payload,
+ const KeyValueMap& AdditionalHeader = {},
+ const KeyValueMap& Parameters = {}) = 0;
[[nodiscard]] virtual Response Put(std::string_view Url, const KeyValueMap& Parameters = {}) = 0;
[[nodiscard]] virtual Response Get(std::string_view Url,
const KeyValueMap& AdditionalHeader = {},
@@ -59,6 +62,7 @@ public:
LoggerRef Log() { return m_Log; }
std::string_view GetBaseUri() const { return m_BaseUri; }
+ void SetBaseUri(std::string_view NewBaseUri) { m_BaseUri = NewBaseUri; }
std::string_view GetSessionId() const { return m_SessionId; }
bool Authenticate();
diff --git a/src/zenhttp/clients/httpclientcpr.cpp b/src/zenhttp/clients/httpclientcpr.cpp
deleted file mode 100644
index bd6de3ff7..000000000
--- a/src/zenhttp/clients/httpclientcpr.cpp
+++ /dev/null
@@ -1,1285 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#include "httpclientcpr.h"
-
-#include <zencore/compactbinary.h>
-#include <zencore/compactbinarybuilder.h>
-#include <zencore/compactbinarypackage.h>
-#include <zencore/compactbinaryutil.h>
-#include <zencore/compress.h>
-#include <zencore/filesystem.h>
-#include <zencore/iobuffer.h>
-#include <zencore/iohash.h>
-#include <zencore/session.h>
-#include <zencore/stream.h>
-#include <zenhttp/packageformat.h>
-#include <algorithm>
-
-ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/ssl_options.h>
-#include <cpr/unix_socket.h>
-ZEN_THIRD_PARTY_INCLUDES_END
-
-namespace zen {
-
-HttpClientBase*
-CreateCprHttpClient(std::string_view BaseUri, const HttpClientSettings& ConnectionSettings, std::function<bool()>&& CheckIfAbortFunction)
-{
- return new CprHttpClient(BaseUri, ConnectionSettings, std::move(CheckIfAbortFunction));
-}
-
-static std::atomic<uint32_t> HttpClientRequestIdCounter{0};
-
-//////////////////////////////////////////////////////////////////////////
-
-static HttpClientErrorCode
-MapCprError(cpr::ErrorCode Code)
-{
- switch (Code)
- {
- case cpr::ErrorCode::OK:
- return HttpClientErrorCode::kOK;
- case cpr::ErrorCode::CONNECTION_FAILURE:
- return HttpClientErrorCode::kConnectionFailure;
- case cpr::ErrorCode::HOST_RESOLUTION_FAILURE:
- return HttpClientErrorCode::kHostResolutionFailure;
- case cpr::ErrorCode::PROXY_RESOLUTION_FAILURE:
- return HttpClientErrorCode::kProxyResolutionFailure;
- case cpr::ErrorCode::INTERNAL_ERROR:
- return HttpClientErrorCode::kInternalError;
- case cpr::ErrorCode::NETWORK_RECEIVE_ERROR:
- return HttpClientErrorCode::kNetworkReceiveError;
- case cpr::ErrorCode::NETWORK_SEND_FAILURE:
- return HttpClientErrorCode::kNetworkSendFailure;
- case cpr::ErrorCode::OPERATION_TIMEDOUT:
- return HttpClientErrorCode::kOperationTimedOut;
- case cpr::ErrorCode::SSL_CONNECT_ERROR:
- return HttpClientErrorCode::kSSLConnectError;
- case cpr::ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR:
- case cpr::ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR:
- return HttpClientErrorCode::kSSLCertificateError;
- case cpr::ErrorCode::SSL_CACERT_ERROR:
- return HttpClientErrorCode::kSSLCACertError;
- case cpr::ErrorCode::GENERIC_SSL_ERROR:
- return HttpClientErrorCode::kGenericSSLError;
- case cpr::ErrorCode::REQUEST_CANCELLED:
- return HttpClientErrorCode::kRequestCancelled;
- default:
- return HttpClientErrorCode::kOtherError;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-//
-// CPR helpers
-
-static cpr::Body
-AsCprBody(const CbObject& Obj)
-{
- return cpr::Body((const char*)Obj.GetBuffer().GetData(), Obj.GetBuffer().GetSize());
-}
-
-static cpr::Body
-AsCprBody(const IoBuffer& Obj)
-{
- return cpr::Body((const char*)Obj.GetData(), Obj.GetSize());
-}
-
-static bool
-ShouldRetry(const cpr::Response& Response)
-{
- switch (Response.error.code)
- {
- case cpr::ErrorCode::OK:
- break;
- case cpr::ErrorCode::INTERNAL_ERROR:
- case cpr::ErrorCode::NETWORK_RECEIVE_ERROR:
- case cpr::ErrorCode::NETWORK_SEND_FAILURE:
- case cpr::ErrorCode::OPERATION_TIMEDOUT:
- return true;
- default:
- return false;
- }
- switch ((HttpResponseCode)Response.status_code)
- {
- case HttpResponseCode::RequestTimeout:
- case HttpResponseCode::TooManyRequests:
- case HttpResponseCode::InternalServerError:
- case HttpResponseCode::BadGateway:
- case HttpResponseCode::ServiceUnavailable:
- case HttpResponseCode::GatewayTimeout:
- return true;
- default:
- return false;
- }
-};
-
-static std::pair<std::string, std::string>
-HeaderContentType(ZenContentType ContentType)
-{
- return std::make_pair("Content-Type", std::string(MapContentTypeToString(ContentType)));
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-CprHttpClient::CprHttpClient(std::string_view BaseUri,
- const HttpClientSettings& Connectionsettings,
- std::function<bool()>&& CheckIfAbortFunction)
-: HttpClientBase(BaseUri, Connectionsettings, std::move(CheckIfAbortFunction))
-{
-}
-
-bool
-CprHttpClient::ShouldLogErrorCode(HttpResponseCode ResponseCode) const
-{
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- // Quiet
- return false;
- }
- const auto& Expected = m_ConnectionSettings.ExpectedErrorCodes;
- return std::find(Expected.begin(), Expected.end(), ResponseCode) == Expected.end();
-}
-
-CprHttpClient::~CprHttpClient()
-{
- ZEN_TRACE_CPU("CprHttpClient::~CprHttpClient");
- m_SessionLock.WithExclusiveLock([&] {
- for (auto CprSession : m_Sessions)
- {
- delete CprSession;
- }
- m_Sessions.clear();
- });
-}
-
-HttpClient::Response
-CprHttpClient::ResponseWithPayload(std::string_view SessionId,
- cpr::Response&& HttpResponse,
- const HttpResponseCode WorkResponseCode,
- IoBuffer&& Payload,
- std::vector<HttpClient::Response::MultipartBoundary>&& BoundaryPositions)
-{
- // This ends up doing a memcpy, would be good to get rid of it by streaming results
- // into buffer directly
- IoBuffer ResponseBuffer = Payload ? std::move(Payload) : IoBuffer(IoBuffer::Clone, HttpResponse.text.data(), HttpResponse.text.size());
-
- if (auto It = HttpResponse.header.find("Content-Type"); It != HttpResponse.header.end())
- {
- const HttpContentType ContentType = ParseContentType(It->second);
- ResponseBuffer.SetContentType(ContentType);
- }
-
- if (!IsHttpSuccessCode(WorkResponseCode) && WorkResponseCode != HttpResponseCode::NotFound)
- {
- if (ShouldLogErrorCode(WorkResponseCode))
- {
- ZEN_WARN("HttpClient request failed (session: {}): {}", SessionId, HttpResponse);
- }
- }
-
- std::sort(BoundaryPositions.begin(),
- BoundaryPositions.end(),
- [](const HttpClient::Response::MultipartBoundary& Lhs, const HttpClient::Response::MultipartBoundary& Rhs) {
- return Lhs.RangeOffset < Rhs.RangeOffset;
- });
-
- return HttpClient::Response{.StatusCode = WorkResponseCode,
- .ResponsePayload = std::move(ResponseBuffer),
- .Header = HttpClient::KeyValueMap(HttpResponse.header.begin(), HttpResponse.header.end()),
- .UploadedBytes = gsl::narrow<int64_t>(HttpResponse.uploaded_bytes),
- .DownloadedBytes = gsl::narrow<int64_t>(HttpResponse.downloaded_bytes),
- .ElapsedSeconds = HttpResponse.elapsed,
- .Ranges = std::move(BoundaryPositions)};
-}
-
-HttpClient::Response
-CprHttpClient::CommonResponse(std::string_view SessionId,
- cpr::Response&& HttpResponse,
- IoBuffer&& Payload,
- std::vector<HttpClient::Response::MultipartBoundary>&& BoundaryPositions)
-{
- const HttpResponseCode WorkResponseCode = HttpResponseCode(HttpResponse.status_code);
- if (HttpResponse.error)
- {
- const bool Quiet = m_CheckIfAbortFunction && m_CheckIfAbortFunction();
- if (!Quiet)
- {
- if (HttpResponse.error.code != cpr::ErrorCode::OPERATION_TIMEDOUT &&
- HttpResponse.error.code != cpr::ErrorCode::CONNECTION_FAILURE &&
- HttpResponse.error.code != cpr::ErrorCode::REQUEST_CANCELLED)
- {
- ZEN_WARN("HttpClient client failure (session: {}): {}", SessionId, HttpResponse);
- }
- }
-
- // Client side failure code
- return HttpClient::Response{
- .StatusCode = WorkResponseCode,
- .ResponsePayload = IoBufferBuilder::MakeCloneFromMemory(HttpResponse.text.data(), HttpResponse.text.size()),
- .Header = HttpClient::KeyValueMap(HttpResponse.header.begin(), HttpResponse.header.end()),
- .UploadedBytes = gsl::narrow<int64_t>(HttpResponse.uploaded_bytes),
- .DownloadedBytes = gsl::narrow<int64_t>(HttpResponse.downloaded_bytes),
- .ElapsedSeconds = HttpResponse.elapsed,
- .Error =
- HttpClient::ErrorContext{.ErrorCode = MapCprError(HttpResponse.error.code), .ErrorMessage = HttpResponse.error.message}};
- }
-
- if (WorkResponseCode == HttpResponseCode::NoContent || (HttpResponse.text.empty() && !Payload))
- {
- return HttpClient::Response{.StatusCode = WorkResponseCode,
- .Header = HttpClient::KeyValueMap(HttpResponse.header.begin(), HttpResponse.header.end()),
- .UploadedBytes = gsl::narrow<int64_t>(HttpResponse.uploaded_bytes),
- .DownloadedBytes = gsl::narrow<int64_t>(HttpResponse.downloaded_bytes),
- .ElapsedSeconds = HttpResponse.elapsed};
- }
- else
- {
- return ResponseWithPayload(SessionId, std::move(HttpResponse), WorkResponseCode, std::move(Payload), std::move(BoundaryPositions));
- }
-}
-
-bool
-CprHttpClient::ValidatePayload(cpr::Response& Response, std::unique_ptr<detail::TempPayloadFile>& PayloadFile)
-{
- ZEN_TRACE_CPU("ValidatePayload");
- IoBuffer ResponseBuffer = (Response.text.empty() && PayloadFile) ? PayloadFile->BorrowIoBuffer()
- : IoBuffer(IoBuffer::Wrap, Response.text.data(), Response.text.size());
-
- if (auto ContentLength = Response.header.find("Content-Length"); ContentLength != Response.header.end())
- {
- std::optional<uint64_t> ExpectedContentSize = ParseInt<uint64_t>(ContentLength->second);
- if (!ExpectedContentSize.has_value())
- {
- Response.error =
- cpr::Error(/*CURLE_READ_ERROR*/ 26, fmt::format("Can not parse Content-Length header. Value: '{}'", ContentLength->second));
- return false;
- }
- if (ExpectedContentSize.value() != ResponseBuffer.GetSize())
- {
- Response.error = cpr::Error(
- /*CURLE_READ_ERROR*/ 26,
- fmt::format("Payload size {} does not match Content-Length {}", ResponseBuffer.GetSize(), ContentLength->second));
- return false;
- }
- }
-
- if (Response.status_code == (long)HttpResponseCode::PartialContent)
- {
- return true;
- }
-
- if (auto JupiterHash = Response.header.find("X-Jupiter-IoHash"); JupiterHash != Response.header.end())
- {
- IoHash ExpectedPayloadHash;
- if (IoHash::TryParse(JupiterHash->second, ExpectedPayloadHash))
- {
- IoHash PayloadHash = IoHash::HashBuffer(ResponseBuffer);
- if (PayloadHash != ExpectedPayloadHash)
- {
- Response.error = cpr::Error(/*CURLE_READ_ERROR*/ 26,
- fmt::format("Payload hash {} does not match X-Jupiter-IoHash {}",
- PayloadHash.ToHexString(),
- ExpectedPayloadHash.ToHexString()));
- return false;
- }
- }
- }
-
- if (auto ContentType = Response.header.find("Content-Type"); ContentType != Response.header.end())
- {
- if (ContentType->second == "application/x-ue-comp")
- {
- IoHash RawHash;
- uint64_t RawSize;
- if (CompressedBuffer::ValidateCompressedHeader(ResponseBuffer, RawHash, RawSize, /*OutOptionalTotalCompressedSize*/ nullptr))
- {
- return true;
- }
- else
- {
- Response.error = cpr::Error(/*CURLE_READ_ERROR*/ 26, "Compressed binary failed validation");
- return false;
- }
- }
- if (ContentType->second == "application/x-ue-cb")
- {
- if (CbValidateError Error = ValidateCompactBinary(ResponseBuffer.GetView(), CbValidateMode::Default);
- Error == CbValidateError::None)
- {
- return true;
- }
- else
- {
- Response.error = cpr::Error(/*CURLE_READ_ERROR*/ 26, fmt::format("Compact binary failed validation: {}", ToString(Error)));
- return false;
- }
- }
- }
-
- return true;
-}
-
-cpr::Response
-CprHttpClient::DoWithRetry(std::string_view SessionId,
- std::function<cpr::Response()>&& Func,
- std::function<bool(cpr::Response& Result)>&& Validate)
-{
- uint8_t Attempt = 0;
- cpr::Response Result = Func();
- while (Attempt < m_ConnectionSettings.RetryCount)
- {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return Result;
- }
- if (!ShouldRetry(Result))
- {
- if (Result.error || !IsHttpSuccessCode(Result.status_code))
- {
- break;
- }
- if (Validate(Result))
- {
- break;
- }
- }
- Sleep(100 * (Attempt + 1));
- Attempt++;
- if (ShouldLogErrorCode(HttpResponseCode(Result.status_code)))
- {
- ZEN_INFO("{} Attempt {}/{}",
- CommonResponse(SessionId, std::move(Result), {}).ErrorMessage("Retry"),
- Attempt,
- m_ConnectionSettings.RetryCount + 1);
- }
- Result = Func();
- }
- return Result;
-}
-
-cpr::Response
-CprHttpClient::DoWithRetry(std::string_view SessionId,
- std::function<cpr::Response()>&& Func,
- std::unique_ptr<detail::TempPayloadFile>& PayloadFile)
-{
- uint8_t Attempt = 0;
- cpr::Response Result = Func();
- while (Attempt < m_ConnectionSettings.RetryCount)
- {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return Result;
- }
- if (!ShouldRetry(Result))
- {
- if (Result.error || !IsHttpSuccessCode(Result.status_code))
- {
- break;
- }
- if (ValidatePayload(Result, PayloadFile))
- {
- break;
- }
- }
- Sleep(100 * (Attempt + 1));
- Attempt++;
- if (ShouldLogErrorCode(HttpResponseCode(Result.status_code)))
- {
- ZEN_INFO("{} Attempt {}/{}",
- CommonResponse(SessionId, std::move(Result), {}).ErrorMessage("Retry"),
- Attempt,
- m_ConnectionSettings.RetryCount + 1);
- }
- Result = Func();
- }
- return Result;
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-CprHttpClient::Session
-CprHttpClient::AllocSession(const std::string_view BaseUrl,
- const std::string_view ResourcePath,
- const HttpClientSettings& ConnectionSettings,
- const KeyValueMap& AdditionalHeader,
- const KeyValueMap& Parameters,
- const std::string_view SessionId,
- std::optional<std::string> AccessToken)
-{
- ZEN_TRACE_CPU("CprHttpClient::AllocSession");
- cpr::Session* CprSession = nullptr;
- m_SessionLock.WithExclusiveLock([&] {
- if (!m_Sessions.empty())
- {
- CprSession = m_Sessions.back();
- m_Sessions.pop_back();
- }
- });
-
- if (CprSession == nullptr)
- {
- CprSession = new cpr::Session();
- CprSession->SetConnectTimeout(ConnectionSettings.ConnectTimeout);
- CprSession->SetTimeout(ConnectionSettings.Timeout);
- if (ConnectionSettings.AssumeHttp2)
- {
- CprSession->SetHttpVersion(cpr::HttpVersion{cpr::HttpVersionCode::VERSION_2_0_PRIOR_KNOWLEDGE});
- }
- if (ConnectionSettings.Verbose)
- {
- // CprSession->SetVerbose(cpr::Verbose{ true });
- CprSession->SetDebugCallback(cpr::DebugCallback{
- [this](cpr::DebugCallback::InfoType type, std::string data, intptr_t userdata) {
- cpr::Session* CprSession = (cpr::Session*)userdata;
- ZEN_UNUSED(CprSession);
- switch (type)
- {
- case cpr::DebugCallback::InfoType::TEXT:
- if (data.find("need more data"sv) == std::string::npos)
- {
- ZEN_INFO("TEXT: {}", data);
- }
- break;
- case cpr::DebugCallback::InfoType::HEADER_IN:
- ZEN_INFO("HIN : {}", data);
- break;
- case cpr::DebugCallback::InfoType::HEADER_OUT:
- if (std::string::size_type TokenPos = data.find("Authorization: Bearer "sv); TokenPos != std::string::npos)
- {
- TokenPos += 22;
- std::string::size_type TokenEndPos = data.find_first_of("\r\n", TokenPos);
- if (TokenEndPos == std::string::npos)
- {
- TokenEndPos = data.length();
- }
- std::string Copy = data;
- Copy.replace(Copy.begin() + TokenPos,
- Copy.begin() + TokenEndPos,
- fmt::format("[{} char token]", TokenEndPos - TokenPos));
- ZEN_INFO("HOUT: {}", Copy);
- }
- else
- {
- ZEN_INFO("HOUT: {}", data);
- }
- break;
- case cpr::DebugCallback::InfoType::DATA_IN:
- // ZEN_INFO("DATA_IN: {}", data);
- break;
- case cpr::DebugCallback::InfoType::DATA_OUT:
- // ZEN_INFO("DATA_OUT: {}", data);
- break;
- case cpr::DebugCallback::InfoType::SSL_DATA_IN:
- // ZEN_INFO("SSL_DATA_IN: {}", data);
- break;
- case cpr::DebugCallback::InfoType::SSL_DATA_OUT:
- // ZEN_INFO("SSL_DATA_OUT: {}", data);
- break;
- }
- },
- (intptr_t)CprSession});
- }
- }
-
- if (!AdditionalHeader->empty())
- {
- CprSession->SetHeader(cpr::Header(AdditionalHeader->begin(), AdditionalHeader->end()));
- }
- if (!SessionId.empty())
- {
- CprSession->UpdateHeader({{"UE-Session", std::string(SessionId)}});
- }
- if (ConnectionSettings.ForbidReuseConnection)
- {
- CprSession->UpdateHeader({{"Connection", "close"}});
- }
-
- if (AccessToken.has_value())
- {
- CprSession->UpdateHeader({{"Authorization", AccessToken.value()}});
- }
- if (!Parameters->empty())
- {
- cpr::Parameters Tmp;
- for (auto It = Parameters->begin(); It != Parameters->end(); It++)
- {
- Tmp.Add({It->first, It->second});
- }
- CprSession->SetParameters(Tmp);
- }
- else
- {
- CprSession->SetParameters({});
- }
-
- if (!ConnectionSettings.UnixSocketPath.empty())
- {
- CprSession->SetUnixSocket(cpr::UnixSocket(PathToUtf8(ConnectionSettings.UnixSocketPath)));
- }
-
- if (ConnectionSettings.InsecureSsl || !ConnectionSettings.CaBundlePath.empty())
- {
- cpr::SslOptions SslOpts;
- if (ConnectionSettings.InsecureSsl)
- {
- SslOpts.SetOption(cpr::ssl::VerifyHost{false});
- SslOpts.SetOption(cpr::ssl::VerifyPeer{false});
- }
- if (!ConnectionSettings.CaBundlePath.empty())
- {
- SslOpts.SetOption(cpr::ssl::CaInfo{ConnectionSettings.CaBundlePath});
- }
- CprSession->SetSslOptions(SslOpts);
- }
-
- ExtendableStringBuilder<128> UrlBuffer;
- UrlBuffer << BaseUrl << ResourcePath;
- CprSession->SetUrl(UrlBuffer.c_str());
-
- return Session(this, CprSession);
-}
-
-void
-CprHttpClient::ReleaseSession(cpr::Session* CprSession)
-{
- ZEN_TRACE_CPU("CprHttpClient::ReleaseSession");
- CprSession->SetUrl({});
- CprSession->SetHeader({});
- CprSession->SetBody({});
- m_SessionLock.WithExclusiveLock([&] { m_Sessions.push_back(CprSession); });
-}
-
-CprHttpClient::Response
-CprHttpClient::TransactPackage(std::string_view Url, CbPackage Package, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::TransactPackage");
-
- Session Sess = AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
-
- // First, list of offered chunks for filtering on the server end
-
- std::vector<IoHash> AttachmentsToSend;
- std::span<const CbAttachment> Attachments = Package.GetAttachments();
-
- const uint32_t RequestId = ++HttpClientRequestIdCounter;
- auto RequestIdString = fmt::to_string(RequestId);
-
- if (Attachments.empty() == false)
- {
- CbObjectWriter Writer;
- Writer.BeginArray("offer");
-
- for (const CbAttachment& Attachment : Attachments)
- {
- Writer.AddHash(Attachment.GetHash());
- }
-
- Writer.EndArray();
-
- BinaryWriter MemWriter;
- Writer.Save(MemWriter);
-
- Sess->UpdateHeader({HeaderContentType(HttpContentType::kCbPackageOffer), {"UE-Request", RequestIdString}});
- Sess->SetBody(cpr::Body{(const char*)MemWriter.Data(), MemWriter.Size()});
-
- cpr::Response FilterResponse = Sess.Post();
-
- if (FilterResponse.status_code == 200)
- {
- IoBuffer ResponseBuffer(IoBuffer::Wrap, FilterResponse.text.data(), FilterResponse.text.size());
- CbValidateError ValidationError = CbValidateError::None;
- if (CbObject ResponseObject = ValidateAndReadCompactBinaryObject(std::move(ResponseBuffer), ValidationError);
- ValidationError == CbValidateError::None)
- {
- for (CbFieldView& Entry : ResponseObject["need"])
- {
- ZEN_ASSERT(Entry.IsHash());
- AttachmentsToSend.push_back(Entry.AsHash());
- }
- }
- }
- }
-
- // Prepare package for send
-
- CbPackage SendPackage;
- SendPackage.SetObject(Package.GetObject(), Package.GetObjectHash());
-
- for (const IoHash& AttachmentCid : AttachmentsToSend)
- {
- const CbAttachment* Attachment = Package.FindAttachment(AttachmentCid);
-
- if (Attachment)
- {
- SendPackage.AddAttachment(*Attachment);
- }
- else
- {
- // This should be an error -- server asked to have something we can't find
- }
- }
-
- // Transmit package payload
-
- CompositeBuffer Message = FormatPackageMessageBuffer(SendPackage);
- SharedBuffer FlatMessage = Message.Flatten();
-
- Sess->UpdateHeader({HeaderContentType(HttpContentType::kCbPackage), {"UE-Request", RequestIdString}});
- Sess->SetBody(cpr::Body{(const char*)FlatMessage.GetData(), FlatMessage.GetSize()});
-
- cpr::Response FilterResponse = Sess.Post();
-
- if (!IsHttpSuccessCode(FilterResponse.status_code))
- {
- return {.StatusCode = HttpResponseCode(FilterResponse.status_code)};
- }
-
- IoBuffer ResponseBuffer(IoBuffer::Clone, FilterResponse.text.data(), FilterResponse.text.size());
-
- if (auto It = FilterResponse.header.find("Content-Type"); It != FilterResponse.header.end())
- {
- HttpContentType ContentType = ParseContentType(It->second);
-
- ResponseBuffer.SetContentType(ContentType);
- }
-
- return {.StatusCode = HttpResponseCode(FilterResponse.status_code), .ResponsePayload = std::move(ResponseBuffer)};
-}
-
-//////////////////////////////////////////////////////////////////////////
-//
-// Standard HTTP verbs
-//
-
-CprHttpClient::Response
-CprHttpClient::Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Put");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- Sess->SetBody(AsCprBody(Payload));
- Sess->UpdateHeader({HeaderContentType(Payload.GetContentType())});
- return Sess.Put();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Put(std::string_view Url, const KeyValueMap& Parameters)
-{
- ZEN_TRACE_CPU("CprHttpClient::Put");
-
- return CommonResponse(m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess = AllocSession(m_BaseUri,
- Url,
- m_ConnectionSettings,
- {{"Content-Length", "0"}},
- Parameters,
- m_SessionId,
- GetAccessToken());
- return Sess.Put();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Get(std::string_view Url, const KeyValueMap& AdditionalHeader, const KeyValueMap& Parameters)
-{
- ZEN_TRACE_CPU("CprHttpClient::Get");
- return CommonResponse(
- m_SessionId,
- DoWithRetry(
- m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, Parameters, m_SessionId, GetAccessToken());
- return Sess.Get();
- },
- [this](cpr::Response& Result) {
- std::unique_ptr<detail::TempPayloadFile> NoTempFile;
- return ValidatePayload(Result, NoTempFile);
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Head(std::string_view Url, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Head");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- return Sess.Head();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Delete(std::string_view Url, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Delete");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- return Sess.Delete();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Post(std::string_view Url, const KeyValueMap& AdditionalHeader, const KeyValueMap& Parameters)
-{
- ZEN_TRACE_CPU("CprHttpClient::PostNoPayload");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, Parameters, m_SessionId, GetAccessToken());
- return Sess.Post();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Post(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader)
-{
- return Post(Url, Payload, Payload.GetContentType(), AdditionalHeader);
-}
-
-CprHttpClient::Response
-CprHttpClient::Post(std::string_view Url, const IoBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::PostWithPayload");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(
- m_SessionId,
- [&]() {
- Session Sess = AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- Sess->UpdateHeader({HeaderContentType(ContentType)});
-
- IoBufferFileReference FileRef = {nullptr, 0, 0};
- if (Payload.GetFileReference(FileRef))
- {
- uint64_t Offset = 0;
- detail::BufferedReadFileStream Buffer(FileRef.FileHandle, FileRef.FileChunkOffset, FileRef.FileChunkSize, 512u * 1024u);
- auto ReadCallback = [&Payload, &Offset, &Buffer](char* buffer, size_t& size, intptr_t) {
- size = Min<size_t>(size, Payload.GetSize() - Offset);
- Buffer.Read(buffer, size);
- Offset += size;
- return true;
- };
- return Sess.Post(cpr::ReadCallback(gsl::narrow<cpr::cpr_off_t>(Payload.GetSize()), ReadCallback));
- }
- Sess->SetBody(AsCprBody(Payload));
- return Sess.Post();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Post(std::string_view Url,
- CbObject Payload,
- const KeyValueMap& AdditionalHeader,
- const std::filesystem::path& TempFolderPath)
-{
- ZEN_TRACE_CPU("CprHttpClient::PostObjectPayload");
-
- std::string PayloadString;
- std::unique_ptr<detail::TempPayloadFile> PayloadFile;
-
- cpr::Response Response = DoWithRetry(
- m_SessionId,
- [&]() {
- PayloadString.clear();
- PayloadFile.reset();
-
- Session Sess = AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
-
- Sess->SetBody(AsCprBody(Payload));
- Sess->UpdateHeader({HeaderContentType(ZenContentType::kCbObject)});
-
- std::vector<std::pair<std::string, std::string>> ReceivedHeaders;
- auto HeaderCallback = [&](std::string header, intptr_t) {
- const std::pair<std::string_view, std::string_view> Header = detail::GetHeaderKeyAndValue(header);
- if (StrCaseCompare(std::string(Header.first).c_str(), "Content-Length") == 0)
- {
- std::optional<size_t> ContentLength = ParseInt<size_t>(Header.second);
- if (ContentLength.has_value())
- {
- if (!TempFolderPath.empty() && ContentLength.value() > m_ConnectionSettings.MaximumInMemoryDownloadSize)
- {
- PayloadFile = std::make_unique<detail::TempPayloadFile>();
- std::error_code Ec = PayloadFile->Open(TempFolderPath, ContentLength.value());
- if (Ec)
- {
- ZEN_WARN("Failed to create temp file in '{}' for HttpClient::Post. Reason: {}",
- TempFolderPath.string(),
- Ec.message());
- PayloadFile.reset();
- }
- }
- else
- {
- PayloadString.reserve(ContentLength.value());
- }
- }
- }
- if (!Header.first.empty())
- {
- ReceivedHeaders.emplace_back(std::move(Header));
- }
- return 1;
- };
-
- auto DownloadCallback = [&](std::string data, intptr_t) {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return false;
- }
-
- if (PayloadFile)
- {
- ZEN_ASSERT(PayloadString.empty());
- std::error_code Ec = PayloadFile->Write(data);
- if (Ec)
- {
- ZEN_WARN("Failed to write to temp file in '{}' for HttpClient::Post. Reason: {}",
- TempFolderPath.string(),
- Ec.message());
- return false;
- }
- }
- else
- {
- PayloadString.append(data);
- }
- return true;
- };
- cpr::Response Response = Sess.Post({}, cpr::WriteCallback{DownloadCallback}, cpr::HeaderCallback{HeaderCallback});
- for (const std::pair<std::string, std::string>& H : ReceivedHeaders)
- {
- Response.header.insert_or_assign(H.first, H.second);
- }
- if (!PayloadString.empty())
- {
- Response.text = std::move(PayloadString);
- }
- return Response;
- },
- PayloadFile);
- return CommonResponse(m_SessionId, std::move(Response), PayloadFile ? PayloadFile->DetachToIoBuffer() : IoBuffer{});
-}
-
-CprHttpClient::Response
-CprHttpClient::Post(std::string_view Url, CbPackage Pkg, const KeyValueMap& AdditionalHeader)
-{
- return Post(Url, zen::FormatPackageMessageBuffer(Pkg), ZenContentType::kCbPackage, AdditionalHeader);
-}
-
-CprHttpClient::Response
-CprHttpClient::Post(std::string_view Url, const CompositeBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Post");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- Sess->UpdateHeader({HeaderContentType(ContentType)});
-
- detail::CompositeBufferReadStream Reader(Payload, 512u * 1024u);
- auto ReadCallback = [this, &Reader](char* buffer, size_t& size, intptr_t) {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return false;
- }
- size = Reader.Read(buffer, size);
- return true;
- };
- return Sess.Post(cpr::ReadCallback(gsl::narrow<cpr::cpr_off_t>(Payload.GetSize()), ReadCallback));
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Upload(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Upload");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(
- m_SessionId,
- [&]() {
- Session Sess = AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- Sess->UpdateHeader({HeaderContentType(Payload.GetContentType())});
-
- IoBufferFileReference FileRef = {nullptr, 0, 0};
- if (Payload.GetFileReference(FileRef))
- {
- uint64_t Offset = 0;
- detail::BufferedReadFileStream Buffer(FileRef.FileHandle, FileRef.FileChunkOffset, FileRef.FileChunkSize, 512u * 1024u);
- auto ReadCallback = [this, &Payload, &Offset, &Buffer](char* buffer, size_t& size, intptr_t) {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return false;
- }
-
- size = Min<size_t>(size, Payload.GetSize() - Offset);
- Buffer.Read(buffer, size);
- Offset += size;
- return true;
- };
- return Sess.Put(cpr::ReadCallback(gsl::narrow<cpr::cpr_off_t>(Payload.GetSize()), ReadCallback));
- }
- Sess->SetBody(AsCprBody(Payload));
- return Sess.Put();
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Upload(std::string_view Url, const CompositeBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Upload");
-
- return CommonResponse(
- m_SessionId,
- DoWithRetry(m_SessionId,
- [&]() {
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- Sess->UpdateHeader({HeaderContentType(ContentType)});
-
- detail::CompositeBufferReadStream Reader(Payload, 512u * 1024u);
- auto ReadCallback = [this, &Reader](char* buffer, size_t& size, intptr_t) {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return false;
- }
- size = Reader.Read(buffer, size);
- return true;
- };
- return Sess.Put(cpr::ReadCallback(gsl::narrow<cpr::cpr_off_t>(Payload.GetSize()), ReadCallback));
- }),
- {});
-}
-
-CprHttpClient::Response
-CprHttpClient::Download(std::string_view Url, const std::filesystem::path& TempFolderPath, const KeyValueMap& AdditionalHeader)
-{
- ZEN_TRACE_CPU("CprHttpClient::Download");
-
- std::string PayloadString;
- std::unique_ptr<detail::TempPayloadFile> PayloadFile;
-
- HttpContentType ContentType = HttpContentType::kUnknownContentType;
- detail::MultipartBoundaryParser BoundaryParser;
- bool IsMultiRangeResponse = false;
-
- cpr::Response Response = DoWithRetry(
- m_SessionId,
- [&]() {
- // Reset state from any previous attempt
- PayloadString.clear();
- PayloadFile.reset();
- BoundaryParser.Boundaries.clear();
- ContentType = HttpContentType::kUnknownContentType;
- IsMultiRangeResponse = false;
-
- auto DownloadCallback = [&](std::string data, intptr_t) {
- if (m_CheckIfAbortFunction && m_CheckIfAbortFunction())
- {
- return false;
- }
-
- if (IsMultiRangeResponse)
- {
- BoundaryParser.ParseInput(data);
- }
-
- if (PayloadFile)
- {
- ZEN_ASSERT(PayloadString.empty());
- std::error_code Ec = PayloadFile->Write(data);
- if (Ec)
- {
- ZEN_WARN("Failed to write to temp file in '{}' for HttpClient::Download. Reason: {}",
- TempFolderPath.string(),
- Ec.message());
- return false;
- }
- }
- else
- {
- PayloadString.append(data);
- }
- return true;
- };
-
- uint64_t RequestedContentLength = (uint64_t)-1;
- if (auto RangeIt = AdditionalHeader.Entries.find("Range"); RangeIt != AdditionalHeader.Entries.end())
- {
- if (RangeIt->second.starts_with("bytes"))
- {
- std::string_view RangeValue(RangeIt->second);
- size_t RangeStartPos = RangeValue.find('=', 5);
- if (RangeStartPos != std::string::npos)
- {
- RangeStartPos++;
- while (RangeStartPos < RangeValue.length() && RangeValue[RangeStartPos] == ' ')
- {
- RangeStartPos++;
- }
- RequestedContentLength = 0;
-
- while (RangeStartPos < RangeValue.length())
- {
- size_t RangeEnd = RangeValue.find_first_of(", \r\n", RangeStartPos);
- if (RangeEnd == std::string::npos)
- {
- RangeEnd = RangeValue.length();
- }
-
- std::string_view RangeString = RangeValue.substr(RangeStartPos, RangeEnd - RangeStartPos);
- size_t RangeSplitPos = RangeString.find('-');
- if (RangeSplitPos != std::string::npos)
- {
- std::optional<size_t> RequestedRangeStart = ParseInt<size_t>(RangeString.substr(0, RangeSplitPos));
- std::optional<size_t> RequestedRangeEnd = ParseInt<size_t>(RangeString.substr(RangeSplitPos + 1));
- if (RequestedRangeStart.has_value() && RequestedRangeEnd.has_value())
- {
- RequestedContentLength += RequestedRangeEnd.value() - RequestedRangeStart.value() + 1;
- }
- }
- RangeStartPos = RangeEnd;
- while (RangeStartPos != RangeValue.length() &&
- (RangeValue[RangeStartPos] == ',' || RangeValue[RangeStartPos] == ' '))
- {
- RangeStartPos++;
- }
- }
- }
- }
- }
-
- cpr::Response Response;
- {
- std::vector<std::pair<std::string, std::string>> ReceivedHeaders;
- auto HeaderCallback = [&](std::string header, intptr_t) {
- if (RequestedContentLength != (uint64_t)-1 && RequestedContentLength > m_ConnectionSettings.MaximumInMemoryDownloadSize)
- {
- ZEN_DEBUG("Multirange request");
- }
- const std::pair<std::string_view, std::string_view> Header = detail::GetHeaderKeyAndValue(header);
- const std::string Key(Header.first);
- if (StrCaseCompare(Key.c_str(), "Content-Length") == 0)
- {
- std::optional<size_t> ContentLength = ParseInt<size_t>(Header.second);
- if (ContentLength.has_value())
- {
- if (!TempFolderPath.empty() && ContentLength.value() > m_ConnectionSettings.MaximumInMemoryDownloadSize)
- {
- PayloadFile = std::make_unique<detail::TempPayloadFile>();
- std::error_code Ec = PayloadFile->Open(TempFolderPath, ContentLength.value());
- if (Ec)
- {
- ZEN_WARN("Failed to create temp file in '{}' for HttpClient::Download. Reason: {}",
- TempFolderPath.string(),
- Ec.message());
- PayloadFile.reset();
- }
- }
- else
- {
- PayloadString.reserve(ContentLength.value());
- }
- }
- }
- else if (StrCaseCompare(Key.c_str(), "Content-Type") == 0)
- {
- IsMultiRangeResponse = BoundaryParser.Init(Header.second);
- if (!IsMultiRangeResponse)
- {
- ContentType = ParseContentType(Header.second);
- }
- }
- else if (StrCaseCompare(Key.c_str(), "Content-Range") == 0)
- {
- if (!IsMultiRangeResponse)
- {
- std::pair<uint64_t, uint64_t> Range = detail::ParseContentRange(Header.second);
- if (Range.second != 0)
- {
- BoundaryParser.Boundaries.push_back(HttpClient::Response::MultipartBoundary{.OffsetInPayload = 0,
- .RangeOffset = Range.first,
- .RangeLength = Range.second,
- .ContentType = ContentType});
- }
- }
- }
- if (!Header.first.empty())
- {
- ReceivedHeaders.emplace_back(std::move(Header));
- }
- return 1;
- };
-
- Session Sess = AllocSession(m_BaseUri, Url, m_ConnectionSettings, AdditionalHeader, {}, m_SessionId, GetAccessToken());
- Response = Sess.Download(cpr::WriteCallback{DownloadCallback}, cpr::HeaderCallback{HeaderCallback});
- for (const std::pair<std::string, std::string>& H : ReceivedHeaders)
- {
- Response.header.insert_or_assign(H.first, H.second);
- }
- }
- if (m_ConnectionSettings.AllowResume)
- {
- auto SupportsRanges = [](const cpr::Response& Response) -> bool {
- if (Response.header.find("Content-Range") != Response.header.end())
- {
- return true;
- }
- if (auto It = Response.header.find("Accept-Ranges"); It != Response.header.end())
- {
- return It->second == "bytes"sv;
- }
- return false;
- };
-
- auto ShouldResume = [&SupportsRanges, &IsMultiRangeResponse](const cpr::Response& Response) -> bool {
- if (IsMultiRangeResponse)
- {
- return false;
- }
- if (ShouldRetry(Response))
- {
- return SupportsRanges(Response);
- }
- return false;
- };
-
- if (ShouldResume(Response))
- {
- auto It = Response.header.find("Content-Length");
- if (It != Response.header.end())
- {
- uint64_t ContentLength = RequestedContentLength;
- if (ContentLength == uint64_t(-1))
- {
- if (auto ParsedContentLength = ParseInt<int64_t>(It->second); ParsedContentLength.has_value())
- {
- ContentLength = ParsedContentLength.value();
- }
- }
-
- std::vector<std::pair<std::string, std::string>> ReceivedHeaders;
-
- auto HeaderCallback = [&](std::string header, intptr_t) {
- const std::pair<std::string_view, std::string_view> Header = detail::GetHeaderKeyAndValue(header);
- if (!Header.first.empty())
- {
- ReceivedHeaders.emplace_back(std::move(Header));
- }
-
- if (StrCaseCompare(std::string(Header.first).c_str(), "Content-Range") == 0)
- {
- if (Header.second.starts_with("bytes "sv))
- {
- size_t RangeStartEnd = Header.second.find('-', 6);
- if (RangeStartEnd != std::string::npos)
- {
- const auto Start = ParseInt<uint64_t>(Header.second.substr(6, RangeStartEnd - 6));
- if (Start)
- {
- uint64_t DownloadedSize = PayloadFile ? PayloadFile->GetSize() : PayloadString.length();
- if (Start.value() == DownloadedSize)
- {
- return 1;
- }
- else if (Start.value() > DownloadedSize)
- {
- return 0;
- }
- if (PayloadFile)
- {
- PayloadFile->ResetWritePos(Start.value());
- }
- else
- {
- PayloadString = PayloadString.substr(0, Start.value());
- }
- return 1;
- }
- }
- }
- return 0;
- }
- return 1;
- };
-
- KeyValueMap HeadersWithRange(AdditionalHeader);
- do
- {
- uint64_t DownloadedSize = PayloadFile ? PayloadFile->GetSize() : PayloadString.length();
-
- std::string Range = fmt::format("bytes={}-{}", DownloadedSize, DownloadedSize + ContentLength - 1);
- if (auto RangeIt = HeadersWithRange.Entries.find("Range"); RangeIt != HeadersWithRange.Entries.end())
- {
- if (RangeIt->second == Range)
- {
- // If we didn't make any progress, abort
- break;
- }
- }
- HeadersWithRange.Entries.insert_or_assign("Range", Range);
-
- Session Sess =
- AllocSession(m_BaseUri, Url, m_ConnectionSettings, HeadersWithRange, {}, m_SessionId, GetAccessToken());
- Response = Sess.Download(cpr::WriteCallback{DownloadCallback}, cpr::HeaderCallback{HeaderCallback});
- for (const std::pair<std::string, std::string>& H : ReceivedHeaders)
- {
- Response.header.insert_or_assign(H.first, H.second);
- }
- ReceivedHeaders.clear();
- } while (ShouldResume(Response));
- }
- }
- }
-
- if (!PayloadString.empty())
- {
- Response.text = std::move(PayloadString);
- }
- return Response;
- },
- PayloadFile);
-
- return CommonResponse(m_SessionId,
- std::move(Response),
- PayloadFile ? PayloadFile->DetachToIoBuffer() : IoBuffer{},
- std::move(BoundaryParser.Boundaries));
-}
-
-} // namespace zen
diff --git a/src/zenhttp/clients/httpclientcpr.h b/src/zenhttp/clients/httpclientcpr.h
deleted file mode 100644
index 509ca5ae2..000000000
--- a/src/zenhttp/clients/httpclientcpr.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#pragma once
-
-#include "httpclientcommon.h"
-
-#include <zencore/logging.h>
-#include <zenhttp/cprutils.h>
-#include <zenhttp/httpclient.h>
-
-ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/body.h>
-#include <cpr/session.h>
-ZEN_THIRD_PARTY_INCLUDES_END
-
-namespace zen {
-
-class CprHttpClient : public HttpClientBase
-{
-public:
- CprHttpClient(std::string_view BaseUri, const HttpClientSettings& Connectionsettings, std::function<bool()>&& CheckIfAbortFunction);
- ~CprHttpClient();
-
- // HttpClientBase
-
- [[nodiscard]] virtual Response Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Put(std::string_view Url, const KeyValueMap& Parameters = {}) override;
- [[nodiscard]] virtual Response Get(std::string_view Url,
- const KeyValueMap& AdditionalHeader = {},
- const KeyValueMap& Parameters = {}) override;
- [[nodiscard]] virtual Response Head(std::string_view Url, const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Delete(std::string_view Url, const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Post(std::string_view Url,
- const KeyValueMap& AdditionalHeader = {},
- const KeyValueMap& Parameters = {}) override;
- [[nodiscard]] virtual Response Post(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Post(std::string_view Url,
- const IoBuffer& Payload,
- ZenContentType ContentType,
- const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Post(std::string_view Url,
- CbObject Payload,
- const KeyValueMap& AdditionalHeader = {},
- const std::filesystem::path& TempFolderPath = {}) override;
- [[nodiscard]] virtual Response Post(std::string_view Url, CbPackage Payload, const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Post(std::string_view Url,
- const CompositeBuffer& Payload,
- ZenContentType ContentType,
- const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Upload(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override;
- [[nodiscard]] virtual Response Upload(std::string_view Url,
- const CompositeBuffer& Payload,
- ZenContentType ContentType,
- const KeyValueMap& AdditionalHeader = {}) override;
-
- [[nodiscard]] virtual Response Download(std::string_view Url,
- const std::filesystem::path& TempFolderPath,
- const KeyValueMap& AdditionalHeader = {}) override;
-
- [[nodiscard]] virtual Response TransactPackage(std::string_view Url,
- CbPackage Package,
- const KeyValueMap& AdditionalHeader = {}) override;
-
-private:
- struct Session
- {
- Session(CprHttpClient* InOuter, cpr::Session* InSession) : Outer(InOuter), CprSession(InSession) {}
- ~Session() { Outer->ReleaseSession(CprSession); }
-
- inline cpr::Session* operator->() const { return CprSession; }
- inline cpr::Response Get()
- {
- ZEN_TRACE_CPU("HttpClient::Impl::Get");
- cpr::Response Result = CprSession->Get();
- ZEN_TRACE("GET {}", Result);
- return Result;
- }
- inline cpr::Response Download(cpr::WriteCallback&& Write, std::optional<cpr::HeaderCallback>&& Header = {})
- {
- ZEN_TRACE_CPU("HttpClient::Impl::Download");
- if (Header)
- {
- CprSession->SetHeaderCallback(std::move(Header.value()));
- }
- cpr::Response Result = CprSession->Download(Write);
- ZEN_TRACE("GET {}", Result);
- CprSession->SetHeaderCallback({});
- CprSession->SetWriteCallback({});
- return Result;
- }
- inline cpr::Response Head()
- {
- ZEN_TRACE_CPU("HttpClient::Impl::Head");
- cpr::Response Result = CprSession->Head();
- ZEN_TRACE("HEAD {}", Result);
- return Result;
- }
- inline cpr::Response Put(std::optional<cpr::ReadCallback>&& Read = {})
- {
- ZEN_TRACE_CPU("HttpClient::Impl::Put");
- if (Read)
- {
- CprSession->SetReadCallback(std::move(Read.value()));
- }
- cpr::Response Result = CprSession->Put();
- ZEN_TRACE("PUT {}", Result);
- CprSession->SetReadCallback({});
- return Result;
- }
- inline cpr::Response Post(std::optional<cpr::ReadCallback>&& Read = {},
- std::optional<cpr::WriteCallback>&& Write = {},
- std::optional<cpr::HeaderCallback>&& Header = {})
- {
- ZEN_TRACE_CPU("HttpClient::Impl::Post");
- if (Read)
- {
- CprSession->SetReadCallback(std::move(Read.value()));
- }
- if (Write)
- {
- CprSession->SetWriteCallback(std::move(Write.value()));
- }
- if (Header)
- {
- CprSession->SetHeaderCallback(std::move(Header.value()));
- }
- cpr::Response Result = CprSession->Post();
- ZEN_TRACE("POST {}", Result);
- CprSession->SetHeaderCallback({});
- CprSession->SetWriteCallback({});
- CprSession->SetReadCallback({});
- return Result;
- }
- inline cpr::Response Delete()
- {
- ZEN_TRACE_CPU("HttpClient::Impl::Delete");
- cpr::Response Result = CprSession->Delete();
- ZEN_TRACE("DELETE {}", Result);
- return Result;
- }
-
- LoggerRef Log() { return Outer->Log(); }
-
- private:
- CprHttpClient* Outer;
- cpr::Session* CprSession;
-
- Session(Session&&) = delete;
- Session& operator=(Session&&) = delete;
- };
-
- Session AllocSession(const std::string_view BaseUrl,
- const std::string_view Url,
- const HttpClientSettings& ConnectionSettings,
- const KeyValueMap& AdditionalHeader,
- const KeyValueMap& Parameters,
- const std::string_view SessionId,
- std::optional<std::string> AccessToken);
-
- RwLock m_SessionLock;
- std::vector<cpr::Session*> m_Sessions;
-
- void ReleaseSession(cpr::Session*);
-
- cpr::Response DoWithRetry(std::string_view SessionId,
- std::function<cpr::Response()>&& Func,
- std::unique_ptr<detail::TempPayloadFile>& PayloadFile);
- cpr::Response DoWithRetry(
- std::string_view SessionId,
- std::function<cpr::Response()>&& Func,
- std::function<bool(cpr::Response& Result)>&& Validate = [](cpr::Response&) { return true; });
-
- bool ShouldLogErrorCode(HttpResponseCode ResponseCode) const;
- bool ValidatePayload(cpr::Response& Response, std::unique_ptr<detail::TempPayloadFile>& PayloadFile);
-
- HttpClient::Response CommonResponse(std::string_view SessionId,
- cpr::Response&& HttpResponse,
- IoBuffer&& Payload,
- std::vector<HttpClient::Response::MultipartBoundary>&& BoundaryPositions = {});
-
- HttpClient::Response ResponseWithPayload(std::string_view SessionId,
- cpr::Response&& HttpResponse,
- const HttpResponseCode WorkResponseCode,
- IoBuffer&& Payload,
- std::vector<HttpClient::Response::MultipartBoundary>&& BoundaryPositions);
-};
-
-} // namespace zen
diff --git a/src/zenhttp/clients/httpclientcurl.cpp b/src/zenhttp/clients/httpclientcurl.cpp
index e76157254..d150b44c6 100644
--- a/src/zenhttp/clients/httpclientcurl.cpp
+++ b/src/zenhttp/clients/httpclientcurl.cpp
@@ -980,7 +980,7 @@ CurlHttpClient::TransactPackage(std::string_view Url, CbPackage Package, const K
//
CurlHttpClient::Response
-CurlHttpClient::Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader)
+CurlHttpClient::Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader, const KeyValueMap& Parameters)
{
ZEN_TRACE_CPU("CurlHttpClient::Put");
@@ -989,7 +989,7 @@ CurlHttpClient::Put(std::string_view Url, const IoBuffer& Payload, const KeyValu
DoWithRetry(
m_SessionId,
[&]() -> CurlResult {
- Session Sess = AllocSession(Url, {});
+ Session Sess = AllocSession(Url, Parameters);
CURL* H = Sess.Get();
Sess.SetHeaders(
diff --git a/src/zenhttp/clients/httpclientcurl.h b/src/zenhttp/clients/httpclientcurl.h
index b7fa52e6c..bdeb46633 100644
--- a/src/zenhttp/clients/httpclientcurl.h
+++ b/src/zenhttp/clients/httpclientcurl.h
@@ -21,7 +21,10 @@ public:
// HttpClientBase
- [[nodiscard]] virtual Response Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override;
+ [[nodiscard]] virtual Response Put(std::string_view Url,
+ const IoBuffer& Payload,
+ const KeyValueMap& AdditionalHeader = {},
+ const KeyValueMap& Parameters = {}) override;
[[nodiscard]] virtual Response Put(std::string_view Url, const KeyValueMap& Parameters = {}) override;
[[nodiscard]] virtual Response Get(std::string_view Url,
const KeyValueMap& AdditionalHeader = {},
diff --git a/src/zenhttp/httpclient.cpp b/src/zenhttp/httpclient.cpp
index 3e81d4a8a..ace7a3c7f 100644
--- a/src/zenhttp/httpclient.cpp
+++ b/src/zenhttp/httpclient.cpp
@@ -36,12 +36,6 @@
namespace zen {
-#if ZEN_WITH_CPR
-extern HttpClientBase* CreateCprHttpClient(std::string_view BaseUri,
- const HttpClientSettings& ConnectionSettings,
- std::function<bool()>&& CheckIfAbortFunction);
-#endif
-
extern HttpClientBase* CreateCurlHttpClient(std::string_view BaseUri,
const HttpClientSettings& ConnectionSettings,
std::function<bool()>&& CheckIfAbortFunction);
@@ -57,14 +51,7 @@ SetDefaultHttpClientBackend(HttpClientBackend Backend)
void
SetDefaultHttpClientBackend(std::string_view Backend)
{
-#if ZEN_WITH_CPR
- if (Backend == "cpr")
- {
- g_DefaultHttpClientBackend = HttpClientBackend::kCpr;
- }
- else
-#endif
- if (Backend == "curl")
+ if (Backend == "curl")
{
g_DefaultHttpClientBackend = HttpClientBackend::kCurl;
}
@@ -128,6 +115,11 @@ HttpClientBase::GetAccessToken()
return m_CachedAccessToken.GetValue();
}
HttpClientAccessToken NewAccessToken = m_ConnectionSettings.AccessTokenProvider.value()();
+ if (!NewAccessToken.IsValid())
+ {
+ ZEN_WARN("HttpClient failed to refresh access token, retrying once");
+ NewAccessToken = m_ConnectionSettings.AccessTokenProvider.value()();
+ }
if (NewAccessToken.IsValid())
{
m_CachedAccessToken = NewAccessToken;
@@ -373,22 +365,7 @@ HttpClient::HttpClient(std::string_view BaseUri, const HttpClientSettings& Conne
, m_ConnectionSettings(ConnectionSettings)
{
m_SessionId = GetSessionIdString();
-
- HttpClientBackend EffectiveBackend =
- ConnectionSettings.Backend != HttpClientBackend::kDefault ? ConnectionSettings.Backend : g_DefaultHttpClientBackend;
-
- switch (EffectiveBackend)
- {
-#if ZEN_WITH_CPR
- case HttpClientBackend::kCpr:
- m_Inner = CreateCprHttpClient(BaseUri, ConnectionSettings, std::move(CheckIfAbortFunction));
- break;
-#endif
- case HttpClientBackend::kCurl:
- default:
- m_Inner = CreateCurlHttpClient(BaseUri, ConnectionSettings, std::move(CheckIfAbortFunction));
- break;
- }
+ m_Inner = CreateCurlHttpClient(BaseUri, ConnectionSettings, std::move(CheckIfAbortFunction));
}
HttpClient::~HttpClient()
@@ -397,6 +374,13 @@ HttpClient::~HttpClient()
}
void
+HttpClient::SetBaseUri(std::string_view NewBaseUri)
+{
+ m_BaseUri = NewBaseUri;
+ m_Inner->SetBaseUri(NewBaseUri);
+}
+
+void
HttpClient::SetSessionId(const Oid& SessionId)
{
if (SessionId == Oid::Zero)
@@ -410,9 +394,12 @@ HttpClient::SetSessionId(const Oid& SessionId)
}
HttpClient::Response
-HttpClient::Put(std::string_view Url, const IoBuffer& Payload, const HttpClient::KeyValueMap& AdditionalHeader)
+HttpClient::Put(std::string_view Url,
+ const IoBuffer& Payload,
+ const HttpClient::KeyValueMap& AdditionalHeader,
+ const HttpClient::KeyValueMap& Parameters)
{
- return m_Inner->Put(Url, Payload, AdditionalHeader);
+ return m_Inner->Put(Url, Payload, AdditionalHeader, Parameters);
}
HttpClient::Response
@@ -972,6 +959,71 @@ TEST_CASE("httpclient.password")
AsioServer->RequestExit();
}
}
+TEST_CASE("httpclient.setbaseuri")
+{
+ struct TestHttpService : public HttpService
+ {
+ explicit TestHttpService(std::string_view Identity) : m_Identity(Identity) {}
+
+ virtual const char* BaseUri() const override { return "/test/"; }
+ virtual void HandleRequest(HttpServerRequest& Req) override
+ {
+ Req.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, m_Identity);
+ }
+
+ std::string m_Identity;
+ };
+
+ ScopedTemporaryDirectory TmpDir1;
+ ScopedTemporaryDirectory TmpDir2;
+ TestHttpService Service1("server-one");
+ TestHttpService Service2("server-two");
+
+ Ref<HttpServer> Server1 = CreateHttpAsioServer(AsioConfig{});
+ Ref<HttpServer> Server2 = CreateHttpAsioServer(AsioConfig{});
+
+ int Port1 = Server1->Initialize(0, TmpDir1.Path());
+ int Port2 = Server2->Initialize(0, TmpDir2.Path());
+ REQUIRE(Port1 != -1);
+ REQUIRE(Port2 != -1);
+
+ Server1->RegisterService(Service1);
+ Server2->RegisterService(Service2);
+
+ std::thread Thread1([&]() { Server1->Run(false); });
+ std::thread Thread2([&]() { Server2->Run(false); });
+
+ auto _ = MakeGuard([&]() {
+ if (Thread1.joinable())
+ {
+ Thread1.join();
+ }
+ if (Thread2.joinable())
+ {
+ Thread2.join();
+ }
+ Server1->Close();
+ Server2->Close();
+ });
+
+ HttpClient Client(fmt::format("127.0.0.1:{}", Port1), HttpClientSettings{}, {});
+ CHECK_EQ(Client.GetBaseUri(), fmt::format("127.0.0.1:{}", Port1));
+
+ HttpClient::Response Resp1 = Client.Get("/test/hello");
+ CHECK(Resp1.IsSuccess());
+ CHECK_EQ(Resp1.AsText(), "server-one");
+
+ Client.SetBaseUri(fmt::format("127.0.0.1:{}", Port2));
+ CHECK_EQ(Client.GetBaseUri(), fmt::format("127.0.0.1:{}", Port2));
+
+ HttpClient::Response Resp2 = Client.Get("/test/hello");
+ CHECK(Resp2.IsSuccess());
+ CHECK_EQ(Resp2.AsText(), "server-two");
+
+ Server1->RequestExit();
+ Server2->RequestExit();
+}
+
TEST_SUITE_END();
void
diff --git a/src/zenhttp/httpclient_test.cpp b/src/zenhttp/httpclient_test.cpp
index 7a657c464..af653cbb2 100644
--- a/src/zenhttp/httpclient_test.cpp
+++ b/src/zenhttp/httpclient_test.cpp
@@ -492,6 +492,17 @@ TEST_CASE("httpclient.put")
CHECK_EQ(Resp.StatusCode, HttpResponseCode::Created);
CHECK_EQ(Resp.AsText(), "resource created");
}
+
+ SUBCASE("PUT with payload and query parameters")
+ {
+ const char* Payload = "put payload data";
+ IoBuffer Buf(IoBuffer::Clone, Payload, strlen(Payload));
+ Buf.SetContentType(ZenContentType::kText);
+
+ HttpClient::Response Resp = Client.Put("/api/test/echo/uri", Buf, {}, {{"key", "value"}});
+ CHECK(Resp.IsSuccess());
+ CHECK_EQ(Resp.AsText(), "echo/uri\nkey=value");
+ }
}
TEST_CASE("httpclient.upload")
diff --git a/src/zenhttp/httpclientauth.cpp b/src/zenhttp/httpclientauth.cpp
index 6a3f18b7a..c42841922 100644
--- a/src/zenhttp/httpclientauth.cpp
+++ b/src/zenhttp/httpclientauth.cpp
@@ -105,7 +105,7 @@ namespace zen { namespace httpclientauth {
}
if (Hidden)
{
- ProcOptions.Flags |= CreateProcOptions::Flag_NoConsole;
+ ProcOptions.Flags |= CreateProcOptions::Flag_NoWindow;
}
const std::filesystem::path AuthTokenPath(std::filesystem::temp_directory_path() / fmt::format(".zen-auth-{}", Oid::NewOid()));
@@ -142,21 +142,40 @@ namespace zen { namespace httpclientauth {
if (JsonError.empty() == false)
{
- ZEN_WARN("Unable to parse Oidcs json response from {}. Reason: '{}'", AuthTokenPath, JsonError);
+ ZEN_WARN("Unable to parse OIDC json output file {}. Reason: '{}'", AuthTokenPath, JsonError);
return HttpClientAccessToken{};
}
std::string Token = Json["Token"].string_value();
std::string ExpiresAtUTCString = Json["ExpiresAtUtc"].string_value();
- ZEN_ASSERT(!ExpiresAtUTCString.empty());
+ if (Token.empty())
+ {
+ ZEN_WARN("The 'Token' field in json output file {} is empty", AuthTokenPath);
+ return HttpClientAccessToken{};
+ }
+ if (ExpiresAtUTCString.empty())
+ {
+ ZEN_WARN("The 'ExpiresAtUtc' field in json output file {} is empty", AuthTokenPath);
+ return HttpClientAccessToken{};
+ }
+ if (ExpiresAtUTCString.back() != 'Z')
+ {
+ ZEN_WARN("The 'ExpiresAtUtc' field '{}' in json output file {} does not end with 'Z'; expected a UTC timestamp",
+ ExpiresAtUTCString,
+ AuthTokenPath);
+ return HttpClientAccessToken{};
+ }
- int Year = 0;
- int Month = 0;
- int Day = 0;
- int Hour = 0;
- int Minute = 0;
- int Second = 0;
- int Millisecond = 0;
- sscanf(ExpiresAtUTCString.c_str(), "%d-%d-%dT%d:%d:%d.%dZ", &Year, &Month, &Day, &Hour, &Minute, &Second, &Millisecond);
+ int Year = 0;
+ int Month = 0;
+ int Day = 0;
+ int Hour = 0;
+ int Minute = 0;
+ int Second = 0;
+ if (sscanf(ExpiresAtUTCString.c_str(), "%d-%d-%dT%d:%d:%d", &Year, &Month, &Day, &Hour, &Minute, &Second) != 6)
+ {
+ ZEN_WARN("Unable to parse ExpiresAtUtc '{}' from json output file {}", ExpiresAtUTCString, AuthTokenPath);
+ return HttpClientAccessToken{};
+ }
std::tm Time = {
Second,
@@ -169,7 +188,6 @@ namespace zen { namespace httpclientauth {
time_t UTCTime = timegm(&Time);
HttpClientAccessToken::TimePoint ExpireTime = std::chrono::system_clock::from_time_t(UTCTime);
- ExpireTime += std::chrono::milliseconds(Millisecond);
return HttpClientAccessToken(fmt::format("Bearer {}"sv, Token), ExpireTime);
}
diff --git a/src/zenhttp/httpserver.cpp b/src/zenhttp/httpserver.cpp
index e5cfbcbae..38021be16 100644
--- a/src/zenhttp/httpserver.cpp
+++ b/src/zenhttp/httpserver.cpp
@@ -329,6 +329,10 @@ ReasonStringForHttpResultCode(int HttpCode)
return "Continue"sv;
case 101:
return "Switching Protocols"sv;
+ case 102:
+ return "Processing"sv;
+ case 103:
+ return "Early Hints"sv;
// 2xx Success
@@ -338,12 +342,20 @@ ReasonStringForHttpResultCode(int HttpCode)
return "Created"sv;
case 202:
return "Accepted"sv;
+ case 203:
+ return "Non-Authoritative Information"sv;
case 204:
return "No Content"sv;
case 205:
return "Reset Content"sv;
case 206:
return "Partial Content"sv;
+ case 207:
+ return "Multi-Status"sv;
+ case 208:
+ return "Already Reported"sv;
+ case 226:
+ return "IM Used"sv;
// 3xx Redirection
@@ -424,6 +436,8 @@ ReasonStringForHttpResultCode(int HttpCode)
return "Too Many Requests"sv;
case 431:
return "Request Header Fields Too Large"sv;
+ case 451:
+ return "Unavailable For Legal Reasons"sv;
// 5xx Server errors
@@ -465,6 +479,18 @@ HttpService::HandlePackageRequest(HttpServerRequest& HttpServiceRequest)
return Ref<IHttpPackageHandler>();
}
+bool
+HttpService::AcceptsLocalFileReferences() const
+{
+ return false;
+}
+
+const ILocalRefPolicy*
+HttpService::GetLocalRefPolicy() const
+{
+ return nullptr;
+}
+
//////////////////////////////////////////////////////////////////////////
HttpServerRequest::HttpServerRequest(HttpService& Service) : m_Service(Service)
@@ -691,7 +717,10 @@ HttpServerRequest::ReadPayloadPackage()
{
if (IoBuffer Payload = ReadPayload())
{
- return ParsePackageMessage(std::move(Payload));
+ ParseFlags Flags =
+ (IsLocalMachineRequest() && m_Service.AcceptsLocalFileReferences()) ? ParseFlags::kAllowLocalReferences : ParseFlags::kDefault;
+ const ILocalRefPolicy* Policy = EnumHasAllFlags(Flags, ParseFlags::kAllowLocalReferences) ? m_Service.GetLocalRefPolicy() : nullptr;
+ return ParsePackageMessage(std::move(Payload), {}, Flags, Policy);
}
return {};
@@ -798,7 +827,18 @@ HttpRequestRouter::HandleRequest(zen::HttpServerRequest& Request)
const HttpVerb Verb = Request.RequestVerb();
- std::string_view Uri = Request.RelativeUri();
+ std::string_view Uri = Request.RelativeUri();
+
+ // Strip the separator slash left over after the service prefix is removed.
+ // When a service has BaseUri "/foo", the prefix length is set to len("/foo") = 4.
+ // Stripping 4 chars from "/foo/bar" yields "/bar" — the path separator becomes
+ // the first character of the relative URI. Remove it so patterns like "bar" or
+ // "{id}" match without needing to account for the leading slash.
+ if (!Uri.empty() && Uri.front() == '/')
+ {
+ Uri.remove_prefix(1);
+ }
+
HttpRouterRequest RouterRequest(Request);
for (const MatcherEndpoint& Handler : m_MatcherEndpoints)
@@ -974,6 +1014,12 @@ HttpServer::SetHttpRequestFilter(IHttpRequestFilter* RequestFilter)
OnSetHttpRequestFilter(RequestFilter);
}
+void
+HttpServer::HandleStatsRequest(HttpServerRequest& Request)
+{
+ Request.WriteResponse(HttpResponseCode::OK, CollectStats());
+}
+
CbObject
HttpServer::CollectStats()
{
@@ -988,6 +1034,9 @@ HttpServer::CollectStats()
}
Cbo.EndObject();
+ Cbo << "distinct_clients" << m_ClientAddresses.Count();
+ Cbo << "distinct_sessions" << m_ClientSessions.Count();
+
Cbo.BeginObject("websockets");
{
Cbo << "active_connections" << GetActiveWebSocketConnectionCount();
@@ -1001,12 +1050,6 @@ HttpServer::CollectStats()
return Cbo.Save();
}
-void
-HttpServer::HandleStatsRequest(HttpServerRequest& Request)
-{
- Request.WriteResponse(HttpResponseCode::OK, CollectStats());
-}
-
//////////////////////////////////////////////////////////////////////////
HttpRpcHandler::HttpRpcHandler()
@@ -1245,7 +1288,12 @@ HandlePackageOffers(HttpService& Service, HttpServerRequest& Request, Ref<IHttpP
return PackageHandlerRef->CreateTarget(Cid, Size);
};
- CbPackage Package = ParsePackageMessage(Request.ReadPayload(), CreateBuffer);
+ ParseFlags PkgFlags = (Request.IsLocalMachineRequest() && Service.AcceptsLocalFileReferences())
+ ? ParseFlags::kAllowLocalReferences
+ : ParseFlags::kDefault;
+ const ILocalRefPolicy* PkgPolicy =
+ EnumHasAllFlags(PkgFlags, ParseFlags::kAllowLocalReferences) ? Service.GetLocalRefPolicy() : nullptr;
+ CbPackage Package = ParsePackageMessage(Request.ReadPayload(), CreateBuffer, PkgFlags, PkgPolicy);
PackageHandlerRef->OnRequestComplete();
}
@@ -1443,6 +1491,78 @@ TEST_CASE("http.common")
}
}
+ SUBCASE("router-leading-slash")
+ {
+ // Verify that HandleRequest strips the leading slash that server implementations
+ // leave in RelativeUri() when the service base URI has no trailing slash.
+ // e.g. BaseUri "/stats" + prefix-strip of "/stats/foo" yields "/foo", not "foo".
+
+ bool HandledLiteral = false;
+ bool HandledPattern = false;
+ bool HandledTwoSeg = false;
+ std::vector<std::string> Captures;
+ auto Reset = [&] {
+ HandledLiteral = HandledPattern = HandledTwoSeg = false;
+ Captures.clear();
+ };
+
+ TestHttpService Service;
+ HttpRequestRouter r;
+
+ r.AddMatcher("seg", [](std::string_view In) -> bool { return !In.empty() && In.find('/') == std::string_view::npos; });
+
+ r.RegisterRoute(
+ "activity_counters",
+ [&](auto& /*Req*/) { HandledLiteral = true; },
+ HttpVerb::kGet);
+
+ r.RegisterRoute(
+ "{seg}",
+ [&](auto& Req) {
+ HandledPattern = true;
+ Captures = {std::string(Req.GetCapture(1))};
+ },
+ HttpVerb::kGet);
+
+ r.RegisterRoute(
+ "prefix/{seg}",
+ [&](auto& Req) {
+ HandledTwoSeg = true;
+ Captures = {std::string(Req.GetCapture(1))};
+ },
+ HttpVerb::kGet);
+
+ // Single-segment literal with leading slash — simulates real server RelativeUri
+ {
+ Reset();
+ TestHttpServerRequest req{Service, "/activity_counters"sv};
+ r.HandleRequest(req);
+ CHECK(HandledLiteral);
+ CHECK(!HandledPattern);
+ }
+
+ // Single-segment pattern with leading slash
+ {
+ Reset();
+ TestHttpServerRequest req{Service, "/hello"sv};
+ r.HandleRequest(req);
+ CHECK(!HandledLiteral);
+ CHECK(HandledPattern);
+ REQUIRE_EQ(Captures.size(), 1);
+ CHECK_EQ(Captures[0], "hello"sv);
+ }
+
+ // Two-segment route with leading slash — first literal segment
+ {
+ Reset();
+ TestHttpServerRequest req{Service, "/prefix/world"sv};
+ r.HandleRequest(req);
+ CHECK(HandledTwoSeg);
+ REQUIRE_EQ(Captures.size(), 1);
+ CHECK_EQ(Captures[0], "world"sv);
+ }
+ }
+
SUBCASE("content-type")
{
for (uint8_t i = 0; i < uint8_t(HttpContentType::kCOUNT); ++i)
diff --git a/src/zenhttp/include/zenhttp/auth/authservice.h b/src/zenhttp/include/zenhttp/auth/authservice.h
index 64b86e21f..ee67c0f5b 100644
--- a/src/zenhttp/include/zenhttp/auth/authservice.h
+++ b/src/zenhttp/include/zenhttp/auth/authservice.h
@@ -8,14 +8,14 @@ namespace zen {
class AuthMgr;
-class HttpAuthService final : public zen::HttpService
+class HttpAuthService final : public HttpService
{
public:
HttpAuthService(AuthMgr& AuthMgr);
virtual ~HttpAuthService();
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
private:
AuthMgr& m_AuthMgr;
diff --git a/src/zenhttp/include/zenhttp/cprutils.h b/src/zenhttp/include/zenhttp/cprutils.h
deleted file mode 100644
index 3cfe652c5..000000000
--- a/src/zenhttp/include/zenhttp/cprutils.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#pragma once
-
-#if ZEN_WITH_CPR
-
-# include <zencore/compactbinary.h>
-# include <zencore/compactbinaryvalidation.h>
-# include <zencore/iobuffer.h>
-# include <zencore/string.h>
-# include <zenhttp/formatters.h>
-# include <zenhttp/httpclient.h>
-# include <zenhttp/httpcommon.h>
-
-ZEN_THIRD_PARTY_INCLUDES_START
-# include <cpr/response.h>
-# include <fmt/format.h>
-ZEN_THIRD_PARTY_INCLUDES_END
-
-template<>
-struct fmt::formatter<cpr::Response>
-{
- constexpr auto parse(format_parse_context& Ctx) -> decltype(Ctx.begin()) { return Ctx.end(); }
-
- template<typename FormatContext>
- auto format(const cpr::Response& Response, FormatContext& Ctx) const -> decltype(Ctx.out())
- {
- using namespace std::literals;
-
- if (Response.error)
- {
- return fmt::format_to(Ctx.out(),
- "Failed: Url: {}, Reason: ({}) '{}'",
- Response.url.str(),
- int(Response.error.code),
- Response.error.message);
- }
- else
- {
- const zen::NiceTimeSpanMs NiceResponseTime(uint64_t(Response.elapsed * 1000));
-
- if (zen::IsHttpSuccessCode(Response.status_code))
- {
- return fmt::format_to(Ctx.out(),
- "OK: Url: {}, Status: ({}) '{}', Bytes: {}/{} (Up/Down), Elapsed: {}",
- Response.url.str(),
- Response.status_code,
- zen::ToString(zen::HttpResponseCode(Response.status_code)),
- Response.uploaded_bytes,
- Response.downloaded_bytes,
- NiceResponseTime.c_str());
- }
- else
- {
- const auto It = Response.header.find("Content-Type");
- const std::string_view ContentType = It != Response.header.end() ? It->second : "<None>"sv;
-
- if (ContentType == "application/x-ue-cb"sv)
- {
- zen::IoBuffer Body(zen::IoBuffer::Wrap, Response.text.data(), Response.text.size());
- zen::CbObjectView Obj(Body.Data());
- zen::ExtendableStringBuilder<256> Sb;
- std::string_view Json = Obj.ToJson(Sb).ToView();
-
- return fmt::format_to(
- Ctx.out(),
- "Failed: Url: {}, Status: ({}) '{}', Reason: '{}'. Bytes: {}/{} (Up/Down), Elapsed: {}, Response: '{}'",
- Response.url.str(),
- Response.status_code,
- zen::ToString(zen::HttpResponseCode(Response.status_code)),
- Response.reason,
- Response.uploaded_bytes,
- Response.downloaded_bytes,
- NiceResponseTime.c_str(),
- Json);
- }
- else
- {
- zen::BodyLogFormatter Body(Response.text);
-
- return fmt::format_to(
- Ctx.out(),
- "Failed: Url: {}, Status: ({}) '{}', Reason: '{}'. Bytes: {}/{} (Up/Down), Elapsed: {}, Response: '{}'",
- Response.url.str(),
- Response.status_code,
- zen::ToString(zen::HttpResponseCode(Response.status_code)),
- Response.reason,
- Response.uploaded_bytes,
- Response.downloaded_bytes,
- NiceResponseTime.c_str(),
- Body.GetText());
- }
- }
- }
- }
-};
-
-#endif // ZEN_WITH_CPR
diff --git a/src/zenhttp/include/zenhttp/httpclient.h b/src/zenhttp/include/zenhttp/httpclient.h
index 9531b9366..e199b700f 100644
--- a/src/zenhttp/include/zenhttp/httpclient.h
+++ b/src/zenhttp/include/zenhttp/httpclient.h
@@ -52,9 +52,6 @@ enum class HttpClientErrorCode : int
enum class HttpClientBackend : uint8_t
{
kDefault,
-#if ZEN_WITH_CPR
- kCpr,
-#endif
kCurl,
};
@@ -326,7 +323,10 @@ public:
return std::make_pair("Accept", MapContentTypeToString(ContentType));
}
- [[nodiscard]] Response Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {});
+ [[nodiscard]] Response Put(std::string_view Url,
+ const IoBuffer& Payload,
+ const KeyValueMap& AdditionalHeader = {},
+ const KeyValueMap& Parameters = {});
[[nodiscard]] Response Put(std::string_view Url, const KeyValueMap& Parameters = {});
[[nodiscard]] Response Get(std::string_view Url, const KeyValueMap& AdditionalHeader = {}, const KeyValueMap& Parameters = {});
[[nodiscard]] Response Head(std::string_view Url, const KeyValueMap& AdditionalHeader = {});
@@ -361,6 +361,7 @@ public:
LoggerRef Log() { return m_Log; }
std::string_view GetBaseUri() const { return m_BaseUri; }
std::string_view GetSessionId() const { return m_SessionId; }
+ void SetBaseUri(std::string_view NewBaseUri);
void SetSessionId(const Oid& SessionId);
bool Authenticate();
diff --git a/src/zenhttp/include/zenhttp/httpclientauth.h b/src/zenhttp/include/zenhttp/httpclientauth.h
index f1bccdca6..ce646ebd7 100644
--- a/src/zenhttp/include/zenhttp/httpclientauth.h
+++ b/src/zenhttp/include/zenhttp/httpclientauth.h
@@ -10,9 +10,8 @@ namespace zen {
class AuthMgr;
namespace httpclientauth {
-
- // The std::function<HttpClientAccessToken()> instances returned from these functions are not guarateed to
- // be thread safe so caller must make sure they are not called from multiple threads in parallell
+ // The std::function<HttpClientAccessToken()> instances returned from these functions are not guaranteed to
+ // be thread safe so caller must make sure they are not called from multiple threads in parallel
std::function<HttpClientAccessToken()> CreateFromStaticToken(HttpClientAccessToken Token);
diff --git a/src/zenhttp/include/zenhttp/httpcommon.h b/src/zenhttp/include/zenhttp/httpcommon.h
index 8fca35ac5..f9a99f3cc 100644
--- a/src/zenhttp/include/zenhttp/httpcommon.h
+++ b/src/zenhttp/include/zenhttp/httpcommon.h
@@ -91,6 +91,7 @@ enum class HttpResponseCode
//!< were not for the fact that the condition has evaluated to false.
UseProxy = 305, //!< \deprecated \parblock Due to security concerns regarding in-band configuration of a proxy. \endparblock
//!< The requested resource MUST be accessed through the proxy given by the Location field.
+ SwitchProxy = 306, //!< \deprecated No longer used. Originally meant subsequent requests should use the specified proxy.
TemporaryRedirect = 307, //!< Indicates that the target resource resides temporarily under a different URI and the user agent MUST NOT
//!< change the request method if it performs an automatic redirection to that URI.
PermanentRedirect = 308, //!< The target resource has been assigned a new permanent URI and any future references to this resource
@@ -133,12 +134,14 @@ enum class HttpResponseCode
ExpectationFailed = 417, //!< Indicates that the expectation given in the request's Expect header field could not be met by at least
//!< one of the inbound servers.
ImATeapot = 418, //!< Any attempt to brew coffee with a teapot should result in the error code 418 I'm a teapot.
+ MisdirectedRequest = 421, //!< Indicates that the request was directed at a server that is not able to produce a response.
UnprocessableEntity = 422, //!< Means the server understands the content type of the request entity (hence a 415(Unsupported Media
//!< Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad
//!< Request) status code is inappropriate) but was unable to process the contained instructions.
Locked = 423, //!< Means the source or destination resource of a method is locked.
FailedDependency = 424, //!< Means that the method could not be performed on the resource because the requested action depended on
//!< another action and that action failed.
+ TooEarly = 425, //!< Indicates that the server is unwilling to risk processing a request that might be replayed.
UpgradeRequired = 426, //!< Indicates that the server refuses to perform the request using the current protocol but might be willing to
//!< do so after the client upgrades to a different protocol.
PreconditionRequired = 428, //!< Indicates that the origin server requires the request to be conditional.
diff --git a/src/zenhttp/include/zenhttp/httpserver.h b/src/zenhttp/include/zenhttp/httpserver.h
index a7d7f4d9c..76f219f04 100644
--- a/src/zenhttp/include/zenhttp/httpserver.h
+++ b/src/zenhttp/include/zenhttp/httpserver.h
@@ -12,7 +12,9 @@
#include <zencore/string.h>
#include <zencore/uid.h>
#include <zenhttp/httpcommon.h>
+#include <zenhttp/localrefpolicy.h>
+#include <zentelemetry/hyperloglog.h>
#include <zentelemetry/stats.h>
#include <filesystem>
@@ -192,9 +194,16 @@ public:
HttpService() = default;
virtual ~HttpService() = default;
- virtual const char* BaseUri() const = 0;
- virtual void HandleRequest(HttpServerRequest& HttpServiceRequest) = 0;
- virtual Ref<IHttpPackageHandler> HandlePackageRequest(HttpServerRequest& HttpServiceRequest);
+ [[nodiscard]] virtual const char* BaseUri() const = 0;
+ virtual void HandleRequest(HttpServerRequest& HttpServiceRequest) = 0;
+ virtual Ref<IHttpPackageHandler> HandlePackageRequest(HttpServerRequest& HttpServiceRequest);
+
+ /// Whether this service accepts local file references in inbound packages from local clients.
+ [[nodiscard]] virtual bool AcceptsLocalFileReferences() const;
+
+ /// Returns the local ref policy for validating file paths in inbound local references.
+ /// Returns nullptr by default, which causes file-path local refs to be rejected (fail-closed).
+ [[nodiscard]] virtual const ILocalRefPolicy* GetLocalRefPolicy() const;
// Internals
@@ -219,6 +228,12 @@ struct IHttpStatsProvider
* not override this will be skipped in WebSocket broadcasts.
*/
virtual CbObject CollectStats() { return {}; }
+
+ /** Return a number indicating activity. Increase the number
+ * when activity is detected. Example would be to return the
+ * number of received requests
+ */
+ virtual uint64_t GetActivityCounter() { return 0; }
};
struct IHttpStatsService
@@ -265,6 +280,19 @@ public:
/** Mark that a request has been handled. Called by server implementations. */
void MarkRequest() { m_RequestMeter.Mark(); }
+ /** Record a client address for distinct-client tracking. Pass the raw
+ * address bytes (4 bytes for IPv4, 16 for IPv6) to avoid string conversion. */
+ void MarkClientAddress(const void* AddressBytes, size_t Size) { m_ClientAddresses.Add(AddressBytes, Size); }
+
+ /** Record a session ID for distinct-session tracking. */
+ void MarkSessionId(const Oid& SessionId)
+ {
+ if (SessionId)
+ {
+ m_ClientSessions.Add(&SessionId.OidBits, sizeof(SessionId.OidBits));
+ }
+ }
+
/** Set a default redirect path for root requests */
void SetDefaultRedirect(std::string_view Path) { m_DefaultRedirect = Path; }
@@ -288,8 +316,8 @@ public:
}
// IHttpStatsProvider
- virtual CbObject CollectStats() override;
virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
private:
std::vector<HttpService*> m_KnownServices;
@@ -297,6 +325,8 @@ private:
int m_EffectiveHttpsPort = 0;
std::string m_ExternalHost;
metrics::Meter m_RequestMeter;
+ metrics::HyperLogLog<12> m_ClientAddresses; // ~4 KiB, ~1.6% error — sufficient for client counting
+ metrics::HyperLogLog<12> m_ClientSessions;
std::string m_DefaultRedirect;
std::atomic<uint64_t> m_ActiveWebSocketConnections{0};
std::atomic<uint64_t> m_WsFramesReceived{0};
diff --git a/src/zenhttp/include/zenhttp/httpstats.h b/src/zenhttp/include/zenhttp/httpstats.h
index 460315faf..b20bc3a36 100644
--- a/src/zenhttp/include/zenhttp/httpstats.h
+++ b/src/zenhttp/include/zenhttp/httpstats.h
@@ -43,7 +43,7 @@ public:
virtual void UnregisterHandler(std::string_view Id, IHttpStatsProvider& Provider) override;
// IWebSocketHandler
- void OnWebSocketOpen(Ref<WebSocketConnection> Connection) override;
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override;
void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg) override;
void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason) override;
@@ -62,6 +62,7 @@ private:
std::atomic<bool> m_PushEnabled{false};
void BroadcastStats();
+ void Initialize();
// Thread-based push (when no io_context is provided)
std::thread m_PushThread;
diff --git a/src/zenhttp/include/zenhttp/localrefpolicy.h b/src/zenhttp/include/zenhttp/localrefpolicy.h
new file mode 100644
index 000000000..0b37f9dc7
--- /dev/null
+++ b/src/zenhttp/include/zenhttp/localrefpolicy.h
@@ -0,0 +1,21 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <filesystem>
+
+namespace zen {
+
+/// Policy interface for validating local file reference paths in inbound CbPackage messages.
+/// Implementations should throw std::invalid_argument if the path is not allowed.
+class ILocalRefPolicy
+{
+public:
+ virtual ~ILocalRefPolicy() = default;
+
+ /// Validate that a local file reference path is allowed.
+ /// Throws std::invalid_argument if the path escapes the allowed root.
+ virtual void ValidatePath(const std::filesystem::path& Path) const = 0;
+};
+
+} // namespace zen
diff --git a/src/zenhttp/include/zenhttp/packageformat.h b/src/zenhttp/include/zenhttp/packageformat.h
index 1a5068580..66e3f6e55 100644
--- a/src/zenhttp/include/zenhttp/packageformat.h
+++ b/src/zenhttp/include/zenhttp/packageformat.h
@@ -5,6 +5,7 @@
#include <zencore/compactbinarypackage.h>
#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
+#include <zenhttp/localrefpolicy.h>
#include <functional>
#include <gsl/gsl-lite.hpp>
@@ -97,11 +98,22 @@ gsl_DEFINE_ENUM_BITMASK_OPERATORS(RpcAcceptOptions);
std::vector<IoBuffer> FormatPackageMessage(const CbPackage& Data, FormatFlags Flags, void* TargetProcessHandle = nullptr);
CompositeBuffer FormatPackageMessageBuffer(const CbPackage& Data, FormatFlags Flags, void* TargetProcessHandle = nullptr);
-CbPackage ParsePackageMessage(
- IoBuffer Payload,
- std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> CreateBuffer = [](const IoHash&, uint64_t Size) -> IoBuffer {
+
+enum class ParseFlags
+{
+ kDefault = 0,
+ kAllowLocalReferences = (1u << 0), // Allow packages containing local file references (local clients only)
+};
+
+gsl_DEFINE_ENUM_BITMASK_OPERATORS(ParseFlags);
+
+CbPackage ParsePackageMessage(
+ IoBuffer Payload,
+ std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> CreateBuffer = [](const IoHash&, uint64_t Size) -> IoBuffer {
return IoBuffer{Size};
- });
+ },
+ ParseFlags Flags = ParseFlags::kDefault,
+ const ILocalRefPolicy* Policy = nullptr);
bool IsPackageMessage(IoBuffer Payload);
bool ParsePackageMessageWithLegacyFallback(const IoBuffer& Response, CbPackage& OutPackage);
@@ -122,10 +134,11 @@ CompositeBuffer FormatPackageMessageBuffer(const CbPackage& Data, void* Targe
class CbPackageReader
{
public:
- CbPackageReader();
+ CbPackageReader(ParseFlags Flags = ParseFlags::kDefault);
~CbPackageReader();
void SetPayloadBufferCreator(std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> CreateBuffer);
+ void SetLocalRefPolicy(const ILocalRefPolicy* Policy);
/** Process compact binary package data stream
@@ -149,6 +162,8 @@ private:
kReadingBuffers
} m_CurrentState = State::kInitialState;
+ ParseFlags m_Flags;
+ const ILocalRefPolicy* m_LocalRefPolicy = nullptr;
std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> m_CreateBuffer;
std::vector<IoBuffer> m_PayloadBuffers;
std::vector<CbAttachmentEntry> m_AttachmentEntries;
diff --git a/src/zenhttp/include/zenhttp/websocket.h b/src/zenhttp/include/zenhttp/websocket.h
index 710579faa..2d25515d3 100644
--- a/src/zenhttp/include/zenhttp/websocket.h
+++ b/src/zenhttp/include/zenhttp/websocket.h
@@ -59,7 +59,7 @@ class IWebSocketHandler
public:
virtual ~IWebSocketHandler() = default;
- virtual void OnWebSocketOpen(Ref<WebSocketConnection> Connection) = 0;
+ virtual void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) = 0;
virtual void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg) = 0;
virtual void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason) = 0;
};
diff --git a/src/zenhttp/monitoring/httpstats.cpp b/src/zenhttp/monitoring/httpstats.cpp
index 3877215a8..5ad5ebcc7 100644
--- a/src/zenhttp/monitoring/httpstats.cpp
+++ b/src/zenhttp/monitoring/httpstats.cpp
@@ -16,6 +16,7 @@ HttpStatsService::HttpStatsService(bool EnableWebSockets) : m_Log(logging::Get("
m_PushEnabled.store(true);
m_PushThread = std::thread([this] { PushThreadFunction(); });
}
+ Initialize();
}
HttpStatsService::HttpStatsService(asio::io_context& IoContext, bool EnableWebSockets) : m_Log(logging::Get("stats"))
@@ -26,6 +27,110 @@ HttpStatsService::HttpStatsService(asio::io_context& IoContext, bool EnableWebSo
m_PushTimer = std::make_unique<asio::steady_timer>(IoContext);
EnqueuePushTimer();
}
+ Initialize();
+}
+
+void
+HttpStatsService::Initialize()
+{
+ m_Router.AddMatcher("handler_id", [](std::string_view Str) -> bool {
+ if (Str.empty())
+ {
+ return false;
+ }
+ for (const auto C : Str)
+ {
+ if (std::isalnum(C) || C == '$')
+ {
+ // fine
+ }
+ else
+ {
+ // not fine
+ return false;
+ }
+ }
+ return true;
+ });
+
+ m_Router.RegisterRoute(
+ "activity_counters",
+ [this](HttpRouterRequest& Request) {
+ CbObjectWriter Obj;
+
+ std::uint64_t SumActivity = 0;
+
+ std::vector<std::pair<std::string, uint64_t>> Activities;
+ {
+ RwLock::SharedLockScope _(m_Lock);
+ Activities.reserve(m_Providers.size());
+ for (const auto& It : m_Providers)
+ {
+ const std::string& HandlerName = It.first;
+ IHttpStatsProvider* Provider = It.second;
+ ZEN_ASSERT(Provider != nullptr);
+ uint64_t ProviderActivityCounter = Provider->GetActivityCounter();
+ if (ProviderActivityCounter != 0)
+ {
+ Activities.push_back(std::make_pair(HandlerName, ProviderActivityCounter));
+ }
+ SumActivity += ProviderActivityCounter;
+ }
+ }
+
+ Obj.BeginArray("providers");
+ for (const std::pair<std::string, uint64_t>& Activity : Activities)
+ {
+ const std::string& HandlerName = Activity.first;
+ uint64_t ProviderActivityCounter = Activity.second;
+ Obj.BeginObject();
+ {
+ Obj.AddString("provider", HandlerName);
+ Obj.AddInteger("activity_counter", ProviderActivityCounter);
+ }
+ Obj.EndObject();
+ }
+ Obj.EndArray();
+
+ Obj.AddInteger("sum", SumActivity);
+
+ Request.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "{handler_id}",
+ [this](HttpRouterRequest& Request) {
+ std::string_view Handler = Request.GetCapture(1);
+ RwLock::SharedLockScope _(m_Lock);
+ if (auto It = m_Providers.find(std::string{Handler}); It != end(m_Providers))
+ {
+ return It->second->HandleStatsRequest(Request.ServerRequest());
+ }
+ Request.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
+ },
+ HttpVerb::kHead | HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "",
+ [this](HttpRouterRequest& Request) {
+ CbObjectWriter Cbo;
+
+ Cbo.BeginArray("providers");
+
+ {
+ RwLock::SharedLockScope _(m_Lock);
+ for (auto& Kv : m_Providers)
+ {
+ Cbo << Kv.first;
+ }
+ }
+
+ Cbo.EndArray();
+
+ Request.ServerRequest().WriteResponse(HttpResponseCode::OK, Cbo.Save());
+ },
+ HttpVerb::kHead | HttpVerb::kGet);
}
HttpStatsService::~HttpStatsService()
@@ -82,54 +187,7 @@ void
HttpStatsService::HandleRequest(HttpServerRequest& Request)
{
ZEN_TRACE_CPU("HttpStatsService::HandleRequest");
- using namespace std::literals;
-
- std::string_view Key = Request.RelativeUri();
-
- switch (Request.RequestVerb())
- {
- case HttpVerb::kHead:
- case HttpVerb::kGet:
- {
- if (Key.empty())
- {
- CbObjectWriter Cbo;
-
- Cbo.BeginArray("providers");
-
- {
- RwLock::SharedLockScope _(m_Lock);
- for (auto& Kv : m_Providers)
- {
- Cbo << Kv.first;
- }
- }
-
- Cbo.EndArray();
-
- Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
- }
- else if (Key[0] == '/')
- {
- Key.remove_prefix(1);
- size_t SlashPos = Key.find_first_of("/?");
- if (SlashPos != std::string::npos)
- {
- Key = Key.substr(0, SlashPos);
- }
-
- RwLock::SharedLockScope _(m_Lock);
- if (auto It = m_Providers.find(std::string{Key}); It != end(m_Providers))
- {
- return It->second->HandleStatsRequest(Request);
- }
- }
- }
-
- [[fallthrough]];
- default:
- return;
- }
+ m_Router.HandleRequest(Request);
}
//////////////////////////////////////////////////////////////////////////
@@ -138,8 +196,9 @@ HttpStatsService::HandleRequest(HttpServerRequest& Request)
//
void
-HttpStatsService::OnWebSocketOpen(Ref<WebSocketConnection> Connection)
+HttpStatsService::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
{
+ ZEN_UNUSED(RelativeUri);
ZEN_TRACE_CPU("HttpStatsService::OnWebSocketOpen");
ZEN_INFO("Stats WebSocket client connected");
@@ -189,11 +248,8 @@ HttpStatsService::BroadcastStats()
return;
}
- // Collect stats from all providers
- ExtendableStringBuilder<4096> JsonBuilder;
- JsonBuilder.Append("{");
-
- bool First = true;
+ // Collect stats from all providers into a single CBO object, then convert to JSON
+ CbObjectWriter Writer;
{
RwLock::SharedLockScope _(m_Lock);
for (auto& [Id, Provider] : m_Providers)
@@ -203,27 +259,15 @@ HttpStatsService::BroadcastStats()
{
continue;
}
-
- if (!First)
- {
- JsonBuilder.Append(",");
- }
- First = false;
-
- // Emit as "provider_id": { ... }
- JsonBuilder.Append("\"");
- JsonBuilder.Append(Id);
- JsonBuilder.Append("\":");
-
- ExtendableStringBuilder<2048> StatsJson;
- Stats.ToJson(StatsJson);
- JsonBuilder.Append(StatsJson.ToView());
+ Writer.AddObject(Id, Stats);
}
}
- JsonBuilder.Append("}");
-
+ CbObject Payload = Writer.Save();
+ ExtendableStringBuilder<4096> JsonBuilder;
+ Payload.ToJson(JsonBuilder);
std::string_view Json = JsonBuilder.ToView();
+
for (auto& Conn : Connections)
{
if (Conn->IsOpen())
diff --git a/src/zenhttp/packageformat.cpp b/src/zenhttp/packageformat.cpp
index 9c62c1f2d..267ce386c 100644
--- a/src/zenhttp/packageformat.cpp
+++ b/src/zenhttp/packageformat.cpp
@@ -36,6 +36,71 @@ const std::string_view HandlePrefix(":?#:");
typedef eastl::fixed_vector<IoBuffer, 16> IoBufferVec_t;
+/// Enforce local-ref path policy. Handle-based refs bypass the policy since they use OS handle security.
+/// If no policy is set, file-path local refs are rejected (fail-closed).
+static void
+ApplyLocalRefPolicy(const ILocalRefPolicy* Policy, const std::filesystem::path& Path)
+{
+ if (Policy)
+ {
+ Policy->ValidatePath(Path);
+ }
+ else
+ {
+ throw std::invalid_argument("local file reference rejected: no validation policy");
+ }
+}
+
+// Validates the CbPackageHeader magic and attachment count. Returns the total
+// chunk count (AttachmentCount + 1, including the implicit root object).
+static uint32_t
+ValidatePackageHeader(const CbPackageHeader& Hdr)
+{
+ if (Hdr.HeaderMagic != kCbPkgMagic)
+ {
+ throw std::invalid_argument(
+ fmt::format("invalid CbPackage header magic, expected {0:x}, got {1:x}", static_cast<uint32_t>(kCbPkgMagic), Hdr.HeaderMagic));
+ }
+ // ChunkCount is AttachmentCount + 1 (the root object is implicit). Guard against
+ // UINT32_MAX wrapping to 0, which would bypass subsequent size checks.
+ if (Hdr.AttachmentCount == UINT32_MAX)
+ {
+ throw std::invalid_argument("invalid CbPackage, attachment count overflow");
+ }
+ return Hdr.AttachmentCount + 1;
+}
+
+struct ValidatedLocalRef
+{
+ bool Valid = false;
+ const CbAttachmentReferenceHeader* Header = nullptr;
+ std::string_view Path;
+ std::string Error;
+};
+
+// Validates that the attachment buffer contains a well-formed local reference
+// header and path. On failure, Valid is false and Error contains the reason.
+static ValidatedLocalRef
+ValidateLocalRef(const IoBuffer& AttachmentBuffer)
+{
+ if (AttachmentBuffer.Size() < sizeof(CbAttachmentReferenceHeader))
+ {
+ return {.Error = fmt::format("local ref attachment too small for header (size {})", AttachmentBuffer.Size())};
+ }
+
+ const CbAttachmentReferenceHeader* AttachRefHdr = AttachmentBuffer.Data<CbAttachmentReferenceHeader>();
+
+ if (AttachmentBuffer.Size() < sizeof(CbAttachmentReferenceHeader) + AttachRefHdr->AbsolutePathLength)
+ {
+ return {.Error = fmt::format("local ref attachment too small for path (need {}, have {})",
+ sizeof(CbAttachmentReferenceHeader) + AttachRefHdr->AbsolutePathLength,
+ AttachmentBuffer.Size())};
+ }
+
+ const char* PathPointer = reinterpret_cast<const char*>(AttachRefHdr + 1);
+ return {.Valid = true, .Header = AttachRefHdr, .Path = std::string_view(PathPointer, AttachRefHdr->AbsolutePathLength)};
+}
+
IoBufferVec_t FormatPackageMessageInternal(const CbPackage& Data, FormatFlags Flags, void* TargetProcessHandle);
std::vector<IoBuffer>
@@ -361,7 +426,10 @@ IsPackageMessage(IoBuffer Payload)
}
CbPackage
-ParsePackageMessage(IoBuffer Payload, std::function<IoBuffer(const IoHash&, uint64_t)> CreateBuffer)
+ParsePackageMessage(IoBuffer Payload,
+ std::function<IoBuffer(const IoHash&, uint64_t)> CreateBuffer,
+ ParseFlags Flags,
+ const ILocalRefPolicy* Policy)
{
ZEN_TRACE_CPU("ParsePackageMessage");
@@ -372,17 +440,13 @@ ParsePackageMessage(IoBuffer Payload, std::function<IoBuffer(const IoHash&, uint
BinaryReader Reader(Payload);
- const CbPackageHeader* Hdr = reinterpret_cast<const CbPackageHeader*>(Reader.GetView(sizeof(CbPackageHeader)).GetData());
- if (Hdr->HeaderMagic != kCbPkgMagic)
- {
- throw std::invalid_argument(
- fmt::format("invalid CbPackage header magic, expected {0:x}, got {1:x}", static_cast<uint32_t>(kCbPkgMagic), Hdr->HeaderMagic));
- }
+ const CbPackageHeader* Hdr = reinterpret_cast<const CbPackageHeader*>(Reader.GetView(sizeof(CbPackageHeader)).GetData());
+ const uint32_t ChunkCount = ValidatePackageHeader(*Hdr);
Reader.Skip(sizeof(CbPackageHeader));
- const uint32_t ChunkCount = Hdr->AttachmentCount + 1;
-
- if (Reader.Remaining() < sizeof(CbAttachmentEntry) * ChunkCount)
+ // Widen to uint64_t so the multiplication cannot wrap on 32-bit.
+ const uint64_t AttachmentTableSize = uint64_t(sizeof(CbAttachmentEntry)) * ChunkCount;
+ if (Reader.Remaining() < AttachmentTableSize)
{
throw std::invalid_argument(fmt::format("invalid CbPackage, missing attachment entry data (need {} bytes, have {} bytes)",
sizeof(CbAttachmentEntry) * ChunkCount,
@@ -417,15 +481,22 @@ ParsePackageMessage(IoBuffer Payload, std::function<IoBuffer(const IoHash&, uint
if (Entry.Flags & CbAttachmentEntry::kIsLocalRef)
{
- // Marshal local reference - a "pointer" to the chunk backing file
-
- ZEN_ASSERT(AttachmentBuffer.Size() >= sizeof(CbAttachmentReferenceHeader));
+ if (!EnumHasAllFlags(Flags, ParseFlags::kAllowLocalReferences))
+ {
+ throw std::invalid_argument(
+ fmt::format("package contains local reference (attachment #{}) but local references are not allowed", i));
+ }
- const CbAttachmentReferenceHeader* AttachRefHdr = AttachmentBuffer.Data<CbAttachmentReferenceHeader>();
- const char* PathPointer = reinterpret_cast<const char*>(AttachRefHdr + 1);
+ // Marshal local reference - a "pointer" to the chunk backing file
- ZEN_ASSERT(AttachmentBuffer.Size() >= (sizeof(CbAttachmentReferenceHeader) + AttachRefHdr->AbsolutePathLength));
- std::string_view PathView(PathPointer, AttachRefHdr->AbsolutePathLength);
+ ValidatedLocalRef LocalRef = ValidateLocalRef(AttachmentBuffer);
+ if (!LocalRef.Valid)
+ {
+ MalformedAttachments.push_back(std::make_pair(i, fmt::format("{} for {}", LocalRef.Error, Entry.AttachmentHash)));
+ continue;
+ }
+ const CbAttachmentReferenceHeader* AttachRefHdr = LocalRef.Header;
+ std::string_view PathView = LocalRef.Path;
IoBuffer FullFileBuffer;
@@ -461,13 +532,29 @@ ParsePackageMessage(IoBuffer Payload, std::function<IoBuffer(const IoHash&, uint
}
else
{
+ ApplyLocalRefPolicy(Policy, Path);
FullFileBuffer = PartialFileBuffers.insert_or_assign(Path.string(), IoBufferBuilder::MakeFromFile(Path)).first->second;
}
}
if (FullFileBuffer)
{
- IoBuffer ChunkReference = AttachRefHdr->PayloadByteOffset == 0 && AttachRefHdr->PayloadByteSize == FullFileBuffer.GetSize()
+ // Guard against offset+size overflow or exceeding the file bounds.
+ const uint64_t FileSize = FullFileBuffer.GetSize();
+ if (AttachRefHdr->PayloadByteOffset > FileSize ||
+ AttachRefHdr->PayloadByteSize > FileSize - AttachRefHdr->PayloadByteOffset)
+ {
+ MalformedAttachments.push_back(
+ std::make_pair(i,
+ fmt::format("Local ref offset/size out of bounds (offset {}, size {}, file size {}) for {}",
+ AttachRefHdr->PayloadByteOffset,
+ AttachRefHdr->PayloadByteSize,
+ FileSize,
+ Entry.AttachmentHash)));
+ continue;
+ }
+
+ IoBuffer ChunkReference = AttachRefHdr->PayloadByteOffset == 0 && AttachRefHdr->PayloadByteSize == FileSize
? FullFileBuffer
: IoBuffer(FullFileBuffer, AttachRefHdr->PayloadByteOffset, AttachRefHdr->PayloadByteSize);
@@ -630,7 +717,9 @@ ParsePackageMessageWithLegacyFallback(const IoBuffer& Response, CbPackage& OutPa
return OutPackage.TryLoad(Response);
}
-CbPackageReader::CbPackageReader() : m_CreateBuffer([](const IoHash&, uint64_t Size) -> IoBuffer { return IoBuffer{Size}; })
+CbPackageReader::CbPackageReader(ParseFlags Flags)
+: m_Flags(Flags)
+, m_CreateBuffer([](const IoHash&, uint64_t Size) -> IoBuffer { return IoBuffer{Size}; })
{
}
@@ -644,6 +733,12 @@ CbPackageReader::SetPayloadBufferCreator(std::function<IoBuffer(const IoHash& Ci
m_CreateBuffer = CreateBuffer;
}
+void
+CbPackageReader::SetLocalRefPolicy(const ILocalRefPolicy* Policy)
+{
+ m_LocalRefPolicy = Policy;
+}
+
uint64_t
CbPackageReader::ProcessPackageHeaderData(const void* Data, uint64_t DataBytes)
{
@@ -657,12 +752,14 @@ CbPackageReader::ProcessPackageHeaderData(const void* Data, uint64_t DataBytes)
return sizeof m_PackageHeader;
case State::kReadingHeader:
- ZEN_ASSERT(DataBytes == sizeof m_PackageHeader);
- memcpy(&m_PackageHeader, Data, sizeof m_PackageHeader);
- ZEN_ASSERT(m_PackageHeader.HeaderMagic == kCbPkgMagic);
- m_CurrentState = State::kReadingAttachmentEntries;
- m_AttachmentEntries.resize(m_PackageHeader.AttachmentCount + 1);
- return (m_PackageHeader.AttachmentCount + 1) * sizeof(CbAttachmentEntry);
+ {
+ ZEN_ASSERT(DataBytes == sizeof m_PackageHeader);
+ memcpy(&m_PackageHeader, Data, sizeof m_PackageHeader);
+ const uint32_t ChunkCount = ValidatePackageHeader(m_PackageHeader);
+ m_CurrentState = State::kReadingAttachmentEntries;
+ m_AttachmentEntries.resize(ChunkCount);
+ return uint64_t(ChunkCount) * sizeof(CbAttachmentEntry);
+ }
case State::kReadingAttachmentEntries:
ZEN_ASSERT(DataBytes == ((m_PackageHeader.AttachmentCount + 1) * sizeof(CbAttachmentEntry)));
@@ -691,16 +788,19 @@ CbPackageReader::MarshalLocalChunkReference(IoBuffer AttachmentBuffer)
{
// Marshal local reference - a "pointer" to the chunk backing file
- ZEN_ASSERT(AttachmentBuffer.Size() >= sizeof(CbAttachmentReferenceHeader));
-
- const CbAttachmentReferenceHeader* AttachRefHdr = AttachmentBuffer.Data<CbAttachmentReferenceHeader>();
- const char8_t* PathPointer = reinterpret_cast<const char8_t*>(AttachRefHdr + 1);
-
- ZEN_ASSERT(AttachmentBuffer.Size() >= (sizeof(CbAttachmentReferenceHeader) + AttachRefHdr->AbsolutePathLength));
+ ValidatedLocalRef LocalRef = ValidateLocalRef(AttachmentBuffer);
+ if (!LocalRef.Valid)
+ {
+ throw std::invalid_argument(LocalRef.Error);
+ }
- std::u8string_view PathView{PathPointer, AttachRefHdr->AbsolutePathLength};
+ const CbAttachmentReferenceHeader* AttachRefHdr = LocalRef.Header;
+ std::filesystem::path Path(Utf8ToWide(LocalRef.Path));
- std::filesystem::path Path{PathView};
+ if (!LocalRef.Path.starts_with(HandlePrefix))
+ {
+ ApplyLocalRefPolicy(m_LocalRefPolicy, Path);
+ }
IoBuffer ChunkReference = IoBufferBuilder::MakeFromFile(Path, AttachRefHdr->PayloadByteOffset, AttachRefHdr->PayloadByteSize);
@@ -714,6 +814,17 @@ CbPackageReader::MarshalLocalChunkReference(IoBuffer AttachmentBuffer)
AttachRefHdr->PayloadByteSize));
}
+ // MakeFromFile silently clamps offset+size to the file size. Detect this
+ // to avoid returning a short buffer that could cause subtle downstream issues.
+ if (ChunkReference.GetSize() != AttachRefHdr->PayloadByteSize)
+ {
+ throw std::invalid_argument(fmt::format("local ref offset/size out of bounds for '{}' (requested offset {}, size {}, got size {})",
+ PathToUtf8(Path),
+ AttachRefHdr->PayloadByteOffset,
+ AttachRefHdr->PayloadByteSize,
+ ChunkReference.GetSize()));
+ }
+
return ChunkReference;
};
@@ -732,6 +843,13 @@ CbPackageReader::Finalize()
{
IoBuffer AttachmentBuffer = m_PayloadBuffers[CurrentAttachmentIndex];
+ if ((Entry.Flags & CbAttachmentEntry::kIsLocalRef) && !EnumHasAllFlags(m_Flags, ParseFlags::kAllowLocalReferences))
+ {
+ throw std::invalid_argument(
+ fmt::format("package contains local reference (attachment #{}) but local references are not allowed",
+ CurrentAttachmentIndex));
+ }
+
if (CurrentAttachmentIndex == 0)
{
// Root object
@@ -815,6 +933,13 @@ CbPackageReader::Finalize()
TEST_SUITE_BEGIN("http.packageformat");
+/// Permissive policy that allows any path, for use in tests that exercise local ref
+/// functionality but are not testing path validation.
+struct PermissiveLocalRefPolicy : public ILocalRefPolicy
+{
+ void ValidatePath(const std::filesystem::path&) const override {}
+};
+
TEST_CASE("CbPackage.Serialization")
{
// Make a test package
@@ -922,6 +1047,169 @@ TEST_CASE("CbPackage.LocalRef")
RemainingBytes -= ByteCount;
};
+ PermissiveLocalRefPolicy AllowAllPolicy;
+ CbPackageReader Reader(ParseFlags::kAllowLocalReferences);
+ Reader.SetLocalRefPolicy(&AllowAllPolicy);
+ uint64_t InitialRead = Reader.ProcessPackageHeaderData(nullptr, 0);
+ uint64_t NextBytes = Reader.ProcessPackageHeaderData(ConsumeBytes(InitialRead), InitialRead);
+ NextBytes = Reader.ProcessPackageHeaderData(ConsumeBytes(NextBytes), NextBytes);
+ auto Buffers = Reader.GetPayloadBuffers();
+
+ for (auto& PayloadBuffer : Buffers)
+ {
+ CopyBytes(PayloadBuffer.MutableData(), PayloadBuffer.GetSize());
+ }
+
+ Reader.Finalize();
+}
+
+TEST_CASE("CbPackage.Validation.TruncatedHeader")
+{
+ // Payload too small for a CbPackageHeader
+ uint8_t Bytes[] = {0xcc, 0xaa, 0x77, 0xaa};
+ IoBuffer Payload(IoBuffer::Wrap, Bytes, sizeof(Bytes));
+ CHECK_THROWS_AS(ParsePackageMessage(Payload), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.BadMagic")
+{
+ CbPackageHeader Hdr{};
+ Hdr.HeaderMagic = 0xDEADBEEF;
+ Hdr.AttachmentCount = 0;
+ IoBuffer Payload(IoBuffer::Wrap, &Hdr, sizeof(Hdr));
+ CHECK_THROWS_AS(ParsePackageMessage(Payload), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.AttachmentCountOverflow")
+{
+ CbPackageHeader Hdr{};
+ Hdr.HeaderMagic = kCbPkgMagic;
+ Hdr.AttachmentCount = UINT32_MAX;
+ IoBuffer Payload(IoBuffer::Wrap, &Hdr, sizeof(Hdr));
+ CHECK_THROWS_AS(ParsePackageMessage(Payload), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.TruncatedAttachmentTable")
+{
+ // Valid header but not enough data for the attachment entries
+ CbPackageHeader Hdr{};
+ Hdr.HeaderMagic = kCbPkgMagic;
+ Hdr.AttachmentCount = 10;
+ IoBuffer Payload(IoBuffer::Wrap, &Hdr, sizeof(Hdr));
+ CHECK_THROWS_AS(ParsePackageMessage(Payload), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.TruncatedAttachmentData")
+{
+ // Valid header + one attachment entry claiming more data than available
+ std::vector<uint8_t> Data(sizeof(CbPackageHeader) + sizeof(CbAttachmentEntry));
+
+ CbPackageHeader* Hdr = reinterpret_cast<CbPackageHeader*>(Data.data());
+ Hdr->HeaderMagic = kCbPkgMagic;
+ Hdr->AttachmentCount = 0; // ChunkCount = 1 (root object)
+
+ CbAttachmentEntry* Entry = reinterpret_cast<CbAttachmentEntry*>(Data.data() + sizeof(CbPackageHeader));
+ Entry->PayloadSize = 9999; // way more than available
+ Entry->Flags = CbAttachmentEntry::kIsObject;
+ Entry->AttachmentHash = IoHash();
+
+ IoBuffer Payload(IoBuffer::Wrap, Data.data(), Data.size());
+ CHECK_THROWS_AS(ParsePackageMessage(Payload), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.LocalRefRejectedByDefault")
+{
+ // Build a valid package with local refs backed by compressed-format files,
+ // then verify it's rejected with default ParseFlags and accepted when allowed.
+ ScopedTemporaryDirectory TempDir;
+ auto Path1 = TempDir.Path() / "abcd";
+ auto Path2 = TempDir.Path() / "efgh";
+
+ // Compress data and write to disk, then create file-backed compressed attachments.
+ // The files must contain compressed-format data because ParsePackageMessage expects it
+ // when resolving local refs.
+ CompressedBuffer Comp1 =
+ CompressedBuffer::Compress(SharedBuffer::MakeView(MakeMemoryView("abcd")), OodleCompressor::NotSet, OodleCompressionLevel::None);
+ CompressedBuffer Comp2 =
+ CompressedBuffer::Compress(SharedBuffer::MakeView(MakeMemoryView("efgh")), OodleCompressor::NotSet, OodleCompressionLevel::None);
+
+ IoHash Hash1 = Comp1.DecodeRawHash();
+ IoHash Hash2 = Comp2.DecodeRawHash();
+
+ {
+ IoBuffer Buf1 = Comp1.GetCompressed().Flatten().AsIoBuffer();
+ IoBuffer Buf2 = Comp2.GetCompressed().Flatten().AsIoBuffer();
+ WriteFile(Path1, Buf1);
+ WriteFile(Path2, Buf2);
+ }
+
+ // Create attachments from file-backed buffers so FormatPackageMessage uses local refs
+ CbAttachment Attach1{CompressedBuffer::FromCompressedNoValidate(IoBufferBuilder::MakeFromFile(Path1)), Hash1};
+ CbAttachment Attach2{CompressedBuffer::FromCompressedNoValidate(IoBufferBuilder::MakeFromFile(Path2)), Hash2};
+
+ CbObjectWriter Cbo;
+ Cbo.AddAttachment("abcd", Attach1);
+ Cbo.AddAttachment("efgh", Attach2);
+
+ CbPackage Pkg;
+ Pkg.AddAttachment(Attach1);
+ Pkg.AddAttachment(Attach2);
+ Pkg.SetObject(Cbo.Save());
+
+ IoBuffer Payload = FormatPackageMessageBuffer(Pkg, FormatFlags::kAllowLocalReferences).Flatten().AsIoBuffer();
+
+ // Default flags should reject local refs
+ CHECK_THROWS_AS(ParsePackageMessage(Payload), std::invalid_argument);
+
+ // With kAllowLocalReferences + a permissive policy, the local-ref gate is passed (the full round-trip
+ // for local refs through ParsePackageMessage is covered by CbPackage.LocalRef via CbPackageReader)
+ PermissiveLocalRefPolicy AllowAllPolicy;
+ CbPackage Result = ParsePackageMessage(Payload, {}, ParseFlags::kAllowLocalReferences, &AllowAllPolicy);
+ CHECK(Result.GetObject());
+ CHECK(Result.GetAttachments().size() == 2);
+}
+
+TEST_CASE("CbPackage.Validation.LocalRefRejectedByReader")
+{
+ // Same test but via CbPackageReader
+ ScopedTemporaryDirectory TempDir;
+ auto FilePath = TempDir.Path() / "testdata";
+
+ {
+ IoBuffer Buf = IoBufferBuilder::MakeCloneFromMemory(MakeMemoryView("testdata"));
+ WriteFile(FilePath, Buf);
+ }
+
+ IoBuffer FileBuffer = IoBufferBuilder::MakeFromFile(FilePath);
+ CbAttachment Attach{SharedBuffer(FileBuffer)};
+
+ CbObjectWriter Cbo;
+ Cbo.AddAttachment("data", Attach);
+
+ CbPackage Pkg;
+ Pkg.AddAttachment(Attach);
+ Pkg.SetObject(Cbo.Save());
+
+ SharedBuffer Buffer = FormatPackageMessageBuffer(Pkg, FormatFlags::kAllowLocalReferences).Flatten();
+ const uint8_t* CursorPtr = reinterpret_cast<const uint8_t*>(Buffer.GetData());
+ uint64_t RemainingBytes = Buffer.GetSize();
+
+ auto ConsumeBytes = [&](uint64_t ByteCount) {
+ ZEN_ASSERT(ByteCount <= RemainingBytes);
+ void* ReturnPtr = (void*)CursorPtr;
+ CursorPtr += ByteCount;
+ RemainingBytes -= ByteCount;
+ return ReturnPtr;
+ };
+
+ auto CopyBytes = [&](void* TargetBuffer, uint64_t ByteCount) {
+ ZEN_ASSERT(ByteCount <= RemainingBytes);
+ memcpy(TargetBuffer, CursorPtr, ByteCount);
+ CursorPtr += ByteCount;
+ RemainingBytes -= ByteCount;
+ };
+
+ // Default flags should reject
CbPackageReader Reader;
uint64_t InitialRead = Reader.ProcessPackageHeaderData(nullptr, 0);
uint64_t NextBytes = Reader.ProcessPackageHeaderData(ConsumeBytes(InitialRead), InitialRead);
@@ -933,7 +1221,199 @@ TEST_CASE("CbPackage.LocalRef")
CopyBytes(PayloadBuffer.MutableData(), PayloadBuffer.GetSize());
}
- Reader.Finalize();
+ CHECK_THROWS_AS(Reader.Finalize(), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.BadMagicViaReader")
+{
+ CbPackageHeader Hdr{};
+ Hdr.HeaderMagic = 0xBADCAFE;
+ Hdr.AttachmentCount = 0;
+
+ CbPackageReader Reader;
+ uint64_t InitialRead = Reader.ProcessPackageHeaderData(nullptr, 0);
+ CHECK_THROWS_AS(Reader.ProcessPackageHeaderData(&Hdr, InitialRead), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.Validation.AttachmentCountOverflowViaReader")
+{
+ CbPackageHeader Hdr{};
+ Hdr.HeaderMagic = kCbPkgMagic;
+ Hdr.AttachmentCount = UINT32_MAX;
+
+ CbPackageReader Reader;
+ uint64_t InitialRead = Reader.ProcessPackageHeaderData(nullptr, 0);
+ CHECK_THROWS_AS(Reader.ProcessPackageHeaderData(&Hdr, InitialRead), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.LocalRefPolicy.PathOutsideRoot")
+{
+ // A file outside the allowed root should be rejected by the policy
+ ScopedTemporaryDirectory AllowedRoot;
+ ScopedTemporaryDirectory OutsideDir;
+
+ auto OutsidePath = OutsideDir.Path() / "secret.dat";
+ {
+ IoBuffer Buf = IoBufferBuilder::MakeCloneFromMemory(MakeMemoryView("secret"));
+ WriteFile(OutsidePath, Buf);
+ }
+
+ // Create file-backed compressed attachment from outside root
+ CompressedBuffer Comp =
+ CompressedBuffer::Compress(SharedBuffer::MakeView(MakeMemoryView("secret")), OodleCompressor::NotSet, OodleCompressionLevel::None);
+ IoHash Hash = Comp.DecodeRawHash();
+ {
+ IoBuffer Buf = Comp.GetCompressed().Flatten().AsIoBuffer();
+ WriteFile(OutsidePath, Buf);
+ }
+
+ CbAttachment Attach{CompressedBuffer::FromCompressedNoValidate(IoBufferBuilder::MakeFromFile(OutsidePath)), Hash};
+
+ CbObjectWriter Cbo;
+ Cbo.AddAttachment("data", Attach);
+
+ CbPackage Pkg;
+ Pkg.AddAttachment(Attach);
+ Pkg.SetObject(Cbo.Save());
+
+ IoBuffer Payload = FormatPackageMessageBuffer(Pkg, FormatFlags::kAllowLocalReferences).Flatten().AsIoBuffer();
+
+ // Policy rooted at AllowedRoot should reject the file in OutsideDir
+ struct TestPolicy : public ILocalRefPolicy
+ {
+ std::string Root;
+ void ValidatePath(const std::filesystem::path& Path) const override
+ {
+ std::string CanonicalFile = std::filesystem::weakly_canonical(Path).string();
+ if (CanonicalFile.size() < Root.size() || CanonicalFile.compare(0, Root.size(), Root) != 0)
+ {
+ throw std::invalid_argument("path outside root");
+ }
+ }
+ } Policy;
+ Policy.Root = std::filesystem::weakly_canonical(AllowedRoot.Path()).string();
+
+ CHECK_THROWS_AS(ParsePackageMessage(Payload, {}, ParseFlags::kAllowLocalReferences, &Policy), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.LocalRefPolicy.PathInsideRoot")
+{
+ // A file inside the allowed root should be accepted by the policy
+ ScopedTemporaryDirectory TempRoot;
+
+ auto FilePath = TempRoot.Path() / "data.dat";
+
+ CompressedBuffer Comp =
+ CompressedBuffer::Compress(SharedBuffer::MakeView(MakeMemoryView("hello")), OodleCompressor::NotSet, OodleCompressionLevel::None);
+ IoHash Hash = Comp.DecodeRawHash();
+ {
+ IoBuffer Buf = Comp.GetCompressed().Flatten().AsIoBuffer();
+ WriteFile(FilePath, Buf);
+ }
+
+ CbAttachment Attach{CompressedBuffer::FromCompressedNoValidate(IoBufferBuilder::MakeFromFile(FilePath)), Hash};
+
+ CbObjectWriter Cbo;
+ Cbo.AddAttachment("data", Attach);
+
+ CbPackage Pkg;
+ Pkg.AddAttachment(Attach);
+ Pkg.SetObject(Cbo.Save());
+
+ IoBuffer Payload = FormatPackageMessageBuffer(Pkg, FormatFlags::kAllowLocalReferences).Flatten().AsIoBuffer();
+
+ struct TestPolicy : public ILocalRefPolicy
+ {
+ std::string Root;
+ void ValidatePath(const std::filesystem::path& Path) const override
+ {
+ std::string CanonicalFile = std::filesystem::weakly_canonical(Path).string();
+ if (CanonicalFile.size() < Root.size() || CanonicalFile.compare(0, Root.size(), Root) != 0)
+ {
+ throw std::invalid_argument("path outside root");
+ }
+ }
+ } Policy;
+ Policy.Root = std::filesystem::weakly_canonical(TempRoot.Path()).string();
+
+ CbPackage Result = ParsePackageMessage(Payload, {}, ParseFlags::kAllowLocalReferences, &Policy);
+ CHECK(Result.GetObject());
+ CHECK(Result.GetAttachments().size() == 1);
+}
+
+TEST_CASE("CbPackage.LocalRefPolicy.PathTraversal")
+{
+ // A file path containing ".." that resolves outside root should be rejected
+ ScopedTemporaryDirectory TempRoot;
+ ScopedTemporaryDirectory OutsideDir;
+
+ auto OutsidePath = OutsideDir.Path() / "evil.dat";
+
+ CompressedBuffer Comp =
+ CompressedBuffer::Compress(SharedBuffer::MakeView(MakeMemoryView("evil")), OodleCompressor::NotSet, OodleCompressionLevel::None);
+ IoHash Hash = Comp.DecodeRawHash();
+ {
+ IoBuffer Buf = Comp.GetCompressed().Flatten().AsIoBuffer();
+ WriteFile(OutsidePath, Buf);
+ }
+
+ CbAttachment Attach{CompressedBuffer::FromCompressedNoValidate(IoBufferBuilder::MakeFromFile(OutsidePath)), Hash};
+
+ CbObjectWriter Cbo;
+ Cbo.AddAttachment("data", Attach);
+
+ CbPackage Pkg;
+ Pkg.AddAttachment(Attach);
+ Pkg.SetObject(Cbo.Save());
+
+ IoBuffer Payload = FormatPackageMessageBuffer(Pkg, FormatFlags::kAllowLocalReferences).Flatten().AsIoBuffer();
+
+ struct TestPolicy : public ILocalRefPolicy
+ {
+ std::string Root;
+ void ValidatePath(const std::filesystem::path& Path) const override
+ {
+ std::string CanonicalFile = std::filesystem::weakly_canonical(Path).string();
+ if (CanonicalFile.size() < Root.size() || CanonicalFile.compare(0, Root.size(), Root) != 0)
+ {
+ throw std::invalid_argument("path outside root");
+ }
+ }
+ } Policy;
+ // Root is TempRoot, but the file lives in OutsideDir
+ Policy.Root = std::filesystem::weakly_canonical(TempRoot.Path()).string();
+
+ CHECK_THROWS_AS(ParsePackageMessage(Payload, {}, ParseFlags::kAllowLocalReferences, &Policy), std::invalid_argument);
+}
+
+TEST_CASE("CbPackage.LocalRefPolicy.NoPolicyFailClosed")
+{
+ // When local refs are allowed but no policy is provided, file-path refs should be rejected
+ ScopedTemporaryDirectory TempDir;
+
+ auto FilePath = TempDir.Path() / "data.dat";
+
+ CompressedBuffer Comp =
+ CompressedBuffer::Compress(SharedBuffer::MakeView(MakeMemoryView("data")), OodleCompressor::NotSet, OodleCompressionLevel::None);
+ IoHash Hash = Comp.DecodeRawHash();
+ {
+ IoBuffer Buf = Comp.GetCompressed().Flatten().AsIoBuffer();
+ WriteFile(FilePath, Buf);
+ }
+
+ CbAttachment Attach{CompressedBuffer::FromCompressedNoValidate(IoBufferBuilder::MakeFromFile(FilePath)), Hash};
+
+ CbObjectWriter Cbo;
+ Cbo.AddAttachment("data", Attach);
+
+ CbPackage Pkg;
+ Pkg.AddAttachment(Attach);
+ Pkg.SetObject(Cbo.Save());
+
+ IoBuffer Payload = FormatPackageMessageBuffer(Pkg, FormatFlags::kAllowLocalReferences).Flatten().AsIoBuffer();
+
+ // kAllowLocalReferences but nullptr policy => fail-closed
+ CHECK_THROWS_AS(ParsePackageMessage(Payload, {}, ParseFlags::kAllowLocalReferences, nullptr), std::invalid_argument);
}
TEST_SUITE_END();
diff --git a/src/zenhttp/servers/httpasio.cpp b/src/zenhttp/servers/httpasio.cpp
index a2cae8762..6cda84875 100644
--- a/src/zenhttp/servers/httpasio.cpp
+++ b/src/zenhttp/servers/httpasio.cpp
@@ -1275,7 +1275,9 @@ HttpServerConnectionT<SocketType>::HandleRequest()
asio::buffer(ResponseStr->data(), ResponseStr->size()),
asio::bind_executor(
m_Strand,
- [Conn = AsSharedPtr(), WsHandler, OwnedResponse = ResponseStr](const asio::error_code& Ec, std::size_t) {
+ [Conn = AsSharedPtr(), WsHandler, OwnedResponse = ResponseStr, PrefixLen = Service->UriPrefixLength()](
+ const asio::error_code& Ec,
+ std::size_t) {
if (Ec)
{
ZEN_WARN("WebSocket 101 send failed: {}", Ec.message());
@@ -1287,7 +1289,9 @@ HttpServerConnectionT<SocketType>::HandleRequest()
Ref<WsConnType> WsConn(new WsConnType(std::move(Conn->m_Socket), *WsHandler, Conn->m_Server.m_HttpServer));
Ref<WebSocketConnection> WsConnRef(WsConn.Get());
- WsHandler->OnWebSocketOpen(std::move(WsConnRef));
+ std::string_view FullUrl = Conn->m_RequestData.Url();
+ std::string_view RelativeUri = FullUrl.substr(std::min(PrefixLen, static_cast<int>(FullUrl.size())));
+ WsHandler->OnWebSocketOpen(std::move(WsConnRef), RelativeUri);
WsConn->Start();
}));
@@ -1330,14 +1334,36 @@ HttpServerConnectionT<SocketType>::HandleRequest()
{
auto RemoteEndpoint = m_Socket->remote_endpoint();
IsLocalConnection = m_Socket->local_endpoint().address() == RemoteEndpoint.address();
- RemoteAddress = RemoteEndpoint.address().to_string();
+ auto Addr = RemoteEndpoint.address();
+ RemoteAddress = Addr.to_string();
+ if (Addr.is_v4())
+ {
+ auto Bytes = Addr.to_v4().to_bytes();
+ m_Server.m_HttpServer->MarkClientAddress(Bytes.data(), Bytes.size());
+ }
+ else
+ {
+ auto Bytes = Addr.to_v6().to_bytes();
+ m_Server.m_HttpServer->MarkClientAddress(Bytes.data(), Bytes.size());
+ }
}
#if ZEN_USE_OPENSSL
else if constexpr (std::is_same_v<SocketType, SslSocket>)
{
auto RemoteEndpoint = m_Socket->lowest_layer().remote_endpoint();
IsLocalConnection = m_Socket->lowest_layer().local_endpoint().address() == RemoteEndpoint.address();
- RemoteAddress = RemoteEndpoint.address().to_string();
+ auto Addr = RemoteEndpoint.address();
+ RemoteAddress = Addr.to_string();
+ if (Addr.is_v4())
+ {
+ auto Bytes = Addr.to_v4().to_bytes();
+ m_Server.m_HttpServer->MarkClientAddress(Bytes.data(), Bytes.size());
+ }
+ else
+ {
+ auto Bytes = Addr.to_v6().to_bytes();
+ m_Server.m_HttpServer->MarkClientAddress(Bytes.data(), Bytes.size());
+ }
}
#endif
else
@@ -1345,6 +1371,8 @@ HttpServerConnectionT<SocketType>::HandleRequest()
RemoteAddress = "unix";
}
+ m_Server.m_HttpServer->MarkSessionId(m_RequestData.SessionId());
+
HttpAsioServerRequest Request(m_RequestData,
*Service,
m_RequestData.Body(),
diff --git a/src/zenhttp/servers/httpsys.cpp b/src/zenhttp/servers/httpsys.cpp
index 9fe9a2254..1b722940d 100644
--- a/src/zenhttp/servers/httpsys.cpp
+++ b/src/zenhttp/servers/httpsys.cpp
@@ -2020,6 +2020,23 @@ HttpSysTransaction::InvokeRequestHandler(HttpService& Service, IoBuffer Payload)
m_HttpServer.MarkRequest();
+ // Track distinct client addresses
+ {
+ const SOCKADDR* SockAddr = HttpRequest()->Address.pRemoteAddress;
+ if (SockAddr->sa_family == AF_INET)
+ {
+ const SOCKADDR_IN* V4 = reinterpret_cast<const SOCKADDR_IN*>(SockAddr);
+ m_HttpServer.MarkClientAddress(&V4->sin_addr, sizeof(V4->sin_addr));
+ }
+ else if (SockAddr->sa_family == AF_INET6)
+ {
+ const SOCKADDR_IN6* V6 = reinterpret_cast<const SOCKADDR_IN6*>(SockAddr);
+ m_HttpServer.MarkClientAddress(&V6->sin6_addr, sizeof(V6->sin6_addr));
+ }
+ }
+
+ m_HttpServer.MarkSessionId(ThisRequest.SessionId());
+
// Default request handling
# if ZEN_WITH_OTEL
@@ -2578,7 +2595,14 @@ InitialRequestHandler::HandleCompletion(ULONG IoResult, ULONG_PTR NumberOfBytesT
&Transaction().Server()));
Ref<WebSocketConnection> WsConnRef(WsConn.Get());
- WsHandler->OnWebSocketOpen(std::move(WsConnRef));
+ ExtendableStringBuilder<128> UrlUtf8;
+ WideToUtf8({(wchar_t*)HttpReq->CookedUrl.pAbsPath,
+ gsl::narrow<size_t>(HttpReq->CookedUrl.AbsPathLength / sizeof(wchar_t))},
+ UrlUtf8);
+ int PrefixLen = Service->UriPrefixLength();
+ std::string_view RelativeUri{UrlUtf8.ToView()};
+ RelativeUri.remove_prefix(std::min(PrefixLen, static_cast<int>(RelativeUri.size())));
+ WsHandler->OnWebSocketOpen(std::move(WsConnRef), RelativeUri);
WsConn->Start();
return nullptr;
diff --git a/src/zenhttp/servers/wstest.cpp b/src/zenhttp/servers/wstest.cpp
index 59c46a418..363c478ae 100644
--- a/src/zenhttp/servers/wstest.cpp
+++ b/src/zenhttp/servers/wstest.cpp
@@ -335,8 +335,9 @@ namespace {
}
// IWebSocketHandler
- void OnWebSocketOpen(Ref<WebSocketConnection> Connection) override
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override
{
+ ZEN_UNUSED(RelativeUri);
m_OpenCount.fetch_add(1);
m_ConnectionsLock.WithExclusiveLock([&] { m_Connections.push_back(Connection); });
diff --git a/src/zenhttp/xmake.lua b/src/zenhttp/xmake.lua
index b4c65ea96..7b050ae35 100644
--- a/src/zenhttp/xmake.lua
+++ b/src/zenhttp/xmake.lua
@@ -9,12 +9,7 @@ target('zenhttp')
add_files("servers/wshttpsys.cpp", {unity_ignored=true})
add_includedirs("include", {public=true})
add_deps("zencore", "zentelemetry", "transport-sdk", "asio")
- if has_config("zencpr") then
- add_deps("cpr")
- else
- remove_files("clients/httpclientcpr.cpp")
- end
- add_packages("http_parser", "json11")
+ add_packages("http_parser", "json11", "libcurl")
add_options("httpsys")
if is_plat("linux", "macosx") then
diff --git a/src/zennomad/nomadprocess.cpp b/src/zennomad/nomadprocess.cpp
index 1ae968fb7..deecdef05 100644
--- a/src/zennomad/nomadprocess.cpp
+++ b/src/zennomad/nomadprocess.cpp
@@ -37,7 +37,7 @@ struct NomadProcess::Impl
}
CreateProcOptions Options;
- Options.Flags |= CreateProcOptions::Flag_Windows_NewProcessGroup;
+ Options.Flags |= CreateProcOptions::Flag_NewProcessGroup;
CreateProcResult Result = CreateProc("nomad" ZEN_EXE_SUFFIX_LITERAL, "nomad" ZEN_EXE_SUFFIX_LITERAL " agent -dev", Options);
diff --git a/src/zenremotestore/builds/buildstorageoperations.cpp b/src/zenremotestore/builds/buildstorageoperations.cpp
index a04063c4c..ca226444a 100644
--- a/src/zenremotestore/builds/buildstorageoperations.cpp
+++ b/src/zenremotestore/builds/buildstorageoperations.cpp
@@ -1149,8 +1149,7 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
WriteScavengedSequenceToCache(ScavengeRootPath, ScavengedContent, ScavengeOp);
- WritePartsComplete++;
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -1252,10 +1251,10 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
ScavengedLookups,
ScavengedPaths,
WriteCache);
- WritePartsComplete++;
+ bool WritePartsDone = WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount;
if (!m_AbortFlag)
{
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsDone)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -1334,9 +1333,7 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
Ec.message());
}
- WritePartsComplete++;
-
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -1389,25 +1386,20 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
BlockRangeStartIndex,
RangeCount,
ExistsResult,
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
[this,
&RemoteChunkIndexNeedsCopyFromSourceFlags,
&SequenceIndexChunksLeftToWriteCounters,
&WritePartsComplete,
&WriteCache,
&Work,
- TotalRequestCount,
TotalPartWriteCount,
- &FilteredDownloadedBytesPerSecond,
&FilteredWrittenBytesPerSecond,
&PartialBlocks](IoBuffer&& InMemoryBuffer,
const std::filesystem::path& OnDiskPath,
size_t BlockRangeStartIndex,
std::span<const std::pair<uint64_t, uint64_t>> OffsetAndLengths) {
- if (m_DownloadStats.RequestsCompleteCount == TotalRequestCount)
- {
- FilteredDownloadedBytesPerSecond.Stop();
- }
-
if (!m_AbortFlag)
{
Work.ScheduleWork(
@@ -1483,8 +1475,7 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
fmt::format("Partial block {} is malformed", BlockDescription.BlockHash));
}
- WritePartsComplete++;
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -1571,8 +1562,7 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
uint64_t BlockSize = BlockBuffer.GetSize();
m_DownloadStats.DownloadedBlockCount++;
m_DownloadStats.DownloadedBlockByteCount += BlockSize;
- m_DownloadStats.RequestsCompleteCount++;
- if (m_DownloadStats.RequestsCompleteCount == TotalRequestCount)
+ if (m_DownloadStats.RequestsCompleteCount.fetch_add(1) + 1 == TotalRequestCount)
{
FilteredDownloadedBytesPerSecond.Stop();
}
@@ -1683,9 +1673,7 @@ BuildsOperationUpdateFolder::Execute(FolderContent& OutLocalFolderState)
}
}
- WritePartsComplete++;
-
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -2987,8 +2975,7 @@ BuildsOperationUpdateFolder::WriteLooseChunk(const uint32_t RemoteChunkInd
ExistingCompressedChunkPath = FindDownloadedChunk(ChunkHash);
if (!ExistingCompressedChunkPath.empty())
{
- m_DownloadStats.RequestsCompleteCount++;
- if (m_DownloadStats.RequestsCompleteCount == TotalRequestCount)
+ if (m_DownloadStats.RequestsCompleteCount.fetch_add(1) + 1 == TotalRequestCount)
{
FilteredDownloadedBytesPerSecond.Stop();
}
@@ -3027,11 +3014,11 @@ BuildsOperationUpdateFolder::WriteLooseChunk(const uint32_t RemoteChunkInd
bool NeedHashVerify =
WriteCompressedChunkToCache(ChunkHash, ChunkTargetPtrs, WriteCache, std::move(CompressedPart));
- WritePartsComplete++;
+ bool WritePartsDone = WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount;
if (!AbortFlag)
{
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsDone)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -3085,6 +3072,8 @@ BuildsOperationUpdateFolder::WriteLooseChunk(const uint32_t RemoteChunkInd
DownloadBuildBlob(RemoteChunkIndex,
ExistsResult,
Work,
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
[this,
&ExistsResult,
SequenceIndexChunksLeftToWriteCounters,
@@ -3092,15 +3081,9 @@ BuildsOperationUpdateFolder::WriteLooseChunk(const uint32_t RemoteChunkInd
&Work,
&WritePartsComplete,
TotalPartWriteCount,
- TotalRequestCount,
RemoteChunkIndex,
- &FilteredDownloadedBytesPerSecond,
&FilteredWrittenBytesPerSecond,
ChunkTargetPtrs = std::move(ChunkTargetPtrs)](IoBuffer&& Payload) mutable {
- if (m_DownloadStats.RequestsCompleteCount == TotalRequestCount)
- {
- FilteredDownloadedBytesPerSecond.Stop();
- }
IoBufferFileReference FileRef;
bool EnableBacklog = Payload.GetFileReference(FileRef);
AsyncWriteDownloadedChunk(m_Options.ZenFolderPath,
@@ -3125,6 +3108,8 @@ void
BuildsOperationUpdateFolder::DownloadBuildBlob(uint32_t RemoteChunkIndex,
const BlobsExistsResult& ExistsResult,
ParallelWork& Work,
+ uint64_t TotalRequestCount,
+ FilteredRate& FilteredDownloadedBytesPerSecond,
std::function<void(IoBuffer&& Payload)>&& OnDownloaded)
{
const IoHash& ChunkHash = m_RemoteContent.ChunkedContent.ChunkHashes[RemoteChunkIndex];
@@ -3140,37 +3125,48 @@ BuildsOperationUpdateFolder::DownloadBuildBlob(uint32_t RemoteChunkInde
uint64_t BlobSize = BuildBlob.GetSize();
m_DownloadStats.DownloadedChunkCount++;
m_DownloadStats.DownloadedChunkByteCount += BlobSize;
- m_DownloadStats.RequestsCompleteCount++;
+ if (m_DownloadStats.RequestsCompleteCount.fetch_add(1) + 1 == TotalRequestCount)
+ {
+ FilteredDownloadedBytesPerSecond.Stop();
+ }
OnDownloaded(std::move(BuildBlob));
}
else
{
if (m_RemoteContent.ChunkedContent.ChunkRawSizes[RemoteChunkIndex] >= m_Options.LargeAttachmentSize)
{
- DownloadLargeBlob(
- *m_Storage.BuildStorage,
- m_TempDownloadFolderPath,
- m_BuildId,
- ChunkHash,
- m_Options.PreferredMultipartChunkSize,
- Work,
- m_NetworkPool,
- m_DownloadStats.DownloadedChunkByteCount,
- m_DownloadStats.MultipartAttachmentCount,
- [this, &Work, ChunkHash, RemoteChunkIndex, OnDownloaded = std::move(OnDownloaded)](IoBuffer&& Payload) mutable {
- m_DownloadStats.DownloadedChunkCount++;
- m_DownloadStats.RequestsCompleteCount++;
+ DownloadLargeBlob(*m_Storage.BuildStorage,
+ m_TempDownloadFolderPath,
+ m_BuildId,
+ ChunkHash,
+ m_Options.PreferredMultipartChunkSize,
+ Work,
+ m_NetworkPool,
+ m_DownloadStats.DownloadedChunkByteCount,
+ m_DownloadStats.MultipartAttachmentCount,
+ [this,
+ &Work,
+ &FilteredDownloadedBytesPerSecond,
+ ChunkHash,
+ RemoteChunkIndex,
+ TotalRequestCount,
+ OnDownloaded = std::move(OnDownloaded)](IoBuffer&& Payload) mutable {
+ m_DownloadStats.DownloadedChunkCount++;
+ if (m_DownloadStats.RequestsCompleteCount.fetch_add(1) + 1 == TotalRequestCount)
+ {
+ FilteredDownloadedBytesPerSecond.Stop();
+ }
- if (Payload && m_Storage.CacheStorage && m_Options.PopulateCache)
- {
- m_Storage.CacheStorage->PutBuildBlob(m_BuildId,
- ChunkHash,
- ZenContentType::kCompressedBinary,
- CompositeBuffer(SharedBuffer(Payload)));
- }
+ if (Payload && m_Storage.CacheStorage && m_Options.PopulateCache)
+ {
+ m_Storage.CacheStorage->PutBuildBlob(m_BuildId,
+ ChunkHash,
+ ZenContentType::kCompressedBinary,
+ CompositeBuffer(SharedBuffer(Payload)));
+ }
- OnDownloaded(std::move(Payload));
- });
+ OnDownloaded(std::move(Payload));
+ });
}
else
{
@@ -3193,7 +3189,10 @@ BuildsOperationUpdateFolder::DownloadBuildBlob(uint32_t RemoteChunkInde
uint64_t BlobSize = BuildBlob.GetSize();
m_DownloadStats.DownloadedChunkCount++;
m_DownloadStats.DownloadedChunkByteCount += BlobSize;
- m_DownloadStats.RequestsCompleteCount++;
+ if (m_DownloadStats.RequestsCompleteCount.fetch_add(1) + 1 == TotalRequestCount)
+ {
+ FilteredDownloadedBytesPerSecond.Stop();
+ }
OnDownloaded(std::move(BuildBlob));
}
@@ -3208,6 +3207,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
size_t BlockRangeStartIndex,
size_t BlockRangeCount,
const BlobsExistsResult& ExistsResult,
+ uint64_t TotalRequestCount,
+ FilteredRate& FilteredDownloadedBytesPerSecond,
std::function<void(IoBuffer&& InMemoryBuffer,
const std::filesystem::path& OnDiskPath,
size_t BlockRangeStartIndex,
@@ -3222,6 +3223,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
IoBuffer&& BlockRangeBuffer,
size_t BlockRangeStartIndex,
std::span<const std::pair<uint64_t, uint64_t>> BlockOffsetAndLengths,
+ uint64_t TotalRequestCount,
+ FilteredRate& FilteredDownloadedBytesPerSecond,
const std::function<void(IoBuffer && InMemoryBuffer,
const std::filesystem::path& OnDiskPath,
size_t BlockRangeStartIndex,
@@ -3229,7 +3232,11 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
uint64_t BlockRangeBufferSize = BlockRangeBuffer.GetSize();
m_DownloadStats.DownloadedBlockCount++;
m_DownloadStats.DownloadedBlockByteCount += BlockRangeBufferSize;
- m_DownloadStats.RequestsCompleteCount += BlockOffsetAndLengths.size();
+ if (m_DownloadStats.RequestsCompleteCount.fetch_add(BlockOffsetAndLengths.size()) + BlockOffsetAndLengths.size() ==
+ TotalRequestCount)
+ {
+ FilteredDownloadedBytesPerSecond.Stop();
+ }
std::filesystem::path BlockChunkPath;
@@ -3337,6 +3344,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
std::move(PayloadBuffer),
SubRangeStartIndex,
std::vector<std::pair<uint64_t, uint64_t>>{std::make_pair(0u, SubRange.second)},
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
OnDownloaded);
SubRangeCountComplete += SubRangeCount;
continue;
@@ -3361,6 +3370,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
std::move(RangeBuffers.PayloadBuffer),
SubRangeStartIndex,
RangesSpan.subspan(SubRangeCountComplete, SubRangeCount),
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
OnDownloaded);
SubRangeCountComplete += SubRangeCount;
continue;
@@ -3371,6 +3382,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
std::move(RangeBuffers.PayloadBuffer),
SubRangeStartIndex,
RangeBuffers.Ranges,
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
OnDownloaded);
SubRangeCountComplete += SubRangeCount;
continue;
@@ -3413,6 +3426,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
std::move(RangeBuffers.PayloadBuffer),
SubRangeStartIndex,
RangesSpan.subspan(SubRangeCountComplete, SubRangeCount),
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
OnDownloaded);
}
else
@@ -3428,6 +3443,8 @@ BuildsOperationUpdateFolder::DownloadPartialBlock(
std::move(RangeBuffers.PayloadBuffer),
SubRangeStartIndex,
RangeBuffers.Ranges,
+ TotalRequestCount,
+ FilteredDownloadedBytesPerSecond,
OnDownloaded);
}
}
@@ -4244,8 +4261,7 @@ BuildsOperationUpdateFolder::AsyncWriteDownloadedChunk(const std::filesystem::pa
bool NeedHashVerify = WriteCompressedChunkToCache(ChunkHash, ChunkTargetPtrs, WriteCache, std::move(CompressedPart));
if (!m_AbortFlag)
{
- WritePartsComplete++;
- if (WritePartsComplete == TotalPartWriteCount)
+ if (WritePartsComplete.fetch_add(1) + 1 == TotalPartWriteCount)
{
FilteredWrittenBytesPerSecond.Stop();
}
@@ -6111,8 +6127,7 @@ BuildsOperationUploadFolder::UploadPartBlobs(const ChunkedFolderContent& Co
TempUploadStats.BlockCount++;
- UploadedBlockCount++;
- if (UploadedBlockCount == UploadBlockCount && UploadedChunkCount == UploadChunkCount)
+ if (UploadedBlockCount.fetch_add(1) + 1 == UploadBlockCount && UploadedChunkCount == UploadChunkCount)
{
FilteredUploadedBytesPerSecond.Stop();
}
@@ -6192,8 +6207,8 @@ BuildsOperationUploadFolder::UploadPartBlobs(const ChunkedFolderContent& Co
if (IsComplete)
{
TempUploadStats.ChunkCount++;
- UploadedChunkCount++;
- if (UploadedBlockCount == UploadBlockCount && UploadedChunkCount == UploadChunkCount)
+ if (UploadedChunkCount.fetch_add(1) + 1 == UploadChunkCount &&
+ UploadedBlockCount == UploadBlockCount)
{
FilteredUploadedBytesPerSecond.Stop();
}
@@ -6227,8 +6242,7 @@ BuildsOperationUploadFolder::UploadPartBlobs(const ChunkedFolderContent& Co
TempUploadStats.ChunkCount++;
UploadedCompressedChunkSize += Payload.GetSize();
UploadedRawChunkSize += RawSize;
- UploadedChunkCount++;
- if (UploadedChunkCount == UploadChunkCount)
+ if (UploadedChunkCount.fetch_add(1) + 1 == UploadChunkCount && UploadedBlockCount == UploadBlockCount)
{
FilteredUploadedBytesPerSecond.Stop();
}
@@ -6237,8 +6251,6 @@ BuildsOperationUploadFolder::UploadPartBlobs(const ChunkedFolderContent& Co
});
};
- std::vector<size_t> GenerateBlockIndexes;
-
std::atomic<uint64_t> GeneratedBlockCount = 0;
std::atomic<uint64_t> GeneratedBlockByteCount = 0;
@@ -6260,9 +6272,9 @@ BuildsOperationUploadFolder::UploadPartBlobs(const ChunkedFolderContent& Co
&Lookup,
&NewBlocks,
&NewBlockChunks,
- &GenerateBlockIndexes,
&GeneratedBlockCount,
&GeneratedBlockByteCount,
+ GenerateBlockCount = BlockIndexes.size(),
&AsyncUploadBlock,
&QueuedPendingInMemoryBlocksForUpload](std::atomic<bool>&) {
if (!m_AbortFlag)
@@ -6293,8 +6305,7 @@ BuildsOperationUploadFolder::UploadPartBlobs(const ChunkedFolderContent& Co
}
GeneratedBlockByteCount += NewBlocks.BlockSizes[BlockIndex];
- GeneratedBlockCount++;
- if (GeneratedBlockCount == GenerateBlockIndexes.size())
+ if (GeneratedBlockCount.fetch_add(1) + 1 == GenerateBlockCount)
{
FilteredGenerateBlockBytesPerSecond.Stop();
}
@@ -7005,8 +7016,7 @@ BuildsOperationPrimeCache::Execute()
CompositeBuffer(SharedBuffer(Payload)));
}
}
- CompletedDownloadCount++;
- if (CompletedDownloadCount == BlobCount)
+ if (CompletedDownloadCount.fetch_add(1) + 1 == BlobCount)
{
FilteredDownloadedBytesPerSecond.Stop();
}
@@ -7029,8 +7039,7 @@ BuildsOperationPrimeCache::Execute()
CompositeBuffer(SharedBuffer(std::move(Payload))));
}
}
- CompletedDownloadCount++;
- if (CompletedDownloadCount == BlobCount)
+ if (CompletedDownloadCount.fetch_add(1) + 1 == BlobCount)
{
FilteredDownloadedBytesPerSecond.Stop();
}
diff --git a/src/zenremotestore/builds/jupiterbuildstorage.cpp b/src/zenremotestore/builds/jupiterbuildstorage.cpp
index c3f7b9e71..d837ce07f 100644
--- a/src/zenremotestore/builds/jupiterbuildstorage.cpp
+++ b/src/zenremotestore/builds/jupiterbuildstorage.cpp
@@ -14,7 +14,7 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <tsl/robin_map.h>
ZEN_THIRD_PARTY_INCLUDES_END
-#include <regex>
+#include <string_view>
namespace zen {
@@ -263,7 +263,7 @@ public:
std::vector<std::function<void()>> WorkList;
for (auto& WorkItem : WorkItems)
{
- WorkList.emplace_back([this, WorkItem = std::move(WorkItem), OnSentBytes]() {
+ WorkList.emplace_back([this, WorkItem = std::move(WorkItem), OnSentBytes = std::move(OnSentBytes)]() {
Stopwatch ExecutionTimer;
auto _ = MakeGuard([&]() { m_Stats.TotalExecutionTimeUs += ExecutionTimer.GetElapsedTimeUs(); });
bool IsComplete = false;
@@ -444,11 +444,13 @@ public:
virtual bool GetExtendedStatistics(ExtendedStatistics& OutStats) override
{
- OutStats.ReceivedBytesPerSource.reserve(m_ReceivedBytesPerSource.size());
- for (auto& It : m_ReceivedBytesPerSource)
- {
- OutStats.ReceivedBytesPerSource.insert_or_assign(It.first, m_SourceBytes[It.second]);
- }
+ m_SourceLock.WithSharedLock([this, &OutStats]() {
+ OutStats.ReceivedBytesPerSource.reserve(m_ReceivedBytesPerSource.size());
+ for (auto& It : m_ReceivedBytesPerSource)
+ {
+ OutStats.ReceivedBytesPerSource.insert_or_assign(It.first, m_SourceBytes[It.second].load(std::memory_order_relaxed));
+ }
+ });
return true;
}
@@ -521,15 +523,29 @@ private:
}
if (!Result.Source.empty())
{
- if (tsl::robin_map<std::string, uint32_t>::const_iterator It = m_ReceivedBytesPerSource.find(Result.Source);
- It != m_ReceivedBytesPerSource.end())
- {
- m_SourceBytes[It->second] += Result.ReceivedBytes;
- }
- else
+ if (!m_SourceLock.WithSharedLock([&]() {
+ if (tsl::robin_map<std::string, uint32_t>::const_iterator It = m_ReceivedBytesPerSource.find(Result.Source);
+ It != m_ReceivedBytesPerSource.end())
+ {
+ m_SourceBytes[It->second] += Result.ReceivedBytes;
+ return true;
+ }
+ return false;
+ }))
{
- m_ReceivedBytesPerSource.insert_or_assign(Result.Source, m_SourceBytes.size());
- m_SourceBytes.push_back(Result.ReceivedBytes);
+ m_SourceLock.WithExclusiveLock([&]() {
+ if (tsl::robin_map<std::string, uint32_t>::const_iterator It = m_ReceivedBytesPerSource.find(Result.Source);
+ It != m_ReceivedBytesPerSource.end())
+ {
+ m_SourceBytes[It->second] += Result.ReceivedBytes;
+ }
+ else if (m_SourceCount < MaxSourceCount)
+ {
+ size_t Index = m_SourceCount++;
+ m_ReceivedBytesPerSource.insert_or_assign(Result.Source, Index);
+ m_SourceBytes[Index] += Result.ReceivedBytes;
+ }
+ });
}
}
}
@@ -540,8 +556,11 @@ private:
const std::string m_Bucket;
const std::filesystem::path m_TempFolderPath;
- tsl::robin_map<std::string, uint32_t> m_ReceivedBytesPerSource;
- std::vector<uint64_t> m_SourceBytes;
+ RwLock m_SourceLock;
+ tsl::robin_map<std::string, uint32_t> m_ReceivedBytesPerSource;
+ static constexpr size_t MaxSourceCount = 8u;
+ std::array<std::atomic<uint64_t>, MaxSourceCount> m_SourceBytes;
+ size_t m_SourceCount = 0;
};
std::unique_ptr<BuildStorageBase>
@@ -572,35 +591,135 @@ ParseBuildStorageUrl(std::string_view InUrl,
Url.erase(ApiString, ExtendedApiString.length());
}
- const std::string ArtifactURLRegExString = R"((http[s]?:\/\/.*?)\/(.*?)\/(.*?)\/(.*))";
- const std::regex ArtifactURLRegEx(ArtifactURLRegExString, std::regex::ECMAScript | std::regex::icase);
- std::match_results<std::string_view::const_iterator> MatchResults;
- std::string_view UrlToParse(Url);
- if (regex_match(begin(UrlToParse), end(UrlToParse), MatchResults, ArtifactURLRegEx) && MatchResults.size() == 5)
- {
- auto GetMatch = [&MatchResults](uint32_t Index) -> std::string_view {
- ZEN_ASSERT(Index < MatchResults.size());
+ // Parse URL of the form: http[s]://host/namespace/bucket/buildid
+ std::string_view Remaining(Url);
- const auto& Match = MatchResults[Index];
+ // Find the end of the scheme (e.g. "http://" or "https://")
+ size_t SchemeEnd = Remaining.find("://");
+ if (SchemeEnd == std::string_view::npos)
+ {
+ return false;
+ }
+ SchemeEnd += 3; // skip past "://"
- return std::string_view(&*Match.first, Match.second - Match.first);
- };
+ // Find the first '/' after the host
+ size_t HostEnd = Remaining.find('/', SchemeEnd);
+ if (HostEnd == std::string_view::npos)
+ {
+ return false;
+ }
- const std::string_view Host = GetMatch(1);
- const std::string_view Namespace = GetMatch(2);
- const std::string_view Bucket = GetMatch(3);
- const std::string_view BuildId = GetMatch(4);
+ // Find the '/' after namespace
+ size_t NamespaceEnd = Remaining.find('/', HostEnd + 1);
+ if (NamespaceEnd == std::string_view::npos)
+ {
+ return false;
+ }
- OutHost = Host;
- OutNamespace = Namespace;
- OutBucket = Bucket;
- OutBuildId = BuildId;
- return true;
+ // Find the '/' after bucket
+ size_t BucketEnd = Remaining.find('/', NamespaceEnd + 1);
+ if (BucketEnd == std::string_view::npos)
+ {
+ return false;
}
- else
+
+ // BuildId must be non-empty
+ if (BucketEnd + 1 >= Remaining.size())
{
return false;
}
+
+ OutHost = Remaining.substr(0, HostEnd);
+ OutNamespace = Remaining.substr(HostEnd + 1, NamespaceEnd - HostEnd - 1);
+ OutBucket = Remaining.substr(NamespaceEnd + 1, BucketEnd - NamespaceEnd - 1);
+ OutBuildId = Remaining.substr(BucketEnd + 1);
+ return true;
}
} // namespace zen
+
+#if ZEN_WITH_TESTS
+
+# include <zencore/testing.h>
+
+namespace zen {
+
+void
+jupiterbuildstorage_forcelink()
+{
+}
+
+} // namespace zen
+
+TEST_SUITE_BEGIN("remotestore.jupiterbuildstorage");
+
+TEST_CASE("ParseBuildStorageUrl.ValidUrl")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ bool Result =
+ zen::ParseBuildStorageUrl("https://horde.devtools.epicgames.com/mynamespace/mybucket/mybuildid", Host, Namespace, Bucket, BuildId);
+ CHECK(Result);
+ CHECK(Host == "https://horde.devtools.epicgames.com");
+ CHECK(Namespace == "mynamespace");
+ CHECK(Bucket == "mybucket");
+ CHECK(BuildId == "mybuildid");
+}
+
+TEST_CASE("ParseBuildStorageUrl.ValidUrlWithApiPrefix")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ bool Result = zen::ParseBuildStorageUrl("https://horde.devtools.epicgames.com/api/v2/builds/mynamespace/mybucket/mybuildid",
+ Host,
+ Namespace,
+ Bucket,
+ BuildId);
+ CHECK(Result);
+ CHECK(Host == "https://horde.devtools.epicgames.com");
+ CHECK(Namespace == "mynamespace");
+ CHECK(Bucket == "mybucket");
+ CHECK(BuildId == "mybuildid");
+}
+
+TEST_CASE("ParseBuildStorageUrl.HttpScheme")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ bool Result = zen::ParseBuildStorageUrl("http://localhost/ns/bucket/build123", Host, Namespace, Bucket, BuildId);
+ CHECK(Result);
+ CHECK(Host == "http://localhost");
+ CHECK(Namespace == "ns");
+ CHECK(Bucket == "bucket");
+ CHECK(BuildId == "build123");
+}
+
+TEST_CASE("ParseBuildStorageUrl.BuildIdWithSlashes")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ bool Result = zen::ParseBuildStorageUrl("https://host/ns/bucket/build/with/slashes", Host, Namespace, Bucket, BuildId);
+ CHECK(Result);
+ CHECK(Host == "https://host");
+ CHECK(Namespace == "ns");
+ CHECK(Bucket == "bucket");
+ CHECK(BuildId == "build/with/slashes");
+}
+
+TEST_CASE("ParseBuildStorageUrl.MissingBuildId")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ CHECK_FALSE(zen::ParseBuildStorageUrl("https://host/ns/bucket/", Host, Namespace, Bucket, BuildId));
+}
+
+TEST_CASE("ParseBuildStorageUrl.MissingBucket")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ CHECK_FALSE(zen::ParseBuildStorageUrl("https://host/ns", Host, Namespace, Bucket, BuildId));
+}
+
+TEST_CASE("ParseBuildStorageUrl.NoScheme")
+{
+ std::string Host, Namespace, Bucket, BuildId;
+ CHECK_FALSE(zen::ParseBuildStorageUrl("host/ns/bucket/buildid", Host, Namespace, Bucket, BuildId));
+}
+
+TEST_SUITE_END();
+
+#endif // ZEN_WITH_TESTS
diff --git a/src/zenremotestore/include/zenremotestore/builds/buildstorageoperations.h b/src/zenremotestore/include/zenremotestore/builds/buildstorageoperations.h
index 0d2eded58..27dc9de86 100644
--- a/src/zenremotestore/include/zenremotestore/builds/buildstorageoperations.h
+++ b/src/zenremotestore/include/zenremotestore/builds/buildstorageoperations.h
@@ -261,12 +261,16 @@ private:
void DownloadBuildBlob(uint32_t RemoteChunkIndex,
const BlobsExistsResult& ExistsResult,
ParallelWork& Work,
+ uint64_t TotalRequestCount,
+ FilteredRate& FilteredDownloadedBytesPerSecond,
std::function<void(IoBuffer&& Payload)>&& OnDownloaded);
- void DownloadPartialBlock(std::span<const ChunkBlockAnalyser::BlockRangeDescriptor> BlockRanges,
- size_t BlockRangeIndex,
- size_t BlockRangeCount,
- const BlobsExistsResult& ExistsResult,
+ void DownloadPartialBlock(std::span<const ChunkBlockAnalyser::BlockRangeDescriptor> BlockRanges,
+ size_t BlockRangeIndex,
+ size_t BlockRangeCount,
+ const BlobsExistsResult& ExistsResult,
+ uint64_t TotalRequestCount,
+ FilteredRate& FilteredDownloadedBytesPerSecond,
std::function<void(IoBuffer&& InMemoryBuffer,
const std::filesystem::path& OnDiskPath,
size_t BlockRangeStartIndex,
diff --git a/src/zenremotestore/include/zenremotestore/builds/jupiterbuildstorage.h b/src/zenremotestore/include/zenremotestore/builds/jupiterbuildstorage.h
index 888ec8ead..270835521 100644
--- a/src/zenremotestore/include/zenremotestore/builds/jupiterbuildstorage.h
+++ b/src/zenremotestore/include/zenremotestore/builds/jupiterbuildstorage.h
@@ -22,4 +22,6 @@ bool ParseBuildStorageUrl(std::string_view InUrl,
std::string& OutBucket,
std::string& OutBuildId);
+void jupiterbuildstorage_forcelink();
+
} // namespace zen
diff --git a/src/zenremotestore/jupiter/jupitersession.cpp b/src/zenremotestore/jupiter/jupitersession.cpp
index b5531fa60..d610d1fc8 100644
--- a/src/zenremotestore/jupiter/jupitersession.cpp
+++ b/src/zenremotestore/jupiter/jupitersession.cpp
@@ -673,7 +673,7 @@ JupiterSession::PutMultipartBuildBlob(std::string_view Namespace,
size_t RetryPartIndex = PartNameToIndex.at(RetryPartId);
const MultipartUploadResponse::Part& RetryPart = Workload->PartDescription.Parts[RetryPartIndex];
IoBuffer RetryPartPayload =
- Workload->Transmitter(RetryPart.FirstByte, RetryPart.LastByte - RetryPart.FirstByte - 1);
+ Workload->Transmitter(RetryPart.FirstByte, RetryPart.LastByte - RetryPart.FirstByte);
std::string RetryMultipartUploadResponseRequestString =
fmt::format("/api/v2/builds/{}/{}/{}/blobs/{}/uploadMultipart{}&supportsRedirect={}",
Namespace,
@@ -882,7 +882,8 @@ JupiterSession::GetBuildBlob(std::string_view Namespace,
m_AllowRedirect ? "true"sv : "false"sv);
HttpClient::Response Response = m_HttpClient.Download(Url, TempFolderPath, Headers);
- if (Response.StatusCode == HttpResponseCode::RangeNotSatisfiable && Ranges.size() > 1)
+ if ((Response.StatusCode == HttpResponseCode::RangeNotSatisfiable || Response.StatusCode == HttpResponseCode::NotImplemented) &&
+ Ranges.size() > 1)
{
// Requests to Jupiter that is not served via nginx (content not stored locally in the file system) can not serve multi-range
// requests (asp.net limitation) This rejection is not implemented as of 2026-03-02, it is in the backlog (@joakim.lindqvist)
diff --git a/src/zenremotestore/projectstore/remoteprojectstore.cpp b/src/zenremotestore/projectstore/remoteprojectstore.cpp
index 1a9dc10ef..2076adb70 100644
--- a/src/zenremotestore/projectstore/remoteprojectstore.cpp
+++ b/src/zenremotestore/projectstore/remoteprojectstore.cpp
@@ -929,7 +929,6 @@ namespace remotestore_impl {
{
return;
}
- ZEN_ASSERT(UploadAttachment->Size != 0);
if (!UploadAttachment->RawPath.empty())
{
if (UploadAttachment->Size > (MaxChunkEmbedSize * 2))
@@ -7008,6 +7007,60 @@ TEST_CASE("buildcontainer.ignore_missing_file_attachment_warn")
}
}
+TEST_CASE("buildcontainer.zero_byte_file_attachment")
+{
+ // A zero-byte file on disk is a valid attachment. BuildContainer must process
+ // it without hitting ZEN_ASSERT(UploadAttachment->Size != 0) in
+ // ResolveAttachments. The empty file flows through the compress-inline path
+ // and becomes a LooseUploadAttachment with raw size 0.
+ using namespace projectstore_testutils;
+ using namespace std::literals;
+
+ ScopedTemporaryDirectory TempDir;
+
+ GcManager Gc;
+ CidStore CidStore(Gc);
+ std::unique_ptr<ProjectStore> ProjectStoreDummy;
+ Ref<ProjectStore::Project> Project = MakeTestProject(CidStore, Gc, TempDir.Path(), ProjectStoreDummy);
+
+ std::filesystem::path RootDir = TempDir.Path() / "root";
+ auto FileAtts = CreateFileAttachments(RootDir, std::initializer_list<size_t>{512});
+
+ Ref<ProjectStore::Oplog> Oplog = Project->NewOplog("bc_zero_byte_file", {});
+ REQUIRE(Oplog);
+ Oplog->AppendNewOplogEntry(CreateFilesOplogPackage(Oid::NewOid(), RootDir, FileAtts));
+
+ // Truncate the file to zero bytes after the oplog entry is created.
+ // The file still exists on disk so RewriteOplog's IsFile() check passes,
+ // but MakeFromFile returns a zero-size buffer.
+ std::filesystem::resize_file(FileAtts[0].second, 0);
+
+ WorkerThreadPool WorkerPool(GetWorkerCount());
+
+ CbObject Container = BuildContainer(
+ CidStore,
+ *Project,
+ *Oplog,
+ WorkerPool,
+ 64u * 1024u,
+ 1000,
+ 32u * 1024u,
+ 64u * 1024u * 1024u,
+ /*BuildBlocks=*/true,
+ /*IgnoreMissingAttachments=*/false,
+ /*AllowChunking=*/true,
+ [](CompressedBuffer&&, ChunkBlockDescription&&) {},
+ [](const IoHash&, TGetAttachmentBufferFunc&&) {},
+ [](std::vector<std::pair<IoHash, FetchChunkFunc>>&&) {},
+ /*EmbedLooseFiles=*/true);
+
+ CHECK(Container.GetSize() > 0);
+
+ // The zero-byte attachment is packed into a block via the compress-inline path.
+ CbArrayView Blocks = Container["blocks"sv].AsArrayView();
+ CHECK(Blocks.Num() > 0);
+}
+
TEST_CASE("buildcontainer.embed_loose_files_false_no_rewrite")
{
// EmbedLooseFiles=false: RewriteOp is skipped for file-op entries; they pass through
diff --git a/src/zenremotestore/zenremotestore.cpp b/src/zenremotestore/zenremotestore.cpp
index a0bb17260..0b205b296 100644
--- a/src/zenremotestore/zenremotestore.cpp
+++ b/src/zenremotestore/zenremotestore.cpp
@@ -5,6 +5,7 @@
#include <zenremotestore/builds/buildmanifest.h>
#include <zenremotestore/builds/buildsavedstate.h>
#include <zenremotestore/builds/buildstorageoperations.h>
+#include <zenremotestore/builds/jupiterbuildstorage.h>
#include <zenremotestore/chunking/chunkedcontent.h>
#include <zenremotestore/chunking/chunkedfile.h>
#include <zenremotestore/chunking/chunkingcache.h>
@@ -20,6 +21,7 @@ zenremotestore_forcelinktests()
{
buildmanifest_forcelink();
buildsavedstate_forcelink();
+ jupiterbuildstorage_forcelink();
buildstorageoperations_forcelink();
chunkblock_forcelink();
chunkedcontent_forcelink();
diff --git a/src/zens3-testbed/main.cpp b/src/zens3-testbed/main.cpp
index 4cd6b411f..1543c4d7c 100644
--- a/src/zens3-testbed/main.cpp
+++ b/src/zens3-testbed/main.cpp
@@ -110,7 +110,7 @@ CreateClient(const cxxopts::ParseResult& Args)
if (Args.count("timeout"))
{
- Options.Timeout = std::chrono::milliseconds(Args["timeout"].as<int>() * 1000);
+ Options.HttpSettings.Timeout = std::chrono::milliseconds(Args["timeout"].as<int>() * 1000);
}
return S3Client(Options);
diff --git a/src/zenserver-test/cache-tests.cpp b/src/zenserver-test/cache-tests.cpp
index 334dd04ab..986dc67e0 100644
--- a/src/zenserver-test/cache-tests.cpp
+++ b/src/zenserver-test/cache-tests.cpp
@@ -9,6 +9,7 @@
# include <zencore/compactbinarypackage.h>
# include <zencore/compress.h>
# include <zencore/fmtutils.h>
+# include <zenhttp/localrefpolicy.h>
# include <zenhttp/packageformat.h>
# include <zenstore/cache/cachepolicy.h>
# include <zencore/filesystem.h>
@@ -25,6 +26,13 @@ namespace zen::tests {
TEST_SUITE_BEGIN("server.cache");
+/// Permissive policy that allows any path, for use in tests that exercise local ref
+/// functionality but are not testing path validation.
+struct PermissiveLocalRefPolicy : public ILocalRefPolicy
+{
+ void ValidatePath(const std::filesystem::path&) const override {}
+};
+
TEST_CASE("zcache.basic")
{
using namespace std::literals;
@@ -743,7 +751,11 @@ TEST_CASE("zcache.rpc")
if (Result.StatusCode == HttpResponseCode::OK)
{
- CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
+ ParseFlags PFlags = EnumHasAllFlags(AcceptOptions, RpcAcceptOptions::kAllowLocalReferences) ? ParseFlags::kAllowLocalReferences
+ : ParseFlags::kDefault;
+ PermissiveLocalRefPolicy AllowAllPolicy;
+ const ILocalRefPolicy* PPolicy = EnumHasAllFlags(PFlags, ParseFlags::kAllowLocalReferences) ? &AllowAllPolicy : nullptr;
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload, {}, PFlags, PPolicy);
CHECK(!Response.IsNull());
OutResult.Response = std::move(Response);
CHECK(OutResult.Result.Parse(OutResult.Response));
@@ -1193,14 +1205,10 @@ TEST_CASE("zcache.rpc")
// CbPackage Package;
// CHECK(Request.Format(Package));
- // IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- // cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", LocalCfg.BaseUri)},
- // cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- // cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ // IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ // // TODO: rewrite using HttpClient instead of removed CPR dependency
- // CHECK(Result.status_code == 200);
// cacherequests::PutCacheRecordsResult ParsedResult;
- // CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
// CHECK(!Response.IsNull());
// CHECK(ParsedResult.Parse(Response));
// for (bool ResponseSuccess : ParsedResult.Success)
@@ -1749,8 +1757,13 @@ TEST_CASE("zcache.rpc.partialchunks")
CHECK(Result.StatusCode == HttpResponseCode::OK);
- CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
- bool Loaded = !Response.IsNull();
+ ParseFlags PFlags = EnumHasAllFlags(Options.AcceptOptions, RpcAcceptOptions::kAllowLocalReferences)
+ ? ParseFlags::kAllowLocalReferences
+ : ParseFlags::kDefault;
+ PermissiveLocalRefPolicy AllowAllPolicy;
+ const ILocalRefPolicy* PPolicy = EnumHasAllFlags(PFlags, ParseFlags::kAllowLocalReferences) ? &AllowAllPolicy : nullptr;
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload, {}, PFlags, PPolicy);
+ bool Loaded = !Response.IsNull();
CHECK_MESSAGE(Loaded, "GetCacheChunks response failed to load.");
cacherequests::GetCacheChunksResult GetCacheChunksResult;
CHECK(GetCacheChunksResult.Parse(Response));
diff --git a/src/zenserver-test/compute-tests.cpp b/src/zenserver-test/compute-tests.cpp
index 021052a3b..835d72713 100644
--- a/src/zenserver-test/compute-tests.cpp
+++ b/src/zenserver-test/compute-tests.cpp
@@ -21,6 +21,7 @@
# include <zenhttp/httpserver.h>
# include <zenhttp/websocket.h>
# include <zencompute/computeservice.h>
+# include <zencore/fmtutils.h>
# include <zenstore/zenstore.h>
# include <zenutil/zenserverprocess.h>
@@ -36,6 +37,8 @@ using namespace std::literals;
static constexpr std::string_view kBuildSystemVersion = "17fe280d-ccd8-4be8-a9d1-89c944a70969";
static constexpr std::string_view kRot13Version = "13131313-1313-1313-1313-131313131313";
static constexpr std::string_view kSleepVersion = "88888888-8888-8888-8888-888888888888";
+static constexpr std::string_view kFailVersion = "fa11fa11-fa11-fa11-fa11-fa11fa11fa11";
+static constexpr std::string_view kCrashVersion = "c4a50000-c4a5-c4a5-c4a5-c4a5c4a5c4a5";
// In-memory implementation of ChunkResolver for test use.
// Stores compressed data keyed by decompressed content hash.
@@ -104,6 +107,16 @@ RegisterWorker(HttpClient& Client, ZenServerEnvironment& Env)
<< "Sleep"sv;
WorkerWriter << "version"sv << Guid::FromString(kSleepVersion);
WorkerWriter.EndObject();
+ WorkerWriter.BeginObject();
+ WorkerWriter << "name"sv
+ << "Fail"sv;
+ WorkerWriter << "version"sv << Guid::FromString(kFailVersion);
+ WorkerWriter.EndObject();
+ WorkerWriter.BeginObject();
+ WorkerWriter << "name"sv
+ << "Crash"sv;
+ WorkerWriter << "version"sv << Guid::FromString(kCrashVersion);
+ WorkerWriter.EndObject();
WorkerWriter.EndArray();
CbPackage WorkerPackage;
@@ -115,7 +128,7 @@ RegisterWorker(HttpClient& Client, ZenServerEnvironment& Env)
const std::string WorkerUrl = fmt::format("/workers/{}", WorkerId.ToHexString());
HttpClient::Response RegisterResp = Client.Post(WorkerUrl, std::move(WorkerPackage));
REQUIRE_MESSAGE(RegisterResp,
- fmt::format("Worker registration failed: status={}, body={}", int(RegisterResp.StatusCode), RegisterResp.ToText()));
+ fmt::format("Worker registration failed: status={}, body={}", RegisterResp.StatusCode, RegisterResp.ToText()));
return WorkerId;
}
@@ -220,6 +233,83 @@ BuildSleepActionForSession(std::string_view Input, uint64_t SleepTimeMs, InMemor
return ActionWriter.Save();
}
+// Build a Fail action CbPackage. The worker exits with the given exit code.
+static CbPackage
+BuildFailActionPackage(int ExitCode)
+{
+ // The Fail function throws before reading inputs, but the action structure
+ // still requires a valid input attachment for the runner to manifest.
+ std::string_view Dummy = "x"sv;
+
+ CompressedBuffer InputCompressed = CompressedBuffer::Compress(SharedBuffer::MakeView(Dummy.data(), Dummy.size()),
+ OodleCompressor::Selkie,
+ OodleCompressionLevel::HyperFast4);
+
+ const IoHash InputRawHash = InputCompressed.DecodeRawHash();
+ const uint64_t InputRawSize = Dummy.size();
+
+ CbAttachment InputAttachment(std::move(InputCompressed), InputRawHash);
+
+ CbObjectWriter ActionWriter;
+ ActionWriter << "Function"sv
+ << "Fail"sv;
+ ActionWriter << "FunctionVersion"sv << Guid::FromString(kFailVersion);
+ ActionWriter << "BuildSystemVersion"sv << Guid::FromString(kBuildSystemVersion);
+ ActionWriter.BeginObject("Inputs"sv);
+ ActionWriter.BeginObject("Source"sv);
+ ActionWriter.AddAttachment("RawHash"sv, InputAttachment);
+ ActionWriter << "RawSize"sv << InputRawSize;
+ ActionWriter.EndObject();
+ ActionWriter.EndObject();
+ ActionWriter.BeginObject("Constants"sv);
+ ActionWriter << "ExitCode"sv << static_cast<uint64_t>(ExitCode);
+ ActionWriter.EndObject();
+
+ CbPackage ActionPackage;
+ ActionPackage.SetObject(ActionWriter.Save());
+ ActionPackage.AddAttachment(InputAttachment);
+
+ return ActionPackage;
+}
+
+// Build a Crash action CbPackage. The worker process crashes hard.
+// Mode: "abort" (default) or "nullptr" (null pointer dereference).
+static CbPackage
+BuildCrashActionPackage(std::string_view Mode = "abort"sv)
+{
+ std::string_view Dummy = "x"sv;
+
+ CompressedBuffer InputCompressed = CompressedBuffer::Compress(SharedBuffer::MakeView(Dummy.data(), Dummy.size()),
+ OodleCompressor::Selkie,
+ OodleCompressionLevel::HyperFast4);
+
+ const IoHash InputRawHash = InputCompressed.DecodeRawHash();
+ const uint64_t InputRawSize = Dummy.size();
+
+ CbAttachment InputAttachment(std::move(InputCompressed), InputRawHash);
+
+ CbObjectWriter ActionWriter;
+ ActionWriter << "Function"sv
+ << "Crash"sv;
+ ActionWriter << "FunctionVersion"sv << Guid::FromString(kCrashVersion);
+ ActionWriter << "BuildSystemVersion"sv << Guid::FromString(kBuildSystemVersion);
+ ActionWriter.BeginObject("Inputs"sv);
+ ActionWriter.BeginObject("Source"sv);
+ ActionWriter.AddAttachment("RawHash"sv, InputAttachment);
+ ActionWriter << "RawSize"sv << InputRawSize;
+ ActionWriter.EndObject();
+ ActionWriter.EndObject();
+ ActionWriter.BeginObject("Constants"sv);
+ ActionWriter << "Mode"sv << Mode;
+ ActionWriter.EndObject();
+
+ CbPackage ActionPackage;
+ ActionPackage.SetObject(ActionWriter.Save());
+ ActionPackage.AddAttachment(InputAttachment);
+
+ return ActionPackage;
+}
+
static HttpClient::Response
PollForResult(HttpClient& Client, const std::string& ResultUrl, uint64_t TimeoutMs = 30'000)
{
@@ -340,8 +430,9 @@ public:
}
// IWebSocketHandler
- void OnWebSocketOpen(Ref<WebSocketConnection> Connection) override
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override
{
+ ZEN_UNUSED(RelativeUri);
m_WsLock.WithExclusiveLock([&] { m_WsConnections.push_back(std::move(Connection)); });
}
@@ -469,6 +560,16 @@ BuildWorkerPackage(ZenServerEnvironment& Env, InMemoryChunkResolver& Resolver)
<< "Sleep"sv;
WorkerWriter << "version"sv << Guid::FromString(kSleepVersion);
WorkerWriter.EndObject();
+ WorkerWriter.BeginObject();
+ WorkerWriter << "name"sv
+ << "Fail"sv;
+ WorkerWriter << "version"sv << Guid::FromString(kFailVersion);
+ WorkerWriter.EndObject();
+ WorkerWriter.BeginObject();
+ WorkerWriter << "name"sv
+ << "Crash"sv;
+ WorkerWriter << "version"sv << Guid::FromString(kCrashVersion);
+ WorkerWriter.EndObject();
WorkerWriter.EndArray();
CbPackage WorkerPackage;
@@ -526,7 +627,7 @@ TEST_CASE("function.rot13")
// Submit action via legacy /jobs/{worker} endpoint
const std::string JobUrl = fmt::format("/jobs/{}", WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildRot13ActionPackage("Hello World"sv));
- REQUIRE_MESSAGE(SubmitResp, fmt::format("Job submission failed: status={}, body={}", int(SubmitResp.StatusCode), SubmitResp.ToText()));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from job submission");
@@ -536,7 +637,7 @@ TEST_CASE("function.rot13")
HttpClient::Response ResultResp = PollForResult(Client, ResultUrl);
REQUIRE_MESSAGE(
ResultResp.StatusCode == HttpResponseCode::OK,
- fmt::format("Job did not complete in time. Last status: {}\nServer log:\n{}", int(ResultResp.StatusCode), Instance.GetLogOutput()));
+ fmt::format("Job did not complete in time. Last status: {}\nServer log:\n{}", ResultResp.StatusCode, Instance.GetLogOutput()));
// Verify result: Rot13("Hello World") == "Uryyb Jbeyq"
CbPackage ResultPackage = ResultResp.AsPackage();
@@ -581,7 +682,7 @@ TEST_CASE("function.workers")
// GET /workers/{worker} — descriptor should match what was registered
const std::string WorkerUrl = fmt::format("/workers/{}", WorkerId.ToHexString());
HttpClient::Response DescResp = Client.Get(WorkerUrl);
- REQUIRE_MESSAGE(DescResp, fmt::format("Failed to get worker descriptor: status={}", int(DescResp.StatusCode)));
+ REQUIRE_MESSAGE(DescResp, fmt::format("Failed to get worker descriptor: status={}", DescResp.StatusCode));
CbObject Desc = DescResp.AsObject();
CHECK_EQ(Desc["buildsystem_version"sv].AsUuid(), Guid::FromString(kBuildSystemVersion));
@@ -627,7 +728,7 @@ TEST_CASE("function.queues.lifecycle")
// Create a queue
HttpClient::Response CreateResp = Client.Post("/queues"sv);
- REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}, body={}", int(CreateResp.StatusCode), CreateResp.ToText()));
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}, body={}", CreateResp.StatusCode, CreateResp.ToText()));
const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
REQUIRE_MESSAGE(QueueId != 0, "Expected non-zero queue_id from queue creation");
@@ -651,8 +752,7 @@ TEST_CASE("function.queues.lifecycle")
// Submit action via queue-scoped endpoint
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildRot13ActionPackage("Hello World"sv));
- REQUIRE_MESSAGE(SubmitResp,
- fmt::format("Queue job submission failed: status={}, body={}", int(SubmitResp.StatusCode), SubmitResp.ToText()));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Queue job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from queue job submission");
@@ -668,9 +768,8 @@ TEST_CASE("function.queues.lifecycle")
// Retrieve result via queue-scoped /jobs/{lsn} endpoint
const std::string ResultUrl = fmt::format("/queues/{}/jobs/{}", QueueId, Lsn);
HttpClient::Response ResultResp = Client.Get(ResultUrl);
- REQUIRE_MESSAGE(
- ResultResp.StatusCode == HttpResponseCode::OK,
- fmt::format("Failed to retrieve result: status={}\nServer log:\n{}", int(ResultResp.StatusCode), Instance.GetLogOutput()));
+ REQUIRE_MESSAGE(ResultResp.StatusCode == HttpResponseCode::OK,
+ fmt::format("Failed to retrieve result: status={}\nServer log:\n{}", ResultResp.StatusCode, Instance.GetLogOutput()));
// Verify result: Rot13("Hello World") == "Uryyb Jbeyq"
CbPackage ResultPackage = ResultResp.AsPackage();
@@ -712,13 +811,13 @@ TEST_CASE("function.queues.cancel")
// Submit a job
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildRot13ActionPackage("Hello World"sv));
- REQUIRE_MESSAGE(SubmitResp, fmt::format("Job submission failed: status={}, body={}", int(SubmitResp.StatusCode), SubmitResp.ToText()));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
// Cancel the queue
const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
HttpClient::Response CancelResp = Client.Delete(QueueUrl);
REQUIRE_MESSAGE(CancelResp.StatusCode == HttpResponseCode::NoContent,
- fmt::format("Queue cancellation failed: status={}, body={}", int(CancelResp.StatusCode), CancelResp.ToText()));
+ fmt::format("Queue cancellation failed: status={}, body={}", CancelResp.StatusCode, CancelResp.ToText()));
// Verify queue status shows cancelled
HttpClient::Response StatusResp = Client.Get(QueueUrl);
@@ -743,7 +842,7 @@ TEST_CASE("function.queues.remote")
// Create a remote queue — response includes both an integer queue_id and an OID queue_token
HttpClient::Response CreateResp = Client.Post("/queues/remote"sv);
REQUIRE_MESSAGE(CreateResp,
- fmt::format("Remote queue creation failed: status={}, body={}", int(CreateResp.StatusCode), CreateResp.ToText()));
+ fmt::format("Remote queue creation failed: status={}, body={}", CreateResp.StatusCode, CreateResp.ToText()));
CbObject CreateObj = CreateResp.AsObject();
const std::string QueueToken = std::string(CreateObj["queue_token"sv].AsString());
@@ -753,7 +852,7 @@ TEST_CASE("function.queues.remote")
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueToken, WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildRot13ActionPackage("Hello World"sv));
REQUIRE_MESSAGE(SubmitResp,
- fmt::format("Remote queue job submission failed: status={}, body={}", int(SubmitResp.StatusCode), SubmitResp.ToText()));
+ fmt::format("Remote queue job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from remote queue job submission");
@@ -769,7 +868,7 @@ TEST_CASE("function.queues.remote")
HttpClient::Response ResultResp = Client.Get(ResultUrl);
REQUIRE_MESSAGE(ResultResp.StatusCode == HttpResponseCode::OK,
fmt::format("Failed to retrieve result from remote queue: status={}\nServer log:\n{}",
- int(ResultResp.StatusCode),
+ ResultResp.StatusCode,
Instance.GetLogOutput()));
// Verify result: Rot13("Hello World") == "Uryyb Jbeyq"
@@ -801,8 +900,7 @@ TEST_CASE("function.queues.cancel_running")
// Submit a Sleep job long enough that it will still be running when we cancel
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildSleepActionPackage("data"sv, 30'000));
- REQUIRE_MESSAGE(SubmitResp,
- fmt::format("Sleep job submission failed: status={}, body={}", int(SubmitResp.StatusCode), SubmitResp.ToText()));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Sleep job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from Sleep job submission");
@@ -814,7 +912,7 @@ TEST_CASE("function.queues.cancel_running")
const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
HttpClient::Response CancelResp = Client.Delete(QueueUrl);
REQUIRE_MESSAGE(CancelResp.StatusCode == HttpResponseCode::NoContent,
- fmt::format("Queue cancellation failed: status={}, body={}", int(CancelResp.StatusCode), CancelResp.ToText()));
+ fmt::format("Queue cancellation failed: status={}, body={}", CancelResp.StatusCode, CancelResp.ToText()));
// The cancelled job should appear in the /completed endpoint once the process exits
const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
@@ -849,7 +947,7 @@ TEST_CASE("function.queues.remote_cancel")
// Create a remote queue to obtain an OID token for token-addressed cancellation
HttpClient::Response CreateResp = Client.Post("/queues/remote"sv);
REQUIRE_MESSAGE(CreateResp,
- fmt::format("Remote queue creation failed: status={}, body={}", int(CreateResp.StatusCode), CreateResp.ToText()));
+ fmt::format("Remote queue creation failed: status={}, body={}", CreateResp.StatusCode, CreateResp.ToText()));
const std::string QueueToken = std::string(CreateResp.AsObject()["queue_token"sv].AsString());
REQUIRE_MESSAGE(!QueueToken.empty(), "Expected non-empty queue_token from remote queue creation");
@@ -857,8 +955,7 @@ TEST_CASE("function.queues.remote_cancel")
// Submit a long-running Sleep job via the token-addressed endpoint
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueToken, WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildSleepActionPackage("data"sv, 30'000));
- REQUIRE_MESSAGE(SubmitResp,
- fmt::format("Sleep job submission failed: status={}, body={}", int(SubmitResp.StatusCode), SubmitResp.ToText()));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Sleep job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from Sleep job submission");
@@ -870,7 +967,7 @@ TEST_CASE("function.queues.remote_cancel")
const std::string QueueUrl = fmt::format("/queues/{}", QueueToken);
HttpClient::Response CancelResp = Client.Delete(QueueUrl);
REQUIRE_MESSAGE(CancelResp.StatusCode == HttpResponseCode::NoContent,
- fmt::format("Remote queue cancellation failed: status={}, body={}", int(CancelResp.StatusCode), CancelResp.ToText()));
+ fmt::format("Remote queue cancellation failed: status={}, body={}", CancelResp.StatusCode, CancelResp.ToText()));
// The cancelled job should appear in the token-addressed /completed endpoint
const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueToken);
@@ -910,13 +1007,13 @@ TEST_CASE("function.queues.drain")
// Submit a long-running job so we can verify it completes even after drain
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
HttpClient::Response Submit1 = Client.Post(JobUrl, BuildSleepActionPackage("data"sv, 2'000));
- REQUIRE_MESSAGE(Submit1, fmt::format("First job submission failed: status={}", int(Submit1.StatusCode)));
+ REQUIRE_MESSAGE(Submit1, fmt::format("First job submission failed: status={}", Submit1.StatusCode));
const int Lsn1 = Submit1.AsObject()["lsn"sv].AsInt32();
// Drain the queue
const std::string DrainUrl = fmt::format("/queues/{}/drain", QueueId);
HttpClient::Response DrainResp = Client.Post(DrainUrl);
- REQUIRE_MESSAGE(DrainResp, fmt::format("Drain failed: status={}, body={}", int(DrainResp.StatusCode), DrainResp.ToText()));
+ REQUIRE_MESSAGE(DrainResp, fmt::format("Drain failed: status={}, body={}", DrainResp.StatusCode, DrainResp.ToText()));
CHECK_EQ(std::string(DrainResp.AsObject()["state"sv].AsString()), "draining");
// Second submission should be rejected with 424
@@ -965,7 +1062,7 @@ TEST_CASE("function.priority")
// jobs by priority when the slot becomes free.
const std::string BlockerJobUrl = fmt::format("/queues/{}/jobs/{}?priority=0", QueueId, WorkerId.ToHexString());
HttpClient::Response BlockerResp = Client.Post(BlockerJobUrl, BuildSleepActionPackage("data"sv, 1'000));
- REQUIRE_MESSAGE(BlockerResp, fmt::format("Blocker job submission failed: status={}", int(BlockerResp.StatusCode)));
+ REQUIRE_MESSAGE(BlockerResp, fmt::format("Blocker job submission failed: status={}", BlockerResp.StatusCode));
// Submit 3 low-priority Rot13 jobs
const std::string LowJobUrl = fmt::format("/queues/{}/jobs/{}?priority=0", QueueId, WorkerId.ToHexString());
@@ -1104,6 +1201,432 @@ TEST_CASE("function.priority")
}
//////////////////////////////////////////////////////////////////////////
+// Process exit code tests
+//
+// These tests exercise how the compute service handles worker processes
+// that exit with non-zero exit codes, including retry behaviour and
+// final failure reporting.
+
+TEST_CASE("function.exit_code.failed_action")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=0 so the action fails immediately
+ // without being rescheduled.
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 0;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit a Fail action with exit code 42
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+ HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildFailActionPackage(42));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Fail job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
+
+ const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
+ REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from Fail job submission");
+
+ // Poll for the LSN to appear in the completed list
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, Lsn),
+ fmt::format("LSN {} did not appear in queue {} completed list within timeout\nServer log:\n{}",
+ Lsn,
+ QueueId,
+ Instance.GetLogOutput()));
+
+ // Verify queue status reflects the failure
+ HttpClient::Response StatusResp = Client.Get(QueueUrl);
+ REQUIRE_MESSAGE(StatusResp, "Failed to get queue status");
+
+ CbObject QueueStatus = StatusResp.AsObject();
+ CHECK_EQ(QueueStatus["failed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["completed_count"sv].AsInt32(), 0);
+
+ // Verify action history records the failure
+ const std::string HistoryUrl = fmt::format("/queues/{}/history", QueueId);
+ HttpClient::Response HistoryResp = Client.Get(HistoryUrl);
+ REQUIRE_MESSAGE(HistoryResp, "Failed to query queue action history");
+
+ bool FoundInHistory = false;
+ for (auto& Item : HistoryResp.AsObject()["history"sv])
+ {
+ if (Item.AsObjectView()["lsn"sv].AsInt32() == Lsn)
+ {
+ CHECK_EQ(Item.AsObjectView()["succeeded"sv].AsBool(), false);
+ FoundInHistory = true;
+ break;
+ }
+ }
+ CHECK_MESSAGE(FoundInHistory, fmt::format("LSN {} not found in action history", Lsn));
+
+ // GET /jobs/{lsn} for a failed action should return OK but with an empty result package
+ const std::string ResultUrl = fmt::format("/queues/{}/jobs/{}", QueueId, Lsn);
+ HttpClient::Response ResultResp = Client.Get(ResultUrl);
+ CHECK_EQ(ResultResp.StatusCode, HttpResponseCode::OK);
+}
+
+TEST_CASE("function.exit_code.auto_retry")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=2 so the action is retried twice before
+ // being reported as failed (3 total attempts: initial + 2 retries).
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 2;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit a Fail action — the worker process will exit with code 1 on
+ // every attempt, eventually exhausting retries.
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+ HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildFailActionPackage(1));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Fail job submission failed: status={}", SubmitResp.StatusCode));
+
+ const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
+
+ // Poll for the LSN to appear in the completed list — this only
+ // happens after all retries are exhausted.
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, Lsn, 60'000),
+ fmt::format("LSN {} did not appear in queue {} completed list after retries\nServer log:\n{}",
+ Lsn,
+ QueueId,
+ Instance.GetLogOutput()));
+
+ // Verify the action history records the retry count
+ const std::string HistoryUrl = fmt::format("/queues/{}/history", QueueId);
+ HttpClient::Response HistoryResp = Client.Get(HistoryUrl);
+ REQUIRE_MESSAGE(HistoryResp, "Failed to query queue action history");
+
+ for (auto& Item : HistoryResp.AsObject()["history"sv])
+ {
+ if (Item.AsObjectView()["lsn"sv].AsInt32() == Lsn)
+ {
+ CHECK_EQ(Item.AsObjectView()["succeeded"sv].AsBool(), false);
+ CHECK_EQ(Item.AsObjectView()["retry_count"sv].AsInt32(), 2);
+ break;
+ }
+ }
+
+ // Queue should show 1 failed, 0 completed
+ HttpClient::Response StatusResp = Client.Get(QueueUrl);
+ REQUIRE_MESSAGE(StatusResp, "Failed to get queue status");
+
+ CbObject QueueStatus = StatusResp.AsObject();
+ CHECK_EQ(QueueStatus["failed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["completed_count"sv].AsInt32(), 0);
+}
+
+TEST_CASE("function.exit_code.reschedule_failed")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=1 so we have room for one manual reschedule
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 1;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit a Fail action — auto-retry will fire once, then it lands in results as Failed
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+ HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildFailActionPackage(7));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Fail job submission failed: status={}", SubmitResp.StatusCode));
+
+ const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
+
+ // Wait for the action to exhaust its auto-retry and land in completed
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, Lsn, 60'000),
+ fmt::format("LSN {} did not appear in queue completed list\nServer log:\n{}", Lsn, Instance.GetLogOutput()));
+
+ // Try to manually reschedule — should fail because retry limit is reached
+ const std::string RescheduleUrl = fmt::format("/queues/{}/jobs/{}", QueueId, Lsn);
+ HttpClient::Response RescheduleResp = Client.Post(RescheduleUrl);
+ CHECK_EQ(RescheduleResp.StatusCode, HttpResponseCode::Conflict);
+}
+
+TEST_CASE("function.exit_code.mixed_success_and_failure")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=0 for fast failure
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 0;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit one Rot13 (success) and one Fail (failure)
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+
+ HttpClient::Response SuccessResp = Client.Post(JobUrl, BuildRot13ActionPackage("Hello"sv));
+ REQUIRE_MESSAGE(SuccessResp, "Rot13 job submission failed");
+ const int LsnSuccess = SuccessResp.AsObject()["lsn"sv].AsInt32();
+
+ HttpClient::Response FailResp = Client.Post(JobUrl, BuildFailActionPackage(1));
+ REQUIRE_MESSAGE(FailResp, "Fail job submission failed");
+ const int LsnFail = FailResp.AsObject()["lsn"sv].AsInt32();
+
+ // Wait for both to appear in the completed list
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, LsnSuccess),
+ fmt::format("Success LSN {} did not complete\nServer log:\n{}", LsnSuccess, Instance.GetLogOutput()));
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, LsnFail),
+ fmt::format("Fail LSN {} did not complete\nServer log:\n{}", LsnFail, Instance.GetLogOutput()));
+
+ // Verify queue counters
+ HttpClient::Response StatusResp = Client.Get(QueueUrl);
+ REQUIRE_MESSAGE(StatusResp, "Failed to get queue status");
+
+ CbObject QueueStatus = StatusResp.AsObject();
+ CHECK_EQ(QueueStatus["completed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["failed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["active_count"sv].AsInt32(), 0);
+}
+
+TEST_CASE("function.crash.abort")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=0 so we don't wait through retries
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 0;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit a Crash action that calls std::abort()
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+ HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildCrashActionPackage("abort"sv));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Crash job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
+
+ const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
+ REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from Crash job submission");
+
+ // Poll for the LSN to appear in the completed list
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, Lsn),
+ fmt::format("LSN {} did not appear in queue {} completed list within timeout\nServer log:\n{}",
+ Lsn,
+ QueueId,
+ Instance.GetLogOutput()));
+
+ // Verify queue status reflects the failure
+ HttpClient::Response StatusResp = Client.Get(QueueUrl);
+ REQUIRE_MESSAGE(StatusResp, "Failed to get queue status");
+
+ CbObject QueueStatus = StatusResp.AsObject();
+ CHECK_EQ(QueueStatus["failed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["completed_count"sv].AsInt32(), 0);
+
+ // Verify action history records the failure
+ const std::string HistoryUrl = fmt::format("/queues/{}/history", QueueId);
+ HttpClient::Response HistoryResp = Client.Get(HistoryUrl);
+ REQUIRE_MESSAGE(HistoryResp, "Failed to query queue action history");
+
+ bool FoundInHistory = false;
+ for (auto& Item : HistoryResp.AsObject()["history"sv])
+ {
+ if (Item.AsObjectView()["lsn"sv].AsInt32() == Lsn)
+ {
+ CHECK_EQ(Item.AsObjectView()["succeeded"sv].AsBool(), false);
+ FoundInHistory = true;
+ break;
+ }
+ }
+ CHECK_MESSAGE(FoundInHistory, fmt::format("LSN {} not found in action history", Lsn));
+}
+
+TEST_CASE("function.crash.nullptr")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=0
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 0;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit a Crash action that dereferences a null pointer
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+ HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildCrashActionPackage("nullptr"sv));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Crash job submission failed: status={}, body={}", SubmitResp.StatusCode, SubmitResp.ToText()));
+
+ const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
+ REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from Crash job submission");
+
+ // Poll for the LSN to appear in the completed list
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, Lsn),
+ fmt::format("LSN {} did not appear in queue {} completed list within timeout\nServer log:\n{}",
+ Lsn,
+ QueueId,
+ Instance.GetLogOutput()));
+
+ // Verify queue status reflects the failure
+ HttpClient::Response StatusResp = Client.Get(QueueUrl);
+ REQUIRE_MESSAGE(StatusResp, "Failed to get queue status");
+
+ CbObject QueueStatus = StatusResp.AsObject();
+ CHECK_EQ(QueueStatus["failed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["completed_count"sv].AsInt32(), 0);
+}
+
+TEST_CASE("function.crash.auto_retry")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
+ Instance.SetDataDir(TestEnv.CreateNewTestDir());
+ const uint16_t Port = Instance.SpawnServerAndWaitUntilReady();
+ REQUIRE_MESSAGE(Port != 0, Instance.GetLogOutput());
+
+ const std::string ComputeBaseUri = fmt::format("http://localhost:{}/compute", Port);
+ HttpClient Client(ComputeBaseUri);
+
+ const IoHash WorkerId = RegisterWorker(Client, TestEnv);
+
+ // Create a queue with max_retries=1 — the crash should be retried once
+ // before being reported as permanently failed.
+ CbObjectWriter ConfigWriter;
+ ConfigWriter << "max_retries"sv << 1;
+
+ CbObjectWriter BodyWriter;
+ BodyWriter << "config"sv << ConfigWriter.Save();
+
+ HttpClient::Response CreateResp = Client.Post("/queues"sv, BodyWriter.Save());
+ REQUIRE_MESSAGE(CreateResp, fmt::format("Queue creation failed: status={}", CreateResp.StatusCode));
+
+ const int QueueId = CreateResp.AsObject()["queue_id"sv].AsInt32();
+ const std::string QueueUrl = fmt::format("/queues/{}", QueueId);
+
+ // Submit a Crash action — will crash on every attempt
+ const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
+ HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildCrashActionPackage("abort"sv));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Crash job submission failed: status={}", SubmitResp.StatusCode));
+
+ const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
+
+ // Poll for the LSN to appear in the completed list after retries exhaust
+ const std::string CompletedUrl = fmt::format("/queues/{}/completed", QueueId);
+ REQUIRE_MESSAGE(PollForLsnInCompleted(Client, CompletedUrl, Lsn, 60'000),
+ fmt::format("LSN {} did not appear in queue {} completed list after retries\nServer log:\n{}",
+ Lsn,
+ QueueId,
+ Instance.GetLogOutput()));
+
+ // Verify the action history records the retry count
+ const std::string HistoryUrl = fmt::format("/queues/{}/history", QueueId);
+ HttpClient::Response HistoryResp = Client.Get(HistoryUrl);
+ REQUIRE_MESSAGE(HistoryResp, "Failed to query queue action history");
+
+ for (auto& Item : HistoryResp.AsObject()["history"sv])
+ {
+ if (Item.AsObjectView()["lsn"sv].AsInt32() == Lsn)
+ {
+ CHECK_EQ(Item.AsObjectView()["succeeded"sv].AsBool(), false);
+ CHECK_EQ(Item.AsObjectView()["retry_count"sv].AsInt32(), 1);
+ break;
+ }
+ }
+
+ // Queue should show 1 failed, 0 completed
+ HttpClient::Response StatusResp = Client.Get(QueueUrl);
+ REQUIRE_MESSAGE(StatusResp, "Failed to get queue status");
+
+ CbObject QueueStatus = StatusResp.AsObject();
+ CHECK_EQ(QueueStatus["failed_count"sv].AsInt32(), 1);
+ CHECK_EQ(QueueStatus["completed_count"sv].AsInt32(), 0);
+}
+
+//////////////////////////////////////////////////////////////////////////
// Remote worker synchronization tests
//
// These tests exercise the orchestrator discovery path where new compute
@@ -1162,9 +1685,8 @@ TEST_CASE("function.remote.worker_sync_on_discovery")
Sleep(200);
}
- REQUIRE_MESSAGE(
- ResultCode == HttpResponseCode::OK,
- fmt::format("Action did not complete in time. Last status: {}\nServer log:\n{}", int(ResultCode), Instance.GetLogOutput()));
+ REQUIRE_MESSAGE(ResultCode == HttpResponseCode::OK,
+ fmt::format("Action did not complete in time. Last status: {}\nServer log:\n{}", ResultCode, Instance.GetLogOutput()));
REQUIRE_MESSAGE(bool(ResultPackage), fmt::format("Empty result package\nServer log:\n{}", Instance.GetLogOutput()));
@@ -1349,9 +1871,8 @@ TEST_CASE("function.remote.queue_association")
Sleep(200);
}
- REQUIRE_MESSAGE(
- ResultCode == HttpResponseCode::OK,
- fmt::format("Action did not complete in time. Last status: {}\nServer log:\n{}", int(ResultCode), Instance.GetLogOutput()));
+ REQUIRE_MESSAGE(ResultCode == HttpResponseCode::OK,
+ fmt::format("Action did not complete in time. Last status: {}\nServer log:\n{}", ResultCode, Instance.GetLogOutput()));
REQUIRE_MESSAGE(bool(ResultPackage), fmt::format("Empty result package\nServer log:\n{}", Instance.GetLogOutput()));
CHECK_EQ(GetRot13Output(ResultPackage), "Uryyb Jbeyq"sv);
@@ -1481,7 +2002,7 @@ TEST_CASE("function.abandon_running_http")
const std::string JobUrl = fmt::format("/queues/{}/jobs/{}", QueueId, WorkerId.ToHexString());
HttpClient::Response SubmitResp = Client.Post(JobUrl, BuildSleepActionPackage("data"sv, 30'000));
- REQUIRE_MESSAGE(SubmitResp, fmt::format("Sleep job submission failed: status={}", int(SubmitResp.StatusCode)));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Sleep job submission failed: status={}", SubmitResp.StatusCode));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN");
@@ -1498,7 +2019,7 @@ TEST_CASE("function.abandon_running_http")
// Trigger abandon via the HTTP endpoint
HttpClient::Response AbandonResp = Client.Post("/abandon"sv);
REQUIRE_MESSAGE(AbandonResp.StatusCode == HttpResponseCode::OK,
- fmt::format("Abandon request failed: status={}, body={}", int(AbandonResp.StatusCode), AbandonResp.ToText()));
+ fmt::format("Abandon request failed: status={}, body={}", AbandonResp.StatusCode, AbandonResp.ToText()));
// Ready endpoint should now return 503
{
@@ -1529,7 +2050,7 @@ TEST_CASE("function.abandon_running_http")
CHECK_MESSAGE(RejectedResp.StatusCode != HttpResponseCode::OK, "Expected action submission to be rejected in Abandoned state");
}
-TEST_CASE("function.session.abandon_pending")
+TEST_CASE("function.session.abandon_pending" * doctest::skip())
{
// Create a session with no runners so actions stay pending
InMemoryChunkResolver Resolver;
@@ -1577,7 +2098,7 @@ TEST_CASE("function.session.abandon_pending")
}
Sleep(100);
}
- CHECK_MESSAGE(Code == HttpResponseCode::OK, fmt::format("Expected action LSN {} to be in results (got {})", Lsn, int(Code)));
+ CHECK_MESSAGE(Code == HttpResponseCode::OK, fmt::format("Expected action LSN {} to be in results (got {})", Lsn, Code));
}
// Queue should show 0 active, 3 abandoned
@@ -1979,11 +2500,11 @@ TEST_CASE("function.retract_http")
// Submit a long-running Sleep action to occupy the single execution slot
const std::string BlockerUrl = fmt::format("/jobs/{}", WorkerId.ToHexString());
HttpClient::Response BlockerResp = Client.Post(BlockerUrl, BuildSleepActionPackage("data"sv, 30'000));
- REQUIRE_MESSAGE(BlockerResp, fmt::format("Blocker submission failed: status={}", int(BlockerResp.StatusCode)));
+ REQUIRE_MESSAGE(BlockerResp, fmt::format("Blocker submission failed: status={}", BlockerResp.StatusCode));
// Submit a second action — it will stay pending because the slot is occupied
HttpClient::Response SubmitResp = Client.Post(BlockerUrl, BuildRot13ActionPackage("Retract HTTP Test"sv));
- REQUIRE_MESSAGE(SubmitResp, fmt::format("Job submission failed: status={}", int(SubmitResp.StatusCode)));
+ REQUIRE_MESSAGE(SubmitResp, fmt::format("Job submission failed: status={}", SubmitResp.StatusCode));
const int Lsn = SubmitResp.AsObject()["lsn"sv].AsInt32();
REQUIRE_MESSAGE(Lsn != 0, "Expected non-zero LSN from job submission");
@@ -1996,7 +2517,7 @@ TEST_CASE("function.retract_http")
HttpClient::Response RetractResp = Client.Post(RetractUrl);
CHECK_MESSAGE(RetractResp.StatusCode == HttpResponseCode::OK,
fmt::format("Retract failed: status={}, body={}\nServer log:\n{}",
- int(RetractResp.StatusCode),
+ RetractResp.StatusCode,
RetractResp.ToText(),
Instance.GetLogOutput()));
@@ -2011,7 +2532,42 @@ TEST_CASE("function.retract_http")
Sleep(500);
HttpClient::Response RetractResp2 = Client.Post(RetractUrl);
CHECK_MESSAGE(RetractResp2.StatusCode == HttpResponseCode::OK,
- fmt::format("Second retract failed: status={}, body={}", int(RetractResp2.StatusCode), RetractResp2.ToText()));
+ fmt::format("Second retract failed: status={}, body={}", RetractResp2.StatusCode, RetractResp2.ToText()));
+}
+
+TEST_CASE("function.session.immediate_query_after_enqueue")
+{
+ // Verify that actions are immediately visible to GetActionResult and
+ // FindActionResult right after enqueue, without waiting for the
+ // scheduler thread to process the update.
+
+ InMemoryChunkResolver Resolver;
+ ScopedTemporaryDirectory SessionBaseDir;
+ zen::compute::ComputeServiceSession Session(Resolver);
+ Session.Ready();
+
+ CbPackage WorkerPackage = BuildWorkerPackage(TestEnv, Resolver);
+ Session.RegisterWorker(WorkerPackage);
+
+ CbObject ActionObj = BuildRot13ActionForSession("immediate-query"sv, Resolver);
+
+ auto EnqueueRes = Session.EnqueueAction(ActionObj, 0);
+ REQUIRE_MESSAGE(EnqueueRes, "Failed to enqueue action");
+
+ // Query by LSN immediately — must not return NotFound
+ CbPackage Result;
+ HttpResponseCode Code = Session.GetActionResult(EnqueueRes.Lsn, Result);
+ CHECK_MESSAGE(Code == HttpResponseCode::Accepted,
+ fmt::format("GetActionResult returned {} immediately after enqueue, expected Accepted", Code));
+
+ // Query by ActionId immediately — must not return NotFound
+ const IoHash ActionId = ActionObj.GetHash();
+ CbPackage FindResult;
+ HttpResponseCode FindCode = Session.FindActionResult(ActionId, FindResult);
+ CHECK_MESSAGE(FindCode == HttpResponseCode::Accepted,
+ fmt::format("FindActionResult returned {} immediately after enqueue, expected Accepted", FindCode));
+
+ Session.Shutdown();
}
TEST_SUITE_END();
diff --git a/src/zenserver-test/hub-tests.cpp b/src/zenserver-test/hub-tests.cpp
index 958a0b050..82dfd7e91 100644
--- a/src/zenserver-test/hub-tests.cpp
+++ b/src/zenserver-test/hub-tests.cpp
@@ -21,28 +21,91 @@
# include <zenutil/consul.h>
# include <zencore/thread.h>
# include <zencore/timer.h>
+# if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+# else
+# include <cstdlib>
+# endif
namespace zen::tests::hub {
using namespace std::literals;
-TEST_SUITE_BEGIN("server.hub");
+static const HttpClientSettings kFastTimeout{.ConnectTimeout = std::chrono::milliseconds(200)};
-TEST_CASE("hub.lifecycle.basic")
+static bool
+WaitForModuleState(HttpClient& Client, std::string_view ModuleId, std::string_view ExpectedState, int TimeoutMs = 10000)
{
+ Stopwatch Timer;
+ while (Timer.GetElapsedTimeMs() < static_cast<uint64_t>(TimeoutMs))
{
- ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
+ HttpClient::Response R = Client.Get(fmt::format("modules/{}", ModuleId));
+ if (R && R.AsObject()["state"].AsString() == ExpectedState)
+ {
+ return true;
+ }
+ Sleep(100);
+ }
+ HttpClient::Response R = Client.Get(fmt::format("modules/{}", ModuleId));
+ return R && R.AsObject()["state"].AsString() == ExpectedState;
+}
- const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady();
- CHECK(PortNumber != 0);
+// Provision a module, retrying on 409 Conflict to handle the window where an async
+// deprovision has removed the module from InstanceLookup but not yet from
+// DeprovisioningModules (which CanProvisionInstance checks).
+static HttpClient::Response
+ProvisionModule(HttpClient& Client, std::string_view ModuleId, int TimeoutMs = 10000)
+{
+ Stopwatch Timer;
+ HttpClient::Response Result;
+ do
+ {
+ Result = Client.Post(fmt::format("modules/{}/provision", ModuleId));
+ if (Result || Result.StatusCode != HttpResponseCode::Conflict)
+ {
+ return Result;
+ }
+ Sleep(100);
+ } while (Timer.GetElapsedTimeMs() < static_cast<uint64_t>(TimeoutMs));
+ return Result;
+}
- HttpClient Client(Instance.GetBaseUri() + "/hub/");
+// Wait for a port to stop accepting connections (i.e. the process has terminated).
+// Needed after async deprovision: WaitForModuleGone returns as soon as the module
+// leaves m_InstanceLookup (synchronous), but the background worker that kills the
+// process may not have run yet.
+static bool
+WaitForPortUnreachable(HttpClient& Client, std::string_view Path = "/health/", int TimeoutMs = 10000)
+{
+ Stopwatch Timer;
+ while (Timer.GetElapsedTimeMs() < static_cast<uint64_t>(TimeoutMs))
+ {
+ if (!Client.Get(Path))
+ {
+ return true;
+ }
+ Sleep(100);
+ }
+ return !Client.Get(Path);
+}
- HttpClient::Response Result = Client.Get("status");
- CHECK(Result);
+static bool
+WaitForModuleGone(HttpClient& Client, std::string_view ModuleId, int TimeoutMs = 10000)
+{
+ Stopwatch Timer;
+ while (Timer.GetElapsedTimeMs() < static_cast<uint64_t>(TimeoutMs))
+ {
+ if (Client.Get(fmt::format("modules/{}", ModuleId)).StatusCode == HttpResponseCode::NotFound)
+ {
+ return true;
+ }
+ Sleep(100);
}
+ return Client.Get(fmt::format("modules/{}", ModuleId)).StatusCode == HttpResponseCode::NotFound;
}
+TEST_SUITE_BEGIN("server.hub");
+
TEST_CASE("hub.lifecycle.children")
{
ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
@@ -50,186 +113,242 @@ TEST_CASE("hub.lifecycle.children")
const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady("--hub-instance-corelimit=2 --hub-instance-http-threads=6");
REQUIRE(PortNumber != 0);
- SUBCASE("spawn")
- {
- HttpClient Client(Instance.GetBaseUri() + "/hub/");
+ HttpClient Client(Instance.GetBaseUri() + "/hub/", kFastTimeout);
+ // Verify the hub starts with no modules
+ {
HttpClient::Response Result = Client.Get("status");
REQUIRE(Result);
+ CHECK_EQ(Result.AsObject()["modules"].AsArrayView().Num(), 0u);
+ }
- {
- Result = Client.Post("modules/abc/provision");
- REQUIRE(Result);
+ HttpClient::Response Result;
- CbObject AbcResult = Result.AsObject();
- CHECK(AbcResult["moduleId"].AsString() == "abc"sv);
- const uint16_t AbcPort = AbcResult["port"].AsUInt16(0);
- CHECK_NE(AbcPort, 0);
+ uint16_t AbcPort = 0;
+ uint16_t DefPort = 0;
- // This should be a fresh instance with no contents
+ {
+ Result = Client.Post("modules/abc/provision");
+ REQUIRE(Result);
- HttpClient AbcClient(fmt::format("http://localhost:{}", AbcPort));
+ CbObject AbcResult = Result.AsObject();
+ CHECK(AbcResult["moduleId"].AsString() == "abc"sv);
+ AbcPort = AbcResult["port"].AsUInt16(0);
+ CHECK_NE(AbcPort, 0);
- Result = AbcClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
+ REQUIRE(WaitForModuleState(Client, "abc", "provisioned"));
- Result = AbcClient.Put("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567",
- IoBufferBuilder::MakeFromMemory(MakeMemoryView("abcdef"sv)));
- CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
- }
+ // This should be a fresh instance with no contents
- {
- Result = Client.Post("modules/def/provision");
- REQUIRE(Result);
+ HttpClient AbcClient(fmt::format("http://localhost:{}", AbcPort), kFastTimeout);
+ CHECK(AbcClient.Get("/health/"));
- CbObject DefResult = Result.AsObject();
- CHECK(DefResult["moduleId"].AsString() == "def"sv);
- const uint16_t DefPort = DefResult["port"].AsUInt16(0);
- REQUIRE_NE(DefPort, 0);
+ Result = AbcClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
- // This should be a fresh instance with no contents
+ Result = AbcClient.Put("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567",
+ IoBufferBuilder::MakeFromMemory(MakeMemoryView("abcdef"sv)));
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
+ }
- HttpClient DefClient(fmt::format("http://localhost:{}", DefPort));
+ {
+ Result = Client.Post("modules/def/provision");
+ REQUIRE(Result);
- Result = DefClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
+ CbObject DefResult = Result.AsObject();
+ CHECK(DefResult["moduleId"].AsString() == "def"sv);
+ DefPort = DefResult["port"].AsUInt16(0);
+ REQUIRE_NE(DefPort, 0);
- Result = DefClient.Put("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567",
- IoBufferBuilder::MakeFromMemory(MakeMemoryView("AbcDef"sv)));
- CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
- }
+ REQUIRE(WaitForModuleState(Client, "def", "provisioned"));
- // this should be rejected because of the invalid module id
- Result = Client.Post("modules/!!!!!/provision");
- CHECK(!Result);
+ // This should be a fresh instance with no contents
- Result = Client.Post("modules/ghi/provision");
- REQUIRE(Result);
+ HttpClient DefClient(fmt::format("http://localhost:{}", DefPort), kFastTimeout);
+ CHECK(DefClient.Get("/health/"));
- // Tear down instances
+ Result = DefClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
- Result = Client.Post("modules/abc/deprovision");
- REQUIRE(Result);
+ Result = DefClient.Put("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567",
+ IoBufferBuilder::MakeFromMemory(MakeMemoryView("AbcDef"sv)));
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
+ }
- Result = Client.Post("modules/def/deprovision");
- REQUIRE(Result);
+ // this should be rejected because of the invalid module id
+ Result = Client.Post("modules/!!!!!/provision");
+ CHECK(!Result);
+
+ Result = Client.Post("modules/ghi/provision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleState(Client, "ghi", "provisioned"));
+
+ // Tear down instances
+
+ Result = Client.Post("modules/abc/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "abc"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", AbcPort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
- Result = Client.Post("modules/ghi/deprovision");
+ Result = Client.Post("modules/def/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "def"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", DefPort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
+
+ Result = Client.Post("modules/ghi/deprovision");
+ REQUIRE(Result);
+
+ // re-provision to verify that (de)hydration preserved state
+ {
+ Result = ProvisionModule(Client, "abc");
REQUIRE(Result);
- // re-provision to verify that (de)hydration preserved state
- {
- Result = Client.Post("modules/abc/provision");
- REQUIRE(Result);
+ CbObject AbcResult = Result.AsObject();
+ CHECK(AbcResult["moduleId"].AsString() == "abc"sv);
+ AbcPort = AbcResult["port"].AsUInt16(0);
+ REQUIRE_NE(AbcPort, 0);
- CbObject AbcResult = Result.AsObject();
- CHECK(AbcResult["moduleId"].AsString() == "abc"sv);
- const uint16_t AbcPort = AbcResult["port"].AsUInt16(0);
- REQUIRE_NE(AbcPort, 0);
+ REQUIRE(WaitForModuleState(Client, "abc", "provisioned"));
- // This should contain the content from the previous run
+ // This should contain the content from the previous run
- HttpClient AbcClient(fmt::format("http://localhost:{}", AbcPort));
+ HttpClient AbcClient(fmt::format("http://localhost:{}", AbcPort), kFastTimeout);
+ CHECK(AbcClient.Get("/health/"));
- Result = AbcClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ Result = AbcClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
- CHECK_EQ(Result.AsText(), "abcdef"sv);
+ CHECK_EQ(Result.AsText(), "abcdef"sv);
- Result = AbcClient.Put("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567",
- IoBufferBuilder::MakeFromMemory(MakeMemoryView("ghijklmnop"sv)));
- CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
- }
+ Result = AbcClient.Put("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567",
+ IoBufferBuilder::MakeFromMemory(MakeMemoryView("ghijklmnop"sv)));
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
+ }
- {
- Result = Client.Post("modules/def/provision");
- REQUIRE(Result);
+ {
+ Result = ProvisionModule(Client, "def");
+ REQUIRE(Result);
- CbObject DefResult = Result.AsObject();
- CHECK(DefResult["moduleId"].AsString() == "def"sv);
- const uint16_t DefPort = DefResult["port"].AsUInt16(0);
- REQUIRE_NE(DefPort, 0);
+ CbObject DefResult = Result.AsObject();
+ CHECK(DefResult["moduleId"].AsString() == "def"sv);
+ DefPort = DefResult["port"].AsUInt16(0);
+ REQUIRE_NE(DefPort, 0);
- // This should contain the content from the previous run
+ REQUIRE(WaitForModuleState(Client, "def", "provisioned"));
- HttpClient DefClient(fmt::format("http://localhost:{}", DefPort));
+ // This should contain the content from the previous run
- Result = DefClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ HttpClient DefClient(fmt::format("http://localhost:{}", DefPort), kFastTimeout);
+ CHECK(DefClient.Get("/health/"));
- CHECK_EQ(Result.AsText(), "AbcDef"sv);
+ Result = DefClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
- Result = DefClient.Put("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567",
- IoBufferBuilder::MakeFromMemory(MakeMemoryView("GhijklmNop"sv)));
- CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
- }
+ CHECK_EQ(Result.AsText(), "AbcDef"sv);
- Result = Client.Post("modules/abc/deprovision");
- REQUIRE(Result);
+ Result = DefClient.Put("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567",
+ IoBufferBuilder::MakeFromMemory(MakeMemoryView("GhijklmNop"sv)));
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
+ }
+
+ Result = Client.Post("modules/abc/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "abc"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", AbcPort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
+
+ Result = Client.Post("modules/def/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "def"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", DefPort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
- Result = Client.Post("modules/def/deprovision");
+ // re-provision to verify that (de)hydration preserved state, including
+ // state which was generated after the very first dehydration
+ {
+ Result = ProvisionModule(Client, "abc");
REQUIRE(Result);
- // re-provision to verify that (de)hydration preserved state, including
- // state which was generated after the very first dehydration
- {
- Result = Client.Post("modules/abc/provision");
- REQUIRE(Result);
+ CbObject AbcResult = Result.AsObject();
+ CHECK(AbcResult["moduleId"].AsString() == "abc"sv);
+ AbcPort = AbcResult["port"].AsUInt16(0);
+ REQUIRE_NE(AbcPort, 0);
- CbObject AbcResult = Result.AsObject();
- CHECK(AbcResult["moduleId"].AsString() == "abc"sv);
- const uint16_t AbcPort = AbcResult["port"].AsUInt16(0);
- REQUIRE_NE(AbcPort, 0);
+ REQUIRE(WaitForModuleState(Client, "abc", "provisioned"));
- // This should contain the content from the previous two runs
+ // This should contain the content from the previous two runs
- HttpClient AbcClient(fmt::format("http://localhost:{}", AbcPort));
+ HttpClient AbcClient(fmt::format("http://localhost:{}", AbcPort), kFastTimeout);
+ CHECK(AbcClient.Get("/health/"));
- Result = AbcClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ Result = AbcClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
- CHECK_EQ(Result.AsText(), "abcdef"sv);
+ CHECK_EQ(Result.AsText(), "abcdef"sv);
- Result = AbcClient.Get("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ Result = AbcClient.Get("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
- CHECK_EQ(Result.AsText(), "ghijklmnop"sv);
- }
+ CHECK_EQ(Result.AsText(), "ghijklmnop"sv);
+ }
- {
- Result = Client.Post("modules/def/provision");
- REQUIRE(Result);
+ {
+ Result = ProvisionModule(Client, "def");
+ REQUIRE(Result);
- CbObject DefResult = Result.AsObject();
- REQUIRE(DefResult["moduleId"].AsString() == "def"sv);
- const uint16_t DefPort = DefResult["port"].AsUInt16(0);
- REQUIRE_NE(DefPort, 0);
+ CbObject DefResult = Result.AsObject();
+ REQUIRE(DefResult["moduleId"].AsString() == "def"sv);
+ DefPort = DefResult["port"].AsUInt16(0);
+ REQUIRE_NE(DefPort, 0);
- // This should contain the content from the previous two runs
+ REQUIRE(WaitForModuleState(Client, "def", "provisioned"));
- HttpClient DefClient(fmt::format("http://localhost:{}", DefPort));
+ // This should contain the content from the previous two runs
- Result = DefClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ HttpClient DefClient(fmt::format("http://localhost:{}", DefPort), kFastTimeout);
+ CHECK(DefClient.Get("/health/"));
- CHECK_EQ(Result.AsText(), "AbcDef"sv);
+ Result = DefClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
- Result = DefClient.Get("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567");
- CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ CHECK_EQ(Result.AsText(), "AbcDef"sv);
- CHECK_EQ(Result.AsText(), "GhijklmNop"sv);
- }
+ Result = DefClient.Get("/z$/ns1/b/1123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
- Result = Client.Post("modules/abc/deprovision");
- REQUIRE(Result);
+ CHECK_EQ(Result.AsText(), "GhijklmNop"sv);
+ }
- Result = Client.Post("modules/def/deprovision");
- REQUIRE(Result);
+ Result = Client.Post("modules/abc/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "abc"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", AbcPort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
- // final sanity check that the hub is still responsive
- Result = Client.Get("status");
- CHECK(Result);
+ Result = Client.Post("modules/def/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "def"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", DefPort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
}
+
+ // final sanity check that the hub is still responsive and all modules are gone
+ Result = Client.Get("status");
+ REQUIRE(Result);
+ CHECK_EQ(Result.AsObject()["modules"].AsArrayView().Num(), 0u);
}
static bool
@@ -258,7 +377,7 @@ TEST_CASE("hub.consul.kv")
consul::ConsulProcess ConsulProc;
ConsulProc.SpawnConsulAgent();
- consul::ConsulClient Client("http://localhost:8500/");
+ consul::ConsulClient Client({.BaseUri = "http://localhost:8500/"});
Client.SetKeyValue("zen/hub/testkey", "testvalue");
std::string RetrievedValue = Client.GetKeyValue("zen/hub/testkey");
@@ -275,11 +394,93 @@ TEST_CASE("hub.consul.hub.registration")
ConsulProc.SpawnConsulAgent();
ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
- const uint16_t PortNumber =
- Instance.SpawnServerAndWaitUntilReady("--consul-endpoint=http://localhost:8500/ --instance-id=test-instance");
+ const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady(
+ "--consul-endpoint=http://localhost:8500/ --instance-id=test-instance "
+ "--consul-health-interval-seconds=5 --consul-deregister-after-seconds=60");
+ REQUIRE(PortNumber != 0);
+
+ consul::ConsulClient Client({.BaseUri = "http://localhost:8500/"});
+ REQUIRE(WaitForConsulService(Client, "zen-hub-test-instance", true, 5000));
+
+ // Verify custom intervals flowed through to the registered check
+ {
+ std::string JsonError;
+ CbFieldIterator ChecksRoot = LoadCompactBinaryFromJson(Client.GetAgentChecksJson(), JsonError);
+ REQUIRE(JsonError.empty());
+
+ CbObjectView HubCheck;
+ for (CbFieldView F : ChecksRoot)
+ {
+ if (!F.IsObject())
+ {
+ continue;
+ }
+ for (CbFieldView C : F.AsObjectView())
+ {
+ CbObjectView Check = C.AsObjectView();
+ if (Check["ServiceID"sv].AsString() == "zen-hub-test-instance"sv)
+ {
+ HubCheck = Check;
+ break;
+ }
+ }
+ }
+ REQUIRE(HubCheck);
+ // Consul does not reflect DeregisterCriticalServiceAfter back in /v1/agent/checks for
+ // service-embedded checks; Definition is always an empty object. Only Type and Interval
+ // are accessible at the top level.
+ CHECK_EQ(HubCheck["Type"sv].AsString(), "http"sv);
+ CHECK_EQ(HubCheck["Interval"sv].AsString(), "5s"sv);
+ }
+
+ Instance.Shutdown();
+
+ CHECK(!Client.HasService("zen-hub-test-instance"));
+
+ ConsulProc.StopConsulAgent();
+}
+
+TEST_CASE("hub.consul.hub.registration.token")
+{
+ // Set an env var that the server will read its Consul token from.
+ // Children inherit parent environment, so the spawned server will see it.
+ constexpr const char* TokenEnvVarName = "ZEN_TEST_CONSUL_TOKEN";
+ constexpr const char* TokenValue = "test-token-value";
+# if ZEN_PLATFORM_WINDOWS
+ char PrevBuf[1024] = {};
+ DWORD PrevLen = GetEnvironmentVariableA(TokenEnvVarName, PrevBuf, sizeof(PrevBuf));
+ REQUIRE(PrevLen < sizeof(PrevBuf));
+ SetEnvironmentVariableA(TokenEnvVarName, TokenValue);
+ auto EnvCleanup = MakeGuard([PrevEnvValue = std::string(PrevBuf, PrevLen), HadPrevToken = PrevLen > 0] {
+ SetEnvironmentVariableA(TokenEnvVarName, HadPrevToken ? PrevEnvValue.c_str() : nullptr);
+ });
+# else
+ const char* PrevEnvPtr = getenv(TokenEnvVarName);
+ setenv(TokenEnvVarName, TokenValue, /*overwrite=*/1);
+ auto EnvCleanup = MakeGuard([PrevEnvValue = std::string(PrevEnvPtr ? PrevEnvPtr : ""), HadPrevToken = PrevEnvPtr != nullptr] {
+ if (HadPrevToken)
+ {
+ setenv(TokenEnvVarName, PrevEnvValue.c_str(), /*overwrite=*/1);
+ }
+ else
+ {
+ unsetenv(TokenEnvVarName);
+ }
+ });
+# endif
+
+ consul::ConsulProcess ConsulProc;
+ ConsulProc.SpawnConsulAgent();
+
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
+ const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady(
+ "--consul-endpoint=http://localhost:8500/ --instance-id=test-instance "
+ "--consul-token-env=ZEN_TEST_CONSUL_TOKEN");
REQUIRE(PortNumber != 0);
- consul::ConsulClient Client("http://localhost:8500/");
+ // Use a plain client -- dev-mode Consul doesn't enforce ACLs, but the
+ // server has exercised the ConsulTokenEnv -> GetEnvVariable -> ConsulClient path.
+ consul::ConsulClient Client({.BaseUri = "http://localhost:8500/"});
REQUIRE(WaitForConsulService(Client, "zen-hub-test-instance", true, 5000));
@@ -300,20 +501,24 @@ TEST_CASE("hub.consul.provision.registration")
Instance.SpawnServerAndWaitUntilReady("--consul-endpoint=http://localhost:8500/ --instance-id=test-instance");
REQUIRE(PortNumber != 0);
- consul::ConsulClient Client("http://localhost:8500/");
+ consul::ConsulClient Client({.BaseUri = "http://localhost:8500/"});
REQUIRE(WaitForConsulService(Client, "zen-hub-test-instance", true, 5000));
- HttpClient HubClient(Instance.GetBaseUri() + "/hub/");
+ HttpClient HubClient(Instance.GetBaseUri() + "/hub/", kFastTimeout);
HttpClient::Response Result = HubClient.Post("modules/testmod/provision");
REQUIRE(Result);
- CHECK(Client.HasService("testmod"));
- {
- const uint16_t ModulePort = Result.AsObject()["port"].AsUInt16(0);
- REQUIRE(ModulePort != 0);
+ // Service is registered in Consul during Provisioning (before the child process starts),
+ // so this returns as soon as the state transition fires, not when the server is ready.
+ REQUIRE(WaitForConsulService(Client, "testmod", true, 10000));
+ const uint16_t ModulePort = Result.AsObject()["port"].AsUInt16(0);
+ REQUIRE(ModulePort != 0);
+
+ // Consul fields are set during Provisioning and can be verified before the server is ready.
+ {
std::string JsonError;
CbFieldIterator ServicesRoot = LoadCompactBinaryFromJson(Client.GetAgentServicesJson(), JsonError);
REQUIRE(JsonError.empty());
@@ -328,7 +533,7 @@ TEST_CASE("hub.consul.provision.registration")
}
REQUIRE(ServicesMap);
- // Verify fields registered by OnProvisioned
+ // Verify fields registered by OnModuleStateChanged
{
CbObjectView ModService = ServicesMap["testmod"].AsObjectView();
CHECK_EQ(ModService["ID"sv].AsString(), "testmod"sv);
@@ -365,10 +570,82 @@ TEST_CASE("hub.consul.provision.registration")
CHECK_EQ(HubService["Service"sv].AsString(), "zen-hub"sv);
CHECK_EQ(HubService["Port"sv].AsDouble(0), double(PortNumber));
}
+
+ // Verify hub health check endpoint URL (registered from startup with an active interval)
+ {
+ std::string ChecksJsonError;
+ CbFieldIterator ChecksRoot = LoadCompactBinaryFromJson(Client.GetAgentChecksJson(), ChecksJsonError);
+ REQUIRE(ChecksJsonError.empty());
+
+ CbObjectView HubCheck;
+ for (CbFieldView F : ChecksRoot)
+ {
+ if (!F.IsObject())
+ {
+ continue;
+ }
+ for (CbFieldView C : F.AsObjectView())
+ {
+ CbObjectView Check = C.AsObjectView();
+ if (Check["ServiceID"sv].AsString() == "zen-hub-test-instance"sv)
+ {
+ HubCheck = Check;
+ }
+ }
+ }
+ REQUIRE(HubCheck);
+ // Consul does not reflect HTTP URL back in /v1/agent/checks for service-embedded checks.
+ CHECK_EQ(HubCheck["Type"sv].AsString(), "http"sv);
+ }
}
- Result = HubClient.Post("modules/testmod/deprovision");
- REQUIRE(Result);
+ // Wait for Provisioned before touching the module's HTTP endpoint.
+ REQUIRE(WaitForModuleState(HubClient, "testmod", "provisioned"));
+
+ // Verify module health check endpoint URL. No health check is registered during Provisioning
+ // (to avoid Consul marking the service critical before the child process is ready); it is added
+ // on transition to Provisioned.
+ {
+ std::string ChecksJsonError;
+ CbFieldIterator ChecksRoot = LoadCompactBinaryFromJson(Client.GetAgentChecksJson(), ChecksJsonError);
+ REQUIRE(ChecksJsonError.empty());
+
+ CbObjectView ModCheck;
+ for (CbFieldView F : ChecksRoot)
+ {
+ if (!F.IsObject())
+ {
+ continue;
+ }
+ for (CbFieldView C : F.AsObjectView())
+ {
+ CbObjectView Check = C.AsObjectView();
+ if (Check["ServiceID"sv].AsString() == "testmod"sv)
+ {
+ ModCheck = Check;
+ }
+ }
+ }
+ REQUIRE(ModCheck);
+ // Consul does not reflect HTTP URL back in /v1/agent/checks for service-embedded checks.
+ CHECK_EQ(ModCheck["Type"sv].AsString(), "http"sv);
+ }
+
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
+
+ {
+ Result = HubClient.Post("modules/testmod/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForConsulService(Client, "testmod", false, 10000));
+
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
+ }
CHECK(!Client.HasService("testmod"));
@@ -377,6 +654,182 @@ TEST_CASE("hub.consul.provision.registration")
ConsulProc.StopConsulAgent();
}
+TEST_CASE("hub.hibernate.lifecycle")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
+ const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady("--hub-instance-corelimit=2 --hub-instance-http-threads=6");
+ REQUIRE(PortNumber != 0);
+
+ HttpClient Client(Instance.GetBaseUri() + "/hub/", kFastTimeout);
+
+ // Provision
+ HttpClient::Response Result = Client.Post("modules/testmod/provision");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ CHECK_EQ(Result.AsObject()["moduleId"].AsString(), "testmod"sv);
+ const uint16_t ModulePort = Result.AsObject()["port"].AsUInt16(0);
+ REQUIRE_NE(ModulePort, 0);
+
+ REQUIRE(WaitForModuleState(Client, "testmod", "provisioned"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+
+ // Write data to verify it survives the hibernate/wake cycle
+ Result = ModClient.Put("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567",
+ IoBufferBuilder::MakeFromMemory(MakeMemoryView("hibernatetest"sv)));
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Created);
+ }
+
+ // Hibernate - state should become "hibernated", server should be unreachable
+ Result = Client.Post("modules/testmod/hibernate");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ CHECK_EQ(Result.AsObject()["moduleId"].AsString(), "testmod"sv);
+
+ REQUIRE(WaitForModuleState(Client, "testmod", "hibernated"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
+
+ // Wake - state should return to "provisioned", server should be reachable, data should be intact
+ Result = Client.Post("modules/testmod/wake");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ CHECK_EQ(Result.AsObject()["moduleId"].AsString(), "testmod"sv);
+
+ REQUIRE(WaitForModuleState(Client, "testmod", "provisioned"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+
+ Result = ModClient.Get("/z$/ns1/b/0123456789abcdef0123456789abcdef01234567");
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+ CHECK_EQ(Result.AsText(), "hibernatetest"sv);
+ }
+
+ // Deprovision - server should become unreachable
+ Result = Client.Post("modules/testmod/deprovision");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ REQUIRE(WaitForModuleGone(Client, "testmod"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
+
+ // Re-provision - server should be reachable on its (potentially new) port
+ Result = ProvisionModule(Client, "testmod");
+ REQUIRE(Result);
+ CHECK_EQ(Result.AsObject()["moduleId"].AsString(), "testmod"sv);
+ const uint16_t ModulePort2 = Result.AsObject()["port"].AsUInt16(0);
+ REQUIRE_NE(ModulePort2, 0);
+ REQUIRE(WaitForModuleState(Client, "testmod", "provisioned"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort2), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
+
+ // Final deprovision - server should become unreachable
+ Result = Client.Post("modules/testmod/deprovision");
+ REQUIRE(Result);
+ REQUIRE(WaitForModuleGone(Client, "testmod"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ModulePort2), kFastTimeout);
+ CHECK(WaitForPortUnreachable(ModClient));
+ }
+}
+
+TEST_CASE("hub.hibernate.errors")
+{
+ ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kHubServer);
+ const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady("--hub-instance-corelimit=2 --hub-instance-http-threads=6");
+ REQUIRE(PortNumber != 0);
+
+ HttpClient Client(Instance.GetBaseUri() + "/hub/", kFastTimeout);
+
+ // Hibernate/wake on an unknown module id should return 404
+ HttpClient::Response Result = Client.Post("modules/unknown/hibernate");
+ CHECK(!Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
+
+ Result = Client.Post("modules/unknown/wake");
+ CHECK(!Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
+
+ Result = Client.Post("modules/unknown/deprovision");
+ CHECK(!Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
+
+ Result = Client.Delete("modules/unknown");
+ CHECK(!Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::NotFound);
+
+ // Double-provision: second call while first is in-flight returns 202 Accepted with the same port.
+ Result = Client.Post("modules/errmod/provision");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ const uint16_t ErrmodPort = Result.AsObject()["port"].AsUInt16(0);
+ REQUIRE_NE(ErrmodPort, 0);
+
+ // Provisioning the same module while in-flight returns 202 Accepted with the allocated port.
+ // Evaluated synchronously before WorkerPool dispatch, so safe regardless of timing.
+ Result = Client.Post("modules/errmod/provision");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ CHECK_EQ(Result.AsObject()["port"].AsUInt16(0), ErrmodPort);
+
+ REQUIRE(WaitForModuleState(Client, "errmod", "provisioned"));
+
+ // Already provisioned: provision and wake both return 200 Completed.
+ Result = Client.Post("modules/errmod/provision");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+
+ Result = Client.Post("modules/errmod/wake");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+
+ // Double-hibernate: second call while first is in-flight returns 202 Accepted.
+ Result = Client.Post("modules/errmod/hibernate");
+ REQUIRE(Result);
+
+ Result = Client.Post("modules/errmod/hibernate");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+
+ REQUIRE(WaitForModuleState(Client, "errmod", "hibernated"));
+
+ // Already hibernated: hibernate returns 200 Completed.
+ Result = Client.Post("modules/errmod/hibernate");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::OK);
+
+ // Double-wake: second call while first is in-flight returns 202 Accepted.
+ Result = Client.Post("modules/errmod/wake");
+ REQUIRE(Result);
+
+ Result = Client.Post("modules/errmod/wake");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+
+ // Double-deprovision: second call while first is in-flight returns 202 Accepted.
+ // errmod2 is a fresh module to avoid waiting on the still-waking errmod.
+ Result = Client.Post("modules/errmod2/provision");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+ REQUIRE(WaitForModuleState(Client, "errmod2", "provisioned"));
+
+ Result = Client.Post("modules/errmod2/deprovision");
+ REQUIRE(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+
+ Result = Client.Post("modules/errmod2/deprovision");
+ CHECK(Result);
+ CHECK_EQ(Result.StatusCode, HttpResponseCode::Accepted);
+}
+
TEST_SUITE_END();
} // namespace zen::tests::hub
diff --git a/src/zenserver-test/process-tests.cpp b/src/zenserver-test/process-tests.cpp
new file mode 100644
index 000000000..ae11bb294
--- /dev/null
+++ b/src/zenserver-test/process-tests.cpp
@@ -0,0 +1,283 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zencore/zencore.h>
+
+#if ZEN_WITH_TESTS
+
+# include "zenserver-test.h"
+
+# include <zencore/filesystem.h>
+# include <zencore/process.h>
+# include <zencore/testing.h>
+
+# if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+# else
+# include <unistd.h>
+# endif
+
+namespace zen::tests {
+
+using namespace std::literals;
+
+static std::filesystem::path
+GetAppStubPath()
+{
+ return TestEnv.ProgramBaseDir() / ("zentest-appstub" ZEN_EXE_SUFFIX_LITERAL);
+}
+
+// Read all available data from the read end of a StdoutPipeHandles.
+// Must be called after CloseWriteEnd() so that the read will see EOF.
+static std::string
+ReadAllFromPipe(StdoutPipeHandles& Pipe)
+{
+ std::string Result;
+ char Buffer[4096];
+
+# if ZEN_PLATFORM_WINDOWS
+ DWORD BytesRead = 0;
+ while (::ReadFile(Pipe.ReadHandle, Buffer, sizeof(Buffer), &BytesRead, nullptr) && BytesRead > 0)
+ {
+ Result.append(Buffer, BytesRead);
+ }
+# else
+ ssize_t BytesRead = 0;
+ while ((BytesRead = read(Pipe.ReadFd, Buffer, sizeof(Buffer))) > 0)
+ {
+ Result.append(Buffer, static_cast<size_t>(BytesRead));
+ }
+# endif
+
+ return Result;
+}
+
+TEST_SUITE_BEGIN("server.process");
+
+//////////////////////////////////////////////////////////////////////////
+
+TEST_CASE("pipe.capture_stdout")
+{
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+
+ const std::string ExpectedOutput = "hello_from_pipe_test";
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CommandLine = fmt::format("zentest-appstub -echo={}", ExpectedOutput);
+
+ CreateProcOptions Options;
+ Options.StdoutPipe = &Pipe;
+
+ ProcessHandle Process(CreateProc(AppStub, CommandLine, Options));
+
+ // Close the write end, then drain before Wait() to avoid deadlock if output fills the pipe buffer.
+ Pipe.CloseWriteEnd();
+
+ std::string Output = ReadAllFromPipe(Pipe);
+
+ Process.Wait();
+
+ // The appstub also prints "[zentest] exiting with exit code: 0\n"
+ CHECK(Output.find(ExpectedOutput) != std::string::npos);
+ CHECK_EQ(Process.GetExitCode(), 0);
+}
+
+TEST_CASE("pipe.capture_multiline")
+{
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CommandLine = "zentest-appstub -echo=line1 -echo=line2 -echo=line3";
+
+ CreateProcOptions Options;
+ Options.StdoutPipe = &Pipe;
+
+ ProcessHandle Process(CreateProc(AppStub, CommandLine, Options));
+
+ Pipe.CloseWriteEnd();
+
+ std::string Output = ReadAllFromPipe(Pipe);
+
+ Process.Wait();
+
+ CHECK(Output.find("line1") != std::string::npos);
+ CHECK(Output.find("line2") != std::string::npos);
+ CHECK(Output.find("line3") != std::string::npos);
+ CHECK_EQ(Process.GetExitCode(), 0);
+}
+
+TEST_CASE("pipe.raii_cleanup")
+{
+ // Verify that StdoutPipeHandles cleans up handles when it goes out of scope
+ // (no leaked handles). We can't directly assert on handle counts, but we can
+ // verify that creating and destroying many pipes doesn't fail.
+ for (int i = 0; i < 100; ++i)
+ {
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+ // Pipe goes out of scope here — destructor should close both ends
+ }
+}
+
+TEST_CASE("pipe.move_semantics")
+{
+ StdoutPipeHandles Original;
+ REQUIRE(CreateStdoutPipe(Original));
+
+ // Move-construct a new pipe from Original
+ StdoutPipeHandles Moved(std::move(Original));
+
+# if ZEN_PLATFORM_WINDOWS
+ CHECK(Moved.ReadHandle != nullptr);
+ CHECK(Moved.WriteHandle != nullptr);
+ CHECK(Original.ReadHandle == nullptr);
+ CHECK(Original.WriteHandle == nullptr);
+# else
+ CHECK(Moved.ReadFd >= 0);
+ CHECK(Moved.WriteFd >= 0);
+ CHECK(Original.ReadFd == -1);
+ CHECK(Original.WriteFd == -1);
+# endif
+
+ // Move-assign
+ StdoutPipeHandles Assigned;
+ Assigned = std::move(Moved);
+
+# if ZEN_PLATFORM_WINDOWS
+ CHECK(Assigned.ReadHandle != nullptr);
+ CHECK(Assigned.WriteHandle != nullptr);
+ CHECK(Moved.ReadHandle == nullptr);
+ CHECK(Moved.WriteHandle == nullptr);
+# else
+ CHECK(Assigned.ReadFd >= 0);
+ CHECK(Assigned.WriteFd >= 0);
+ CHECK(Moved.ReadFd == -1);
+ CHECK(Moved.WriteFd == -1);
+# endif
+
+ // Assigned goes out of scope — destructor closes handles
+}
+
+TEST_CASE("pipe.close_is_idempotent")
+{
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+
+ Pipe.Close();
+ // Calling Close again should be safe (no double-close)
+ Pipe.Close();
+
+# if ZEN_PLATFORM_WINDOWS
+ CHECK(Pipe.ReadHandle == nullptr);
+ CHECK(Pipe.WriteHandle == nullptr);
+# else
+ CHECK(Pipe.ReadFd == -1);
+ CHECK(Pipe.WriteFd == -1);
+# endif
+}
+
+TEST_CASE("pipe.close_write_end_only")
+{
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+
+ Pipe.CloseWriteEnd();
+
+# if ZEN_PLATFORM_WINDOWS
+ CHECK(Pipe.ReadHandle != nullptr);
+ CHECK(Pipe.WriteHandle == nullptr);
+# else
+ CHECK(Pipe.ReadFd >= 0);
+ CHECK(Pipe.WriteFd == -1);
+# endif
+
+ // Remaining read handle cleaned up by destructor
+}
+
+TEST_CASE("pipe.capture_with_nonzero_exit")
+{
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CommandLine = "zentest-appstub -echo=before_exit -f=42";
+
+ CreateProcOptions Options;
+ Options.StdoutPipe = &Pipe;
+
+ ProcessHandle Process(CreateProc(AppStub, CommandLine, Options));
+
+ Pipe.CloseWriteEnd();
+
+ std::string Output = ReadAllFromPipe(Pipe);
+
+ Process.Wait();
+
+ CHECK(Output.find("before_exit") != std::string::npos);
+ CHECK_EQ(Process.GetExitCode(), 42);
+}
+
+TEST_CASE("pipe.stderr_on_shared_pipe")
+{
+ StdoutPipeHandles Pipe;
+ REQUIRE(CreateStdoutPipe(Pipe));
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CommandLine = "zentest-appstub -echo=from_stdout -echoerr=from_stderr";
+
+ CreateProcOptions Options;
+ Options.StdoutPipe = &Pipe;
+
+ ProcessHandle Process(CreateProc(AppStub, CommandLine, Options));
+
+ Pipe.CloseWriteEnd();
+
+ std::string Output = ReadAllFromPipe(Pipe);
+
+ Process.Wait();
+
+ // Both stdout and stderr content should appear on the shared pipe
+ CHECK(Output.find("from_stdout") != std::string::npos);
+ CHECK(Output.find("from_stderr") != std::string::npos);
+ CHECK_EQ(Process.GetExitCode(), 0);
+}
+
+TEST_CASE("pipe.separate_stderr")
+{
+ StdoutPipeHandles StdoutPipe;
+ StdoutPipeHandles StderrPipe;
+ REQUIRE(CreateStdoutPipe(StdoutPipe));
+ REQUIRE(CreateStdoutPipe(StderrPipe));
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CommandLine = "zentest-appstub -echo=on_stdout -echoerr=on_stderr";
+
+ CreateProcOptions Options;
+ Options.StdoutPipe = &StdoutPipe;
+ Options.StderrPipe = &StderrPipe;
+
+ ProcessHandle Process(CreateProc(AppStub, CommandLine, Options));
+
+ StdoutPipe.CloseWriteEnd();
+ StderrPipe.CloseWriteEnd();
+
+ std::string StdoutOutput = ReadAllFromPipe(StdoutPipe);
+ std::string StderrOutput = ReadAllFromPipe(StderrPipe);
+
+ Process.Wait();
+
+ CHECK(StdoutOutput.find("on_stdout") != std::string::npos);
+ CHECK(StderrOutput.find("on_stderr") != std::string::npos);
+ // Verify separation: stderr content should NOT appear in stdout pipe
+ CHECK(StdoutOutput.find("on_stderr") == std::string::npos);
+ CHECK(StderrOutput.find("on_stdout") == std::string::npos);
+ CHECK_EQ(Process.GetExitCode(), 0);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+TEST_SUITE_END();
+
+} // namespace zen::tests
+
+#endif
diff --git a/src/zenserver-test/projectstore-tests.cpp b/src/zenserver-test/projectstore-tests.cpp
index 5cc75c590..cec453511 100644
--- a/src/zenserver-test/projectstore-tests.cpp
+++ b/src/zenserver-test/projectstore-tests.cpp
@@ -22,6 +22,7 @@ ZEN_THIRD_PARTY_INCLUDES_START
ZEN_THIRD_PARTY_INCLUDES_END
# include <random>
+# include <thread>
namespace zen::tests {
@@ -340,6 +341,102 @@ TEST_CASE("project.basic")
ZEN_INFO("+++++++");
}
+ SUBCASE("snapshot zero byte file")
+ {
+ // A zero-byte file referenced in an oplog entry must survive a
+ // snapshot: the file is read, compressed, stored in CidStore, and
+ // the oplog is rewritten with a BinaryAttachment reference. After
+ // the snapshot the chunk must be retrievable and decompress to an
+ // empty payload.
+
+ std::filesystem::path EmptyFileRelPath = std::filesystem::path("zerobyte_snapshot_test") / "empty.bin";
+ std::filesystem::path EmptyFileAbsPath = RootPath / EmptyFileRelPath;
+ CreateDirectories(MakeSafeAbsolutePath(EmptyFileAbsPath.parent_path()));
+ // Create a zero-byte file on disk.
+ WriteFile(MakeSafeAbsolutePath(EmptyFileAbsPath), IoBuffer{});
+ REQUIRE(IsFile(MakeSafeAbsolutePath(EmptyFileAbsPath)));
+
+ const std::string_view EmptyChunkId{
+ "00000000"
+ "00000000"
+ "00030000"};
+ auto EmptyFileOid = zen::Oid::FromHexString(EmptyChunkId);
+
+ zen::CbObjectWriter OpWriter;
+ OpWriter << "key"
+ << "zero_byte_test";
+ OpWriter.BeginArray("files");
+ OpWriter.BeginObject();
+ OpWriter << "id" << EmptyFileOid;
+ OpWriter << "clientpath"
+ << "/{engine}/empty_file";
+ OpWriter << "serverpath" << EmptyFileRelPath.c_str();
+ OpWriter.EndObject();
+ OpWriter.EndArray();
+
+ zen::CbObject Op = OpWriter.Save();
+ zen::CbPackage OpPackage(Op);
+
+ zen::BinaryWriter MemOut;
+ legacy::SaveCbPackage(OpPackage, MemOut);
+
+ HttpClient Http{BaseUri};
+
+ {
+ auto Response = Http.Post("/new", IoBufferBuilder::MakeFromMemory(MemOut.GetView()));
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::Created);
+ }
+
+ // Read file data before snapshot - raw and uncompressed, 0 bytes.
+ // http.sys converts a 200 OK with empty body to 204 No Content, so
+ // accept either status code.
+ {
+ zen::StringBuilder<128> ChunkGetUri;
+ ChunkGetUri << "/" << EmptyChunkId;
+ auto Response = Http.Get(ChunkGetUri);
+
+ REQUIRE(Response);
+ CHECK((Response.StatusCode == HttpResponseCode::OK || Response.StatusCode == HttpResponseCode::NoContent));
+ CHECK(Response.ResponsePayload.GetSize() == 0);
+ }
+
+ // Trigger snapshot.
+ {
+ IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) { Writer.AddString("method"sv, "snapshot"sv); });
+ auto Response = Http.Post("/rpc"sv, Payload);
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
+ }
+
+ // Read chunk after snapshot - compressed, decompresses to 0 bytes.
+ {
+ zen::StringBuilder<128> ChunkGetUri;
+ ChunkGetUri << "/" << EmptyChunkId;
+ auto Response = Http.Get(ChunkGetUri, {{"Accept-Type", "application/x-ue-comp"}});
+
+ REQUIRE(Response);
+ REQUIRE(Response.StatusCode == HttpResponseCode::OK);
+
+ IoBuffer Data = Response.ResponsePayload;
+ IoHash RawHash;
+ uint64_t RawSize;
+ CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Data), RawHash, RawSize);
+ REQUIRE(Compressed);
+ CHECK(RawSize == 0);
+ IoBuffer DataDecompressed = Compressed.Decompress().AsIoBuffer();
+ CHECK(DataDecompressed.GetSize() == 0);
+ }
+
+ // Cleanup
+ {
+ std::error_code Ec;
+ DeleteDirectories(MakeSafeAbsolutePath(RootPath / "zerobyte_snapshot_test"), Ec);
+ }
+
+ ZEN_INFO("+++++++");
+ }
+
SUBCASE("test chunk not found error")
{
HttpClient Http{BaseUri};
@@ -1027,7 +1124,7 @@ TEST_CASE("project.rpcappendop")
std::string_view ProjectName,
std::string_view OplogName,
std::span<const CompressedBuffer> Attachments,
- void* ServerProcessHandle,
+ const ProcessHandle& ServerProcessHandle,
const std::filesystem::path& TempPath) {
CompositeBuffer PackageMessage;
{
@@ -1054,7 +1151,8 @@ TEST_CASE("project.rpcappendop")
Request.EndArray(); // "chunks"
RequestPackage.SetObject(Request.Save());
- PackageMessage = CompositeBuffer(FormatPackageMessage(RequestPackage, FormatFlags::kAllowLocalReferences, ServerProcessHandle));
+ PackageMessage =
+ CompositeBuffer(FormatPackageMessage(RequestPackage, FormatFlags::kAllowLocalReferences, ServerProcessHandle.Handle()));
}
HttpClient::Response Response =
@@ -1063,8 +1161,8 @@ TEST_CASE("project.rpcappendop")
};
{
- HttpClient Client(Servers.GetInstance(0).GetBaseUri());
- void* ServerProcessHandle = Servers.GetInstance(0).GetProcessHandle();
+ HttpClient Client(Servers.GetInstance(0).GetBaseUri());
+ const ProcessHandle& ServerProcessHandle = Servers.GetInstance(0).GetProcessHandle();
MakeProject(Client, "proj0");
MakeOplog(Client, "proj0", "oplog0");
@@ -1108,8 +1206,8 @@ TEST_CASE("project.rpcappendop")
}
{
- HttpClient Client(Servers.GetInstance(1).GetBaseUri());
- void* ServerProcessHandle = nullptr; // Force use of path for attachments passed on disk
+ HttpClient Client(Servers.GetInstance(1).GetBaseUri());
+ ProcessHandle ServerProcessHandle; // Force use of path for attachments passed on disk
MakeProject(Client, "proj0");
MakeOplog(Client, "proj0", "oplog0");
@@ -1153,6 +1251,412 @@ TEST_CASE("project.rpcappendop")
}
}
+TEST_CASE("project.file.data.transitions")
+{
+ using namespace utils;
+
+ std::filesystem::path TestDir = TestEnv.CreateNewTestDir();
+
+ ZenServerInstance Instance(TestEnv);
+ Instance.SetDataDir(TestDir);
+ const uint16_t PortNumber = Instance.SpawnServerAndWaitUntilReady();
+
+ zen::StringBuilder<64> ServerBaseUri;
+ ServerBaseUri << fmt::format("http://localhost:{}", PortNumber);
+
+ // Set up a root directory with a test file on disk for path-referenced serving
+ std::filesystem::path RootDir = TestDir / "root";
+ std::filesystem::path TestFilePath = RootDir / "content" / "testfile.bin";
+ std::filesystem::path RelServerPath = std::filesystem::path("content") / "testfile.bin";
+ CreateDirectories(TestFilePath.parent_path());
+ IoBuffer FileBlob = CreateRandomBlob(4096);
+ WriteFile(TestFilePath, FileBlob);
+
+ // Create a compressed blob to use as a CAS-referenced attachment (content differs from FileBlob)
+ CompressedBuffer CompressedBlob = CompressedBuffer::Compress(SharedBuffer(CreateRandomBlob(2048)));
+
+ // Fixed chunk IDs for the file entry across sub-tests
+ const std::string_view FileChunkIdStr{
+ "aa000000"
+ "bb000000"
+ "cc000001"};
+ Oid FileOid = Oid::FromHexString(FileChunkIdStr);
+
+ HttpClient Http{ServerBaseUri};
+
+ auto MakeProject = [&](std::string_view ProjectName) {
+ CbObjectWriter Project;
+ Project.AddString("id"sv, ProjectName);
+ Project.AddString("root"sv, PathToUtf8(RootDir.c_str()));
+ Project.AddString("engine"sv, ""sv);
+ Project.AddString("project"sv, ""sv);
+ Project.AddString("projectfile"sv, ""sv);
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}", ProjectName), Project.Save());
+ REQUIRE_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("MakeProject"));
+ };
+
+ auto MakeOplog = [&](std::string_view ProjectName, std::string_view OplogName) {
+ HttpClient::Response Response =
+ Http.Post(fmt::format("/prj/{}/oplog/{}", ProjectName, OplogName), IoBuffer{}, ZenContentType::kCbObject);
+ REQUIRE_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("MakeOplog"));
+ };
+
+ auto PostOplogEntry = [&](std::string_view ProjectName, std::string_view OplogName, const CbPackage& OpPackage) {
+ zen::BinaryWriter MemOut;
+ legacy::SaveCbPackage(OpPackage, MemOut);
+ IoBuffer Body{IoBuffer::Wrap, MemOut.GetData(), MemOut.GetSize()};
+ Body.SetContentType(HttpContentType::kCbPackage);
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/new", ProjectName, OplogName), Body);
+ REQUIRE_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("PostOplogEntry"));
+ };
+
+ auto GetChunk = [&](std::string_view ProjectName) -> HttpClient::Response {
+ return Http.Get(fmt::format("/prj/{}/oplog/oplog/{}", ProjectName, FileChunkIdStr));
+ };
+
+ // Extract the raw decompressed bytes from a chunk response, handling both compressed and uncompressed payloads
+ auto GetDecompressedPayload = [](const HttpClient::Response& Response) -> IoBuffer {
+ if (Response.ResponsePayload.GetContentType() == ZenContentType::kCompressedBinary)
+ {
+ IoHash RawHash;
+ uint64_t RawSize;
+ CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Response.ResponsePayload), RawHash, RawSize);
+ REQUIRE(Compressed);
+ return Compressed.Decompress().AsIoBuffer();
+ }
+ return Response.ResponsePayload;
+ };
+
+ auto TriggerGcAndWait = [&]() {
+ HttpClient::Response TriggerResponse = Http.Post("/admin/gc?smallobjects=true"sv, IoBuffer{});
+ REQUIRE_MESSAGE(TriggerResponse.IsSuccess(), TriggerResponse.ErrorMessage("TriggerGc"));
+
+ for (int Attempt = 0; Attempt < 100; ++Attempt)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ HttpClient::Response StatusResponse = Http.Get("/admin/gc"sv);
+ REQUIRE_MESSAGE(StatusResponse.IsSuccess(), StatusResponse.ErrorMessage("GcStatus"));
+ CbObject StatusObj = StatusResponse.AsObject();
+ if (StatusObj["Status"sv].AsString() == "Idle"sv)
+ {
+ return;
+ }
+ }
+ FAIL("GC did not complete within timeout");
+ };
+
+ auto BuildPathReferencedFileOp = [&](const Oid& KeyId) -> CbPackage {
+ CbPackage Package;
+ CbObjectWriter Object;
+ Object << "key"sv << OidAsString(KeyId);
+ Object.BeginArray("files"sv);
+ Object.BeginObject();
+ Object << "id"sv << FileOid;
+ Object << "serverpath"sv << RelServerPath.string();
+ Object << "clientpath"sv
+ << "/{engine}/testfile.bin"sv;
+ Object.EndObject();
+ Object.EndArray();
+ Package.SetObject(Object.Save());
+ return Package;
+ };
+
+ auto BuildHashReferencedFileOp = [&](const Oid& KeyId, const CompressedBuffer& Blob) -> CbPackage {
+ CbPackage Package;
+ CbObjectWriter Object;
+ Object << "key"sv << OidAsString(KeyId);
+ CbAttachment Attach(Blob, Blob.DecodeRawHash());
+ Object.BeginArray("files"sv);
+ Object.BeginObject();
+ Object << "id"sv << FileOid;
+ Object << "data"sv << Attach;
+ Object << "clientpath"sv
+ << "/{engine}/testfile.bin"sv;
+ Object.EndObject();
+ Object.EndArray();
+ Package.AddAttachment(Attach);
+ Package.SetObject(Object.Save());
+ return Package;
+ };
+
+ SUBCASE("path-referenced file is retrievable")
+ {
+ MakeProject("proj_path"sv);
+ MakeOplog("proj_path"sv, "oplog"sv);
+
+ CbPackage Op = BuildPathReferencedFileOp(Oid::NewOid());
+ PostOplogEntry("proj_path"sv, "oplog"sv, Op);
+
+ HttpClient::Response Response = GetChunk("proj_path"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK_EQ(Payload.GetSize(), FileBlob.GetSize());
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+
+ SUBCASE("hash-referenced file is retrievable")
+ {
+ MakeProject("proj_hash"sv);
+ MakeOplog("proj_hash"sv, "oplog"sv);
+
+ CbPackage Op = BuildHashReferencedFileOp(Oid::NewOid(), CompressedBlob);
+ PostOplogEntry("proj_hash"sv, "oplog"sv, Op);
+
+ HttpClient::Response Response = GetChunk("proj_hash"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ IoBuffer ExpectedDecompressed = CompressedBlob.Decompress().AsIoBuffer();
+ CHECK_EQ(Payload.GetSize(), ExpectedDecompressed.GetSize());
+ CHECK(Payload.GetView().EqualBytes(ExpectedDecompressed.GetView()));
+ }
+ }
+
+ SUBCASE("hash-referenced to path-referenced transition with different content")
+ {
+ MakeProject("proj_hash_to_path_diff"sv);
+ MakeOplog("proj_hash_to_path_diff"sv, "oplog"sv);
+
+ Oid FirstOpKey = Oid::NewOid();
+ Oid SecondOpKey;
+ bool RunGcAfterTransition = false;
+
+ SUBCASE("new op key") { SecondOpKey = Oid::NewOid(); }
+ SUBCASE("same op key") { SecondOpKey = FirstOpKey; }
+ SUBCASE("new op key with gc")
+ {
+ SecondOpKey = Oid::NewOid();
+ RunGcAfterTransition = true;
+ }
+ SUBCASE("same op key with gc")
+ {
+ SecondOpKey = FirstOpKey;
+ RunGcAfterTransition = true;
+ }
+
+ // First op: file with CAS hash (content differs from the on-disk file)
+ {
+ CbPackage Op = BuildHashReferencedFileOp(FirstOpKey, CompressedBlob);
+ PostOplogEntry("proj_hash_to_path_diff"sv, "oplog"sv, Op);
+
+ HttpClient::Response Response = GetChunk("proj_hash_to_path_diff"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk first op"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ IoBuffer ExpectedDecompressed = CompressedBlob.Decompress().AsIoBuffer();
+ CHECK(Payload.GetView().EqualBytes(ExpectedDecompressed.GetView()));
+ }
+ }
+
+ // Second op: same FileId transitions to serverpath (different data)
+ {
+ CbPackage Op = BuildPathReferencedFileOp(SecondOpKey);
+ PostOplogEntry("proj_hash_to_path_diff"sv, "oplog"sv, Op);
+ }
+
+ if (RunGcAfterTransition)
+ {
+ TriggerGcAndWait();
+ }
+
+ // Must serve the on-disk file content, not the old CAS blob
+ HttpClient::Response Response = GetChunk("proj_hash_to_path_diff"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk after transition"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK_EQ(Payload.GetSize(), FileBlob.GetSize());
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+
+ SUBCASE("hash-referenced to path-referenced transition with identical content")
+ {
+ // Compress the same on-disk file content as a CAS blob so both references yield identical data
+ CompressedBuffer MatchingBlob = CompressedBuffer::Compress(SharedBuffer::Clone(FileBlob.GetView()));
+
+ MakeProject("proj_hash_to_path_same"sv);
+ MakeOplog("proj_hash_to_path_same"sv, "oplog"sv);
+
+ Oid FirstOpKey = Oid::NewOid();
+ Oid SecondOpKey;
+ bool RunGcAfterTransition = false;
+
+ SUBCASE("new op key") { SecondOpKey = Oid::NewOid(); }
+ SUBCASE("same op key") { SecondOpKey = FirstOpKey; }
+ SUBCASE("new op key with gc")
+ {
+ SecondOpKey = Oid::NewOid();
+ RunGcAfterTransition = true;
+ }
+ SUBCASE("same op key with gc")
+ {
+ SecondOpKey = FirstOpKey;
+ RunGcAfterTransition = true;
+ }
+
+ // First op: file with CAS hash (content matches the on-disk file)
+ {
+ CbPackage Op = BuildHashReferencedFileOp(FirstOpKey, MatchingBlob);
+ PostOplogEntry("proj_hash_to_path_same"sv, "oplog"sv, Op);
+
+ HttpClient::Response Response = GetChunk("proj_hash_to_path_same"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk first op"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+
+ // Second op: same FileId transitions to serverpath (same data)
+ {
+ CbPackage Op = BuildPathReferencedFileOp(SecondOpKey);
+ PostOplogEntry("proj_hash_to_path_same"sv, "oplog"sv, Op);
+ }
+
+ if (RunGcAfterTransition)
+ {
+ TriggerGcAndWait();
+ }
+
+ // Must still resolve successfully after the transition
+ HttpClient::Response Response = GetChunk("proj_hash_to_path_same"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk after transition"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK_EQ(Payload.GetSize(), FileBlob.GetSize());
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+
+ SUBCASE("path-referenced to hash-referenced transition with different content")
+ {
+ MakeProject("proj_path_to_hash_diff"sv);
+ MakeOplog("proj_path_to_hash_diff"sv, "oplog"sv);
+
+ Oid FirstOpKey = Oid::NewOid();
+ Oid SecondOpKey;
+ bool RunGcAfterTransition = false;
+
+ SUBCASE("new op key") { SecondOpKey = Oid::NewOid(); }
+ SUBCASE("same op key") { SecondOpKey = FirstOpKey; }
+ SUBCASE("new op key with gc")
+ {
+ SecondOpKey = Oid::NewOid();
+ RunGcAfterTransition = true;
+ }
+ SUBCASE("same op key with gc")
+ {
+ SecondOpKey = FirstOpKey;
+ RunGcAfterTransition = true;
+ }
+
+ // First op: file with serverpath
+ {
+ CbPackage Op = BuildPathReferencedFileOp(FirstOpKey);
+ PostOplogEntry("proj_path_to_hash_diff"sv, "oplog"sv, Op);
+
+ HttpClient::Response Response = GetChunk("proj_path_to_hash_diff"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk first op"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+
+ // Second op: same FileId transitions to CAS hash (different data)
+ {
+ CbPackage Op = BuildHashReferencedFileOp(SecondOpKey, CompressedBlob);
+ PostOplogEntry("proj_path_to_hash_diff"sv, "oplog"sv, Op);
+ }
+
+ if (RunGcAfterTransition)
+ {
+ TriggerGcAndWait();
+ }
+
+ // Must serve the CAS blob content, not the old on-disk file
+ HttpClient::Response Response = GetChunk("proj_path_to_hash_diff"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk after transition"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ IoBuffer ExpectedDecompressed = CompressedBlob.Decompress().AsIoBuffer();
+ CHECK_EQ(Payload.GetSize(), ExpectedDecompressed.GetSize());
+ CHECK(Payload.GetView().EqualBytes(ExpectedDecompressed.GetView()));
+ }
+ }
+
+ SUBCASE("path-referenced to hash-referenced transition with identical content")
+ {
+ // Compress the same on-disk file content as a CAS blob so both references yield identical data
+ CompressedBuffer MatchingBlob = CompressedBuffer::Compress(SharedBuffer::Clone(FileBlob.GetView()));
+
+ MakeProject("proj_path_to_hash_same"sv);
+ MakeOplog("proj_path_to_hash_same"sv, "oplog"sv);
+
+ Oid FirstOpKey = Oid::NewOid();
+ Oid SecondOpKey;
+ bool RunGcAfterTransition = false;
+
+ SUBCASE("new op key") { SecondOpKey = Oid::NewOid(); }
+ SUBCASE("same op key") { SecondOpKey = FirstOpKey; }
+ SUBCASE("new op key with gc")
+ {
+ SecondOpKey = Oid::NewOid();
+ RunGcAfterTransition = true;
+ }
+ SUBCASE("same op key with gc")
+ {
+ SecondOpKey = FirstOpKey;
+ RunGcAfterTransition = true;
+ }
+
+ // First op: file with serverpath
+ {
+ CbPackage Op = BuildPathReferencedFileOp(FirstOpKey);
+ PostOplogEntry("proj_path_to_hash_same"sv, "oplog"sv, Op);
+
+ HttpClient::Response Response = GetChunk("proj_path_to_hash_same"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk first op"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+
+ // Second op: same FileId transitions to CAS hash (same data)
+ {
+ CbPackage Op = BuildHashReferencedFileOp(SecondOpKey, MatchingBlob);
+ PostOplogEntry("proj_path_to_hash_same"sv, "oplog"sv, Op);
+ }
+
+ if (RunGcAfterTransition)
+ {
+ TriggerGcAndWait();
+ }
+
+ // Must still resolve successfully after the transition
+ HttpClient::Response Response = GetChunk("proj_path_to_hash_same"sv);
+ CHECK_MESSAGE(Response.IsSuccess(), Response.ErrorMessage("GetChunk after transition"));
+ if (Response.IsSuccess())
+ {
+ IoBuffer Payload = GetDecompressedPayload(Response);
+ CHECK_EQ(Payload.GetSize(), FileBlob.GetSize());
+ CHECK(Payload.GetView().EqualBytes(FileBlob.GetView()));
+ }
+ }
+}
+
TEST_SUITE_END();
} // namespace zen::tests
diff --git a/src/zenserver-test/zenserver-test.cpp b/src/zenserver-test/zenserver-test.cpp
index 42632682b..cf7ffe4e4 100644
--- a/src/zenserver-test/zenserver-test.cpp
+++ b/src/zenserver-test/zenserver-test.cpp
@@ -76,10 +76,6 @@ main(int argc, char** argv)
zen::CommandLineConverter ArgConverter(argc, argv);
-# if ZEN_PLATFORM_LINUX
- IgnoreChildSignals();
-# endif
-
# if ZEN_WITH_TRACE
zen::TraceInit("zenserver-test");
TraceOptions TraceCommandlineOptions;
@@ -103,7 +99,8 @@ main(int argc, char** argv)
// somehow in the future
std::string ServerClass;
- bool Verbose = false;
+ bool Verbose = false;
+ bool KillStale = false;
for (int i = 1; i < argc; ++i)
{
@@ -123,6 +120,44 @@ main(int argc, char** argv)
{
Verbose = true;
}
+ else if (argv[i] == "--kill-stale-processes"sv)
+ {
+ KillStale = true;
+ }
+ }
+
+ // Since GHA runners can leave processes behind from a previous test run, we need
+ // to be able to clean up any stale server processes before starting the tests to
+ // avoid interference
+
+ if (KillStale)
+ {
+ ZEN_INFO("Killing any stale processes from previous test runs...");
+
+ auto KillStaleProcesses = [](const std::filesystem::path& Executable) {
+ ZEN_INFO(" Looking for stale '{}' processes...", Executable.filename());
+
+ for (;;)
+ {
+ ProcessHandle StaleProcess;
+ std::error_code Ec = FindProcess(Executable, StaleProcess, /*IncludeSelf*/ false);
+
+ if (Ec || !StaleProcess.IsValid())
+ {
+ break;
+ }
+
+ ZEN_WARN("====> Found stale '{}' process (pid {}) from a previous test run - terminating it",
+ Executable.filename(),
+ StaleProcess.Pid());
+
+ StaleProcess.Terminate(0);
+ }
+ };
+
+ KillStaleProcesses(ProgramBaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL);
+ KillStaleProcesses(ProgramBaseDir / "zenserver-test" ZEN_EXE_SUFFIX_LITERAL);
+ KillStaleProcesses(ProgramBaseDir / "zentest-appstub" ZEN_EXE_SUFFIX_LITERAL);
}
zen::tests::TestEnv.InitializeForTest(ProgramBaseDir, TestBaseDir, ServerClass);
diff --git a/src/zenserver/compute/computeserver.cpp b/src/zenserver/compute/computeserver.cpp
index d1875f41a..1673cea6c 100644
--- a/src/zenserver/compute/computeserver.cpp
+++ b/src/zenserver/compute/computeserver.cpp
@@ -481,7 +481,7 @@ ZenComputeServer::InitializeServices(const ZenComputeServerConfig& ServerConfig)
ServerConfig.DataDir / "functions",
ServerConfig.MaxConcurrentActions);
- m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatusService);
+ m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatsService, m_StatusService);
# if ZEN_WITH_NOMAD
// Nomad provisioner
diff --git a/src/zenserver/config/config.cpp b/src/zenserver/config/config.cpp
index 15f6f79f3..daad154bc 100644
--- a/src/zenserver/config/config.cpp
+++ b/src/zenserver/config/config.cpp
@@ -417,7 +417,7 @@ ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerConfi
options.add_option("network",
"",
"httpclient",
- "Select HTTP client implementation (e.g. 'curl', 'cpr')",
+ "Select HTTP client implementation",
cxxopts::value<std::string>(ServerOptions.HttpClient.Backend)->default_value("curl"),
"<http client>");
diff --git a/src/zenserver/config/config.h b/src/zenserver/config/config.h
index 5078fe71a..d35a1a8c7 100644
--- a/src/zenserver/config/config.h
+++ b/src/zenserver/config/config.h
@@ -40,7 +40,7 @@ struct ZenSentryConfig
struct HttpClientConfig
{
- std::string Backend = "cpr"; // Choice of HTTP client implementation (e.g. "curl", "cpr")
+ std::string Backend = "curl"; // Choice of HTTP client implementation
};
struct ZenServerConfig
diff --git a/src/zenserver/diag/diagsvcs.cpp b/src/zenserver/diag/diagsvcs.cpp
index dd4b8956c..1c52510db 100644
--- a/src/zenserver/diag/diagsvcs.cpp
+++ b/src/zenserver/diag/diagsvcs.cpp
@@ -73,6 +73,17 @@ HttpHealthService::HttpHealthService()
Writer.EndObject();
Writer << "Hostname"sv << GetMachineName();
+
+ {
+ std::vector<std::string> IpAddresses = GetLocalIpAddresses();
+ Writer.BeginArray("IpAddresses"sv);
+ for (const std::string& Ip : IpAddresses)
+ {
+ Writer << Ip;
+ }
+ Writer.EndArray();
+ }
+
Writer << "Platform"sv << GetRuntimePlatformName();
Writer << "Arch"sv << GetCpuName();
Writer << "OS"sv << GetOperatingSystemVersion();
diff --git a/src/zenserver/diag/logging.cpp b/src/zenserver/diag/logging.cpp
index 178c3d3b5..f3d8dbfe3 100644
--- a/src/zenserver/diag/logging.cpp
+++ b/src/zenserver/diag/logging.cpp
@@ -6,6 +6,7 @@
#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
+#include <zencore/logging/broadcastsink.h>
#include <zencore/logging/logger.h>
#include <zencore/logging/registry.h>
#include <zencore/memory/llm.h>
@@ -13,6 +14,7 @@
#include <zencore/string.h>
#include <zenutil/logging.h>
#include <zenutil/logging/rotatingfilesink.h>
+#include <zenutil/splitconsole/tcplogstreamsink.h>
#include "otlphttp.h"
@@ -28,6 +30,7 @@ InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService)
.IsTest = InOptions.IsTest,
.NoConsoleOutput = InOptions.LoggingConfig.NoConsoleOutput,
.QuietConsole = InOptions.LoggingConfig.QuietConsole,
+ .ForceColor = InOptions.LoggingConfig.ForceColor,
.AbsLogFile = InOptions.LoggingConfig.AbsLogFile,
.LogId = InOptions.LoggingConfig.LogId};
@@ -45,7 +48,7 @@ InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService)
/* max size */ 128 * 1024 * 1024,
/* max files */ 16,
/* rotate on open */ true));
- Ref<logging::Logger> HttpLogger(new logging::Logger("http_requests", std::vector<logging::SinkPtr>{HttpSink}));
+ Ref<logging::Logger> HttpLogger(new logging::Logger("http_requests", HttpSink));
logging::Registry::Instance().Register(HttpLogger);
if (WithCacheService)
@@ -58,35 +61,58 @@ InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService)
/* max size */ 128 * 1024 * 1024,
/* max files */ 16,
/* rotate on open */ false));
- Ref<logging::Logger> CacheLogger(new logging::Logger("z$", std::vector<logging::SinkPtr>{CacheSink}));
+ Ref<logging::Logger> CacheLogger(new logging::Logger("z$", CacheSink));
logging::Registry::Instance().Register(CacheLogger);
// Jupiter - only log upstream HTTP traffic to file
- Ref<logging::Logger> JupiterLogger(new logging::Logger("jupiter", std::vector<logging::SinkPtr>{FileSink}));
+ Ref<logging::Logger> JupiterLogger(new logging::Logger("jupiter", FileSink));
logging::Registry::Instance().Register(JupiterLogger);
// Zen - only log upstream HTTP traffic to file
- Ref<logging::Logger> ZenClientLogger(new logging::Logger("zenclient", std::vector<logging::SinkPtr>{FileSink}));
+ Ref<logging::Logger> ZenClientLogger(new logging::Logger("zenclient", FileSink));
logging::Registry::Instance().Register(ZenClientLogger);
}
+ Ref<logging::BroadcastSink> BroadcastSink = GetDefaultBroadcastSink();
+
#if ZEN_WITH_OTEL
- if (!InOptions.LoggingConfig.OtelEndpointUri.empty())
+ if (BroadcastSink && !InOptions.LoggingConfig.OtelEndpointUri.empty())
{
// TODO: Should sanity check that endpoint is reachable? Also, a valid URI?
logging::SinkPtr OtelSink(new zen::logging::OtelHttpProtobufSink(InOptions.LoggingConfig.OtelEndpointUri));
- zen::logging::Default()->AddSink(std::move(OtelSink));
+ BroadcastSink->AddSink(std::move(OtelSink));
}
#endif
+ if (BroadcastSink && !InOptions.LoggingConfig.LogStreamEndpoint.empty())
+ {
+ std::string Endpoint = InOptions.LoggingConfig.LogStreamEndpoint;
+ std::string Host = "localhost";
+ uint16_t Port = 0;
+
+ auto ColonPos = Endpoint.rfind(':');
+ if (ColonPos != std::string::npos)
+ {
+ Host = Endpoint.substr(0, ColonPos);
+ std::optional<uint16_t> P = ParseInt<uint16_t>(std::string_view(Endpoint).substr(ColonPos + 1));
+ Port = P.value_or(0);
+ }
+
+ if (Port > 0)
+ {
+ logging::SinkPtr StreamSink(new TcpLogStreamSink(Host, Port, "zenserver"));
+ BroadcastSink->AddSink(std::move(StreamSink));
+ }
+ }
+
FinishInitializeLogging(LogOptions);
const zen::Oid ServerSessionId = zen::GetSessionId();
- static constinit logging::LogPoint SessionIdPoint{{}, logging::Info, "server session id: {}"};
logging::Registry::Instance().ApplyAll([&](auto Logger) {
+ static constinit logging::LogPoint SessionIdPoint{{}, logging::Info, "server session id: {}"};
ZEN_MEMSCOPE(ELLMTag::Logging);
Logger->Log(SessionIdPoint, fmt::make_format_args(ServerSessionId));
});
diff --git a/src/zenserver/frontend/frontend.cpp b/src/zenserver/frontend/frontend.cpp
index 579a65c5a..52ec5b8b3 100644
--- a/src/zenserver/frontend/frontend.cpp
+++ b/src/zenserver/frontend/frontend.cpp
@@ -9,6 +9,7 @@
#include <zencore/logging.h>
#include <zencore/string.h>
#include <zencore/trace.h>
+#include <zenhttp/httpstats.h>
ZEN_THIRD_PARTY_INCLUDES_START
#if ZEN_PLATFORM_WINDOWS
@@ -28,8 +29,9 @@ static unsigned char gHtmlZipData[] = {
namespace zen {
////////////////////////////////////////////////////////////////////////////////
-HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpStatusService& StatusService)
+HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpStatsService& StatsService, HttpStatusService& StatusService)
: m_Directory(Directory)
+, m_StatsService(StatsService)
, m_StatusService(StatusService)
{
ZEN_TRACE_CPU("HttpFrontendService::HttpFrontendService");
@@ -68,6 +70,14 @@ HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpSt
{
m_Directory = HtmlDir;
}
+
+ // Map data/ requests to the project docs/ directory in dev mode
+ std::filesystem::path DocsDir = ParentPath / "docs";
+ if (IsDir(DocsDir, ErrorCode))
+ {
+ m_DocsDirectory = DocsDir;
+ }
+
break;
}
Path = ParentPath;
@@ -86,12 +96,14 @@ HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpSt
{
ZEN_INFO("front-end is NOT AVAILABLE");
}
+ m_StatsService.RegisterHandler("dashboard", *this);
m_StatusService.RegisterHandler("dashboard", *this);
}
HttpFrontendService::~HttpFrontendService()
{
m_StatusService.UnregisterHandler("dashboard", *this);
+ m_StatsService.UnregisterHandler("dashboard", *this);
}
const char*
@@ -114,6 +126,8 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request)
{
using namespace std::literals;
+ metrics::OperationTiming::Scope $(m_HttpRequests);
+
ExtendableStringBuilder<256> UriBuilder;
std::string_view Uri = Request.RelativeUriWithExtension();
@@ -145,6 +159,18 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request)
const std::string_view DotExt = Uri.substr(DotIndex + 1);
ContentType = ParseContentType(DotExt);
+
+ // Extensions used only for static file serving — not in the global
+ // ParseContentType table because that table also drives URI extension
+ // stripping for content negotiation, and we don't want /api/foo.txt to
+ // have its extension removed.
+ if (ContentType == HttpContentType::kUnknownContentType)
+ {
+ if (DotExt == "txt" || DotExt == "md")
+ {
+ ContentType = HttpContentType::kText;
+ }
+ }
}
if (ContentType == HttpContentType::kUnknownContentType)
@@ -154,6 +180,21 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request)
auto WriteResponseForUri = [this,
&Request](std::string_view InUri, HttpResponseCode ResponseCode, HttpContentType ContentType) -> bool {
+ // In dev mode, map data/ requests to the project docs/ directory
+ constexpr std::string_view DataPrefix = "data/";
+ if (!m_DocsDirectory.empty() && InUri.starts_with(DataPrefix))
+ {
+ std::string_view DocsRelative = InUri.substr(DataPrefix.size());
+ auto FullPath = m_DocsDirectory / std::filesystem::path(DocsRelative).make_preferred();
+ FileContents File = ReadFile(FullPath);
+
+ if (!File.ErrorCode)
+ {
+ Request.WriteResponse(ResponseCode, ContentType, File.Data[0]);
+ return true;
+ }
+ }
+
// The given content directory overrides any zip-fs discovered in the binary
if (!m_Directory.empty())
{
@@ -195,4 +236,26 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request)
}
}
+void
+HttpFrontendService::HandleStatsRequest(HttpServerRequest& Request)
+{
+ Request.WriteResponse(HttpResponseCode::OK, CollectStats());
+}
+
+CbObject
+HttpFrontendService::CollectStats()
+{
+ ZEN_TRACE_CPU("HttpFrontendService::Stats");
+ CbObjectWriter Cbo;
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+ return Cbo.Save();
+}
+
+uint64_t
+HttpFrontendService::GetActivityCounter()
+{
+ return m_HttpRequests.Count();
+}
+
} // namespace zen
diff --git a/src/zenserver/frontend/frontend.h b/src/zenserver/frontend/frontend.h
index 6d8585b72..e0b86f1de 100644
--- a/src/zenserver/frontend/frontend.h
+++ b/src/zenserver/frontend/frontend.h
@@ -11,19 +11,27 @@
namespace zen {
-class HttpFrontendService final : public zen::HttpService, public IHttpStatusProvider
+class HttpStatsService;
+
+class HttpFrontendService final : public HttpService, public IHttpStatusProvider, public IHttpStatsProvider
{
public:
- HttpFrontendService(std::filesystem::path Directory, HttpStatusService& StatusService);
+ HttpFrontendService(std::filesystem::path Directory, HttpStatsService& StatsService, HttpStatusService& StatusService);
virtual ~HttpFrontendService();
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
private:
- std::unique_ptr<ZipFs> m_ZipFs;
- std::filesystem::path m_Directory;
- HttpStatusService& m_StatusService;
+ std::unique_ptr<ZipFs> m_ZipFs;
+ std::filesystem::path m_Directory;
+ std::filesystem::path m_DocsDirectory;
+ HttpStatsService& m_StatsService;
+ HttpStatusService& m_StatusService;
+ metrics::OperationTiming m_HttpRequests;
};
} // namespace zen
diff --git a/src/zenserver/frontend/html/banner.js b/src/zenserver/frontend/html/banner.js
index 2e878dedf..01679e621 100644
--- a/src/zenserver/frontend/html/banner.js
+++ b/src/zenserver/frontend/html/banner.js
@@ -291,7 +291,7 @@ class ZenBanner extends HTMLElement {
` : '';
return `
- <a class="banner" href="/dashboard/">
+ <a class="banner" part="banner" href="/dashboard/">
<div class="logo-mark">${this._logoMark()}</div>
<div class="divider"></div>
<div class="text-block">
diff --git a/src/zenserver/frontend/html/compute/hub.html b/src/zenserver/frontend/html/compute/hub.html
index 620349a2b..41c80d3a3 100644
--- a/src/zenserver/frontend/html/compute/hub.html
+++ b/src/zenserver/frontend/html/compute/hub.html
@@ -83,7 +83,7 @@
}
async function fetchStats() {
- var data = await fetchJSON('/hub/stats');
+ var data = await fetchJSON('/stats/hub');
var current = data.currentInstanceCount || 0;
var max = data.maxInstanceCount || 0;
@@ -127,11 +127,11 @@
for (var i = 0; i < modules.length; i++) {
var m = modules[i];
var moduleId = m.moduleId || '';
- var provisioned = m.provisioned;
+ var state = m.state || 'unprovisioned';
- var badge = provisioned
+ var badge = (state === 'provisioned')
? '<span class="status-badge active">Provisioned</span>'
- : '<span class="status-badge inactive">Inactive</span>';
+ : '<span class="status-badge inactive">' + escapeHtml(state.charAt(0).toUpperCase() + state.slice(1)) + '</span>';
var tr = document.createElement('tr');
tr.innerHTML =
diff --git a/src/zenserver/frontend/html/nav.js b/src/zenserver/frontend/html/nav.js
index a5de203f2..759942186 100644
--- a/src/zenserver/frontend/html/nav.js
+++ b/src/zenserver/frontend/html/nav.js
@@ -11,6 +11,9 @@
*
* Each child <a> becomes a nav link. The current page is
* highlighted automatically based on the href.
+ *
+ * Links may be added or removed dynamically — the component
+ * re-renders automatically via MutationObserver.
*/
class ZenNav extends HTMLElement {
@@ -18,17 +21,56 @@ class ZenNav extends HTMLElement {
connectedCallback() {
if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
this._render();
+
+ this._observer = new MutationObserver(() => this._render());
+ this._observer.observe(this, { childList: true });
+ }
+
+ disconnectedCallback() {
+ if (this._observer) {
+ this._observer.disconnect();
+ this._observer = null;
+ }
}
_render() {
const currentPath = window.location.pathname;
+ const currentSearch = window.location.search;
const items = Array.from(this.querySelectorAll(':scope > a'));
+ const currentParams = new URLSearchParams(currentSearch);
+
+ let spacerInserted = false;
const links = items.map(a => {
const href = a.getAttribute('href') || '';
const label = a.textContent.trim();
- const active = currentPath.endsWith(href);
- return `<a class="nav-link${active ? ' active' : ''}" href="${href}">${label}</a>`;
+ const alignRight = a.hasAttribute('data-align') && a.getAttribute('data-align') === 'right';
+ let active = false;
+
+ try {
+ const linkUrl = new URL(href, window.location.origin);
+ if (linkUrl.pathname === currentPath || currentPath.endsWith(href)) {
+ // All of the link's query params must be present in the current URL
+ const linkParams = linkUrl.searchParams;
+ active = Array.from(linkParams.entries()).every(
+ ([k, v]) => currentParams.get(k) === v
+ );
+ // A bare path with no params only matches when the current URL also has no page param
+ if (linkParams.toString() === '' && currentParams.has('page')) {
+ active = false;
+ }
+ }
+ } catch (e) {
+ active = currentPath.endsWith(href);
+ }
+
+ let prefix = '';
+ if (alignRight && !spacerInserted) {
+ prefix = '<span class="nav-spacer"></span>';
+ spacerInserted = true;
+ }
+
+ return `${prefix}<a class="nav-link${active ? ' active' : ''}" href="${href}">${label}</a>`;
}).join('');
this.shadowRoot.innerHTML = `
@@ -70,8 +112,12 @@ class ZenNav extends HTMLElement {
color: var(--theme_bright);
background: var(--theme_g2);
}
+
+ .nav-spacer {
+ flex: 1;
+ }
</style>
- <nav class="nav-bar">${links}</nav>
+ <nav class="nav-bar" part="nav-bar">${links}</nav>
`;
}
}
diff --git a/src/zenserver/frontend/html/pages/builds.js b/src/zenserver/frontend/html/pages/builds.js
new file mode 100644
index 000000000..6b3426378
--- /dev/null
+++ b/src/zenserver/frontend/html/pages/builds.js
@@ -0,0 +1,88 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+import { ZenPage } from "./page.js"
+import { Fetcher } from "../util/fetcher.js"
+import { Friendly } from "../util/friendly.js"
+
+////////////////////////////////////////////////////////////////////////////////
+export class Page extends ZenPage
+{
+ generate_crumbs() {}
+
+ async main()
+ {
+ this.set_title("build store");
+
+ // Build Store Stats
+ const stats_section = this._collapsible_section("Build Store Service Stats");
+ stats_section.tag().classify("dropall").text("raw yaml \u2192").on_click(() => {
+ window.open("/stats/builds.yaml", "_blank");
+ });
+ this._stats_grid = stats_section.tag().classify("grid").classify("stats-tiles");
+
+ const stats = await new Fetcher().resource("stats", "builds").json();
+ if (stats)
+ {
+ this._render_stats(stats);
+ }
+
+ this.connect_stats_ws((all_stats) => {
+ const s = all_stats["builds"];
+ if (s)
+ {
+ this._render_stats(s);
+ }
+ });
+ }
+
+ _render_stats(stats)
+ {
+ const grid = this._stats_grid;
+ const safe = (obj, path) => path.split(".").reduce((a, b) => a && a[b], obj);
+
+ grid.inner().innerHTML = "";
+
+ // HTTP Requests tile
+ this._render_http_requests_tile(grid, safe(stats, "requests"), safe(stats, "store.badrequestcount") || 0);
+
+ // Build Store tile
+ {
+ const blobs = safe(stats, "store.blobs");
+ const metadata = safe(stats, "store.metadata");
+ if (blobs || metadata)
+ {
+ const tile = grid.tag().classify("card").classify("stats-tile");
+ tile.tag().classify("card-title").text("Build Store");
+ const columns = tile.tag().classify("tile-columns");
+
+ const left = columns.tag().classify("tile-metrics");
+ this._metric(left, Friendly.bytes(safe(stats, "store.size.disk") || 0), "disk", true);
+ if (blobs)
+ {
+ this._metric(left, Friendly.sep(blobs.count || 0), "blobs");
+ this._metric(left, Friendly.sep(blobs.readcount || 0), "blob reads");
+ this._metric(left, Friendly.sep(blobs.writecount || 0), "blob writes");
+ const blobHitRatio = (blobs.readcount || 0) > 0
+ ? (((blobs.hitcount || 0) / blobs.readcount) * 100).toFixed(1) + "%"
+ : "-";
+ this._metric(left, blobHitRatio, "blob hit ratio");
+ }
+
+ const right = columns.tag().classify("tile-metrics");
+ if (metadata)
+ {
+ this._metric(right, Friendly.sep(metadata.count || 0), "metadata entries", true);
+ this._metric(right, Friendly.sep(metadata.readcount || 0), "meta reads");
+ this._metric(right, Friendly.sep(metadata.writecount || 0), "meta writes");
+ const metaHitRatio = (metadata.readcount || 0) > 0
+ ? (((metadata.hitcount || 0) / metadata.readcount) * 100).toFixed(1) + "%"
+ : "-";
+ this._metric(right, metaHitRatio, "meta hit ratio");
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/zenserver/frontend/html/pages/cache.js b/src/zenserver/frontend/html/pages/cache.js
index 3b838958a..e0f6f73b6 100644
--- a/src/zenserver/frontend/html/pages/cache.js
+++ b/src/zenserver/frontend/html/pages/cache.js
@@ -11,6 +11,8 @@ import { Table, Toolbar } from "../util/widgets.js"
////////////////////////////////////////////////////////////////////////////////
export class Page extends ZenPage
{
+ generate_crumbs() {}
+
async main()
{
this.set_title("cache");
@@ -31,7 +33,13 @@ export class Page extends ZenPage
this._render_stats(stats);
}
- this._connect_stats_ws();
+ this.connect_stats_ws((all_stats) => {
+ const stats = all_stats["z$"];
+ if (stats)
+ {
+ this._render_stats(stats);
+ }
+ });
// Cache Namespaces
var section = this._collapsible_section("Cache Namespaces");
@@ -87,76 +95,6 @@ export class Page extends ZenPage
}
}
- _collapsible_section(name)
- {
- const section = this.add_section(name);
- const container = section._parent.inner();
- const heading = container.firstElementChild;
-
- heading.style.cursor = "pointer";
- heading.style.userSelect = "none";
-
- const indicator = document.createElement("span");
- indicator.textContent = " \u25BC";
- indicator.style.fontSize = "0.7em";
- heading.appendChild(indicator);
-
- let collapsed = false;
- heading.addEventListener("click", (e) => {
- if (e.target !== heading && e.target !== indicator)
- {
- return;
- }
- collapsed = !collapsed;
- indicator.textContent = collapsed ? " \u25B6" : " \u25BC";
- let sibling = heading.nextElementSibling;
- while (sibling)
- {
- sibling.style.display = collapsed ? "none" : "";
- sibling = sibling.nextElementSibling;
- }
- });
-
- return section;
- }
-
- _connect_stats_ws()
- {
- try
- {
- const proto = location.protocol === "https:" ? "wss:" : "ws:";
- const ws = new WebSocket(`${proto}//${location.host}/stats`);
-
- try { this._ws_paused = localStorage.getItem("zen-ws-paused") === "true"; } catch (e) { this._ws_paused = false; }
- document.addEventListener("zen-ws-toggle", (e) => {
- this._ws_paused = e.detail.paused;
- });
-
- ws.onmessage = (ev) => {
- if (this._ws_paused)
- {
- return;
- }
- try
- {
- const all_stats = JSON.parse(ev.data);
- const stats = all_stats["z$"];
- if (stats)
- {
- this._render_stats(stats);
- }
- }
- catch (e) { /* ignore parse errors */ }
- };
-
- ws.onclose = () => { this._stats_ws = null; };
- ws.onerror = () => { ws.close(); };
-
- this._stats_ws = ws;
- }
- catch (e) { /* WebSocket not available */ }
- }
-
_render_stats(stats)
{
const safe = (obj, path) => path.split(".").reduce((a, b) => a && a[b], obj);
diff --git a/src/zenserver/frontend/html/pages/compute.js b/src/zenserver/frontend/html/pages/compute.js
index ab3d49c27..2eb4d4e9b 100644
--- a/src/zenserver/frontend/html/pages/compute.js
+++ b/src/zenserver/frontend/html/pages/compute.js
@@ -24,6 +24,12 @@ function formatTime(date)
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
}
+function truncateHash(hash)
+{
+ if (!hash || hash.length <= 15) return hash;
+ return hash.slice(0, 6) + "\u2026" + hash.slice(-6);
+}
+
function formatDuration(startDate, endDate)
{
if (!startDate || !endDate) return "-";
@@ -100,39 +106,6 @@ export class Page extends ZenPage
}, 2000);
}
- _collapsible_section(name)
- {
- const section = this.add_section(name);
- const container = section._parent.inner();
- const heading = container.firstElementChild;
-
- heading.style.cursor = "pointer";
- heading.style.userSelect = "none";
-
- const indicator = document.createElement("span");
- indicator.textContent = " \u25BC";
- indicator.style.fontSize = "0.7em";
- heading.appendChild(indicator);
-
- let collapsed = false;
- heading.addEventListener("click", (e) => {
- if (e.target !== heading && e.target !== indicator)
- {
- return;
- }
- collapsed = !collapsed;
- indicator.textContent = collapsed ? " \u25B6" : " \u25BC";
- let sibling = heading.nextElementSibling;
- while (sibling)
- {
- sibling.style.display = collapsed ? "none" : "";
- sibling = sibling.nextElementSibling;
- }
- });
-
- return section;
- }
-
async _load_chartjs()
{
if (window.Chart)
@@ -338,11 +311,7 @@ export class Page extends ZenPage
{
const workerIds = data.workers || [];
- if (this._workers_table)
- {
- this._workers_table.clear();
- }
- else
+ if (!this._workers_table)
{
this._workers_table = this._workers_host.add_widget(
Table,
@@ -353,6 +322,7 @@ export class Page extends ZenPage
if (workerIds.length === 0)
{
+ this._workers_table.clear();
return;
}
@@ -382,6 +352,9 @@ export class Page extends ZenPage
id,
);
+ // Worker ID column: monospace for hex readability
+ row.get_cell(5).style("fontFamily", "'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace");
+
// Make name clickable to expand detail
const cell = row.get_cell(0);
cell.tag().text(name).on_click(() => this._toggle_worker_detail(id, desc));
@@ -579,6 +552,11 @@ export class Page extends ZenPage
["LSN", "queue", "status", "function", "started", "finished", "duration", "worker ID", "action ID"],
Table.Flag_FitLeft|Table.Flag_PackRight|Table.Flag_Sortable|Table.Flag_AlignNumeric, -1
);
+
+ // Right-align hash column headers to match data cells
+ const hdr = this._history_table.inner().firstElementChild;
+ hdr.children[7].style.textAlign = "right";
+ hdr.children[8].style.textAlign = "right";
}
// Entries arrive oldest-first; reverse to show newest at top
@@ -593,7 +571,10 @@ export class Page extends ZenPage
const startDate = filetimeToDate(entry.time_Running);
const endDate = filetimeToDate(entry.time_Completed ?? entry.time_Failed);
- this._history_table.add_row(
+ const workerId = entry.workerId || "-";
+ const actionId = entry.actionId || "-";
+
+ const row = this._history_table.add_row(
lsn,
queueId,
status,
@@ -601,9 +582,15 @@ export class Page extends ZenPage
formatTime(startDate),
formatTime(endDate),
formatDuration(startDate, endDate),
- entry.workerId || "-",
- entry.actionId || "-",
+ truncateHash(workerId),
+ truncateHash(actionId),
);
+
+ // Hash columns: force right-align (AlignNumeric misses hex strings starting with a-f),
+ // use monospace for readability, and show full value on hover
+ const mono = "'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace";
+ row.get_cell(7).style("textAlign", "right").style("fontFamily", mono).attr("title", workerId);
+ row.get_cell(8).style("textAlign", "right").style("fontFamily", mono).attr("title", actionId);
}
}
diff --git a/src/zenserver/frontend/html/pages/docs.js b/src/zenserver/frontend/html/pages/docs.js
new file mode 100644
index 000000000..8caf36d0c
--- /dev/null
+++ b/src/zenserver/frontend/html/pages/docs.js
@@ -0,0 +1,415 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+import { ZenPage } from "./page.js"
+import { marked, Renderer } from "../thirdparty/marked.esm.js"
+import { Fetcher } from "../util/fetcher.js"
+
+function slugify(text)
+{
+ return text.toLowerCase().replace(/[^\w]+/g, "-").replace(/^-|-$/g, "");
+}
+
+const renderer = new Renderer();
+renderer.heading = function({ text, depth })
+{
+ const id = slugify(text);
+ if (depth === 1)
+ {
+ return `<h1 id="${id}">${text}<a class="docs-source-link" title="View source"></a><a class="docs-github-link" title="View on GitHub" target="_blank"></a></h1>`;
+ }
+ if (depth === 2)
+ {
+ // Close previous <details> section (if any) and open a new one
+ return `</details><details class="docs-section" open><summary class="docs-section-title" id="${id}">${text}</summary>`;
+ }
+ return `<h${depth} id="${id}">${text}</h${depth}>`;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+export class Page extends ZenPage
+{
+ generate_crumbs() {}
+
+ async main()
+ {
+ this.set_title("docs");
+ this._parent.inner().classList.add("docs-page");
+
+ const index = await new Fetcher().resource("/dashboard/data/_index.json").json();
+ if (!index || index.length === 0)
+ {
+ this._parent.tag().text("No documentation available.");
+ return;
+ }
+
+ // Filter input
+ const filter_box = document.createElement("input");
+ filter_box.type = "text";
+ filter_box.className = "docs-filter";
+ filter_box.placeholder = "Filter\u2026";
+ filter_box.addEventListener("input", () => this._apply_filter(filter_box.value));
+ this._parent.inner().appendChild(filter_box);
+
+ // Layout: sidebar + content
+ const layout = document.createElement("div");
+ layout.className = "docs-layout";
+ this._parent.inner().appendChild(layout);
+
+ // Sidebar
+ const sidebar = document.createElement("nav");
+ sidebar.className = "docs-sidebar";
+ layout.appendChild(sidebar);
+
+ this._docs_index = index;
+ this._sidebar = sidebar;
+ this._selected_link = null;
+ this._filter = "";
+ this._docs_cache = {};
+
+ for (const entry of index)
+ {
+ const link = document.createElement("a");
+ link.className = "docs-sidebar-link";
+ link.textContent = entry.title;
+ link.href = "#";
+ link.addEventListener("click", (e) => {
+ e.preventDefault();
+ this._select_doc(entry, link);
+ });
+ sidebar.appendChild(link);
+ }
+
+ // Prefetch all docs in the background for filtering
+ Promise.all(index.map(entry =>
+ new Fetcher().resource("/dashboard/data/" + entry.path).text()
+ .then(md => { this._docs_cache[entry.path] = md.toLowerCase(); })
+ .catch(() => {})
+ ));
+
+ // Content area
+ const content = document.createElement("article");
+ content.className = "docs-content";
+ layout.appendChild(content);
+ this._content = content;
+
+ // Intercept clicks on links within rendered doc content
+ content.addEventListener("click", (e) => {
+ const anchor = e.target.closest("a");
+ if (!anchor || anchor.classList.contains("docs-source-link") || anchor.classList.contains("docs-github-link"))
+ {
+ return;
+ }
+
+ const href = anchor.getAttribute("href") || "";
+
+ // Fragment-only link (e.g. #workers) — scroll within current doc
+ if (href.startsWith("#"))
+ {
+ e.preventDefault();
+ this._scroll_to_fragment(href.slice(1));
+ return;
+ }
+
+ // Relative link to another doc (e.g. API.md or specs/CompactBinary.md)
+ if (!href.startsWith("http") && href.endsWith(".md"))
+ {
+ const parts = href.split("#");
+ const target_path = parts[0];
+ const target_fragment = parts[1] || null;
+ const target_entry = this._docs_index.find(d => d.path.toLowerCase() === target_path.toLowerCase());
+ if (target_entry)
+ {
+ e.preventDefault();
+ const target_link = this._sidebar.children[this._docs_index.indexOf(target_entry)];
+ this._select_doc(target_entry, target_link, target_fragment);
+ }
+ }
+ });
+
+ // Select initial doc from URL param or first entry
+ const requested = this.get_param("doc", "");
+ const initial = index.find(e => e.path === requested) || index[0];
+ const initial_link = sidebar.children[index.indexOf(initial)];
+ this._select_doc(initial, initial_link);
+ }
+
+ async _select_doc(entry, link, fragment)
+ {
+ if (this._selected_link)
+ {
+ this._selected_link.classList.remove("active");
+ }
+ this._selected_link = link;
+ link.classList.add("active");
+
+ this.set_param("doc", entry.path);
+
+ this._content.innerHTML = "<p class=\"docs-loading\">Loading\u2026</p>";
+
+ try
+ {
+ const md = await new Fetcher().resource("/dashboard/data/" + entry.path).text();
+ this._content.innerHTML = marked.parse(md, { renderer });
+
+ const source_link = this._content.querySelector(".docs-source-link");
+ if (source_link)
+ {
+ source_link.href = "/dashboard/data/" + entry.path;
+ }
+
+ const github_link = this._content.querySelector(".docs-github-link");
+ if (github_link)
+ {
+ github_link.href = "https://github.com/EpicGames/zen/blob/main/docs/" + entry.path;
+ }
+
+ // Render mermaid diagrams
+ await this._render_mermaid();
+
+ // Re-apply filter to the newly rendered content
+ if (this._filter)
+ {
+ this._apply_filter_to_content();
+ }
+
+ // Scroll to fragment if specified
+ const target_fragment = fragment || window.location.hash.slice(1);
+ if (target_fragment)
+ {
+ this._scroll_to_fragment(target_fragment);
+ }
+ else
+ {
+ window.scrollTo(0, 0);
+ }
+ }
+ catch (e)
+ {
+ this._content.innerHTML = "<p class=\"docs-error\">Failed to load document.</p>";
+ }
+ }
+
+ _scroll_to_fragment(id)
+ {
+ if (!id)
+ {
+ return;
+ }
+ const target = this._content.querySelector("#" + CSS.escape(id));
+ if (target)
+ {
+ target.scrollIntoView({ behavior: "smooth" });
+ }
+ }
+
+ _apply_filter(query)
+ {
+ this._filter = query.toLowerCase().trim();
+
+ // Filter sidebar entries based on cached doc content
+ const sidebar_links = this._sidebar.children;
+ for (let i = 0; i < this._docs_index.length; i++)
+ {
+ const entry = this._docs_index[i];
+ const link = sidebar_links[i];
+ if (!this._filter)
+ {
+ link.style.display = "";
+ continue;
+ }
+
+ const cached = this._docs_cache[entry.path];
+ const matches = !cached || cached.includes(this._filter) || entry.title.toLowerCase().includes(this._filter);
+ link.style.display = matches ? "" : "none";
+ }
+
+ this._apply_filter_to_content();
+ }
+
+ _apply_filter_to_content()
+ {
+ // Remove existing highlights
+ for (const mark of this._content.querySelectorAll("mark.docs-highlight"))
+ {
+ const parent = mark.parentNode;
+ parent.replaceChild(document.createTextNode(mark.textContent), mark);
+ parent.normalize();
+ }
+
+ const sections = this._content.querySelectorAll("details.docs-section");
+
+ for (const section of sections)
+ {
+ if (!this._filter)
+ {
+ section.style.display = "";
+ section.open = true;
+ continue;
+ }
+
+ const matches = section.textContent.toLowerCase().includes(this._filter);
+ section.style.display = matches ? "" : "none";
+
+ if (matches)
+ {
+ section.open = true;
+ this._highlight_element(section);
+ }
+ }
+ }
+
+ _get_mermaid_theme()
+ {
+ const attr = document.documentElement.getAttribute("data-theme");
+ const is_dark = attr
+ ? attr === "dark"
+ : window.matchMedia("(prefers-color-scheme: dark)").matches;
+ return is_dark ? "dark" : "default";
+ }
+
+ async _load_mermaid()
+ {
+ if (window.mermaid)
+ {
+ return window.mermaid;
+ }
+
+ return new Promise((resolve, reject) => {
+ const script = document.createElement("script");
+ script.src = "/dashboard/thirdparty/mermaid.min.js";
+ script.onload = () => {
+ window.mermaid.initialize({
+ startOnLoad: false,
+ theme: this._get_mermaid_theme(),
+ themeVariables: {
+ background: "transparent",
+ },
+ });
+ resolve(window.mermaid);
+ };
+ script.onerror = reject;
+ document.head.appendChild(script);
+ });
+ }
+
+ async _render_mermaid()
+ {
+ // marked renders ```mermaid blocks as <code class="language-mermaid"> inside <pre>
+ const code_blocks = this._content.querySelectorAll("pre > code.language-mermaid");
+ if (code_blocks.length === 0)
+ {
+ return;
+ }
+
+ try
+ {
+ const mermaid = await this._load_mermaid();
+
+ for (let i = 0; i < code_blocks.length; i++)
+ {
+ const code = code_blocks[i];
+ const pre = code.parentElement;
+ const definition = code.textContent;
+
+ const { svg } = await mermaid.render(`mermaid-${Date.now()}-${i}`, definition);
+
+ const container = document.createElement("div");
+ container.className = "docs-mermaid";
+ container.dataset.definition = definition;
+ container.innerHTML = svg;
+ pre.replaceWith(container);
+ }
+
+ this._watch_theme();
+ }
+ catch (e)
+ {
+ // Mermaid failed to load or render — leave code blocks as-is
+ }
+ }
+
+ _watch_theme()
+ {
+ if (this._theme_observer)
+ {
+ return;
+ }
+
+ this._theme_observer = new MutationObserver(() => this._rerender_mermaid());
+ this._theme_observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ["data-theme"],
+ });
+ }
+
+ async _rerender_mermaid()
+ {
+ const containers = this._content.querySelectorAll(".docs-mermaid[data-definition]");
+ if (containers.length === 0)
+ {
+ return;
+ }
+
+ try
+ {
+ const mermaid = await this._load_mermaid();
+ mermaid.initialize({
+ startOnLoad: false,
+ theme: this._get_mermaid_theme(),
+ themeVariables: {
+ background: "transparent",
+ },
+ });
+
+ for (let i = 0; i < containers.length; i++)
+ {
+ const container = containers[i];
+ const definition = container.dataset.definition;
+ const { svg } = await mermaid.render(`mermaid-${Date.now()}-${i}`, definition);
+ container.innerHTML = svg;
+ }
+ }
+ catch (e)
+ {
+ // Mermaid failed to re-render — leave existing SVGs as-is
+ }
+ }
+
+ _highlight_element(root)
+ {
+ const filter = this._filter;
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
+ const matches = [];
+
+ let node;
+ while ((node = walker.nextNode()))
+ {
+ if (node.parentElement && node.parentElement.closest("pre"))
+ {
+ continue;
+ }
+
+ const text = node.textContent.toLowerCase();
+ let pos = 0;
+ while ((pos = text.indexOf(filter, pos)) !== -1)
+ {
+ matches.push({ node, pos, len: filter.length });
+ pos += filter.length;
+ }
+ }
+
+ for (let i = matches.length - 1; i >= 0; i--)
+ {
+ const { node: text_node, pos, len } = matches[i];
+ const after = text_node.splitText(pos);
+ after.splitText(len);
+
+ const mark = document.createElement("mark");
+ mark.className = "docs-highlight";
+ mark.textContent = after.textContent;
+ after.parentNode.replaceChild(mark, after);
+ }
+ }
+}
diff --git a/src/zenserver/frontend/html/pages/entry.js b/src/zenserver/frontend/html/pages/entry.js
index 1e4c82e3f..e381f4a71 100644
--- a/src/zenserver/frontend/html/pages/entry.js
+++ b/src/zenserver/frontend/html/pages/entry.js
@@ -168,7 +168,7 @@ export class Page extends ZenPage
if (key === "cook.artifacts")
{
action_tb.left().add("view-raw").on_click(() => {
- window.location = "/" + ["prj", project, "oplog", oplog, value+".json"].join("/");
+ window.open("/" + ["prj", project, "oplog", oplog, value+".json"].join("/"), "_self");
});
}
diff --git a/src/zenserver/frontend/html/pages/hub.js b/src/zenserver/frontend/html/pages/hub.js
index f9e4fff33..274e3fd35 100644
--- a/src/zenserver/frontend/html/pages/hub.js
+++ b/src/zenserver/frontend/html/pages/hub.js
@@ -5,7 +5,74 @@
import { ZenPage } from "./page.js"
import { Fetcher } from "../util/fetcher.js"
import { Friendly } from "../util/friendly.js"
-import { Table } from "../util/widgets.js"
+import { Modal } from "../util/modal.js"
+
+////////////////////////////////////////////////////////////////////////////////
+const STABLE_STATES = new Set(["provisioned", "hibernated", "crashed"]);
+
+function _is_actionable(state)
+{
+ return STABLE_STATES.has(state);
+}
+
+function _btn_enabled(state, action)
+{
+ if (action === "hibernate") { return state === "provisioned"; }
+ if (action === "wake") { return state === "hibernated"; }
+ if (action === "deprovision") { return _is_actionable(state); }
+ return false;
+}
+
+// Click listener is on the wrap and guarded by !btn.disabled, so the tooltip
+// (title on the span) shows even when the button is disabled.
+function _make_action_btn(icon, tooltip, on_click)
+{
+ const wrap = document.createElement("span");
+ wrap.className = "module-action-wrap";
+ wrap.title = tooltip;
+
+ const btn = document.createElement("button");
+ btn.className = "module-action-btn";
+ btn.textContent = icon;
+
+ wrap.appendChild(btn);
+ wrap.addEventListener("click", () => { if (!btn.disabled) { on_click(); } });
+ return [wrap, btn];
+}
+
+function _make_bulk_btn(icon, label, on_click)
+{
+ const btn = document.createElement("button");
+ btn.className = "module-bulk-btn";
+ btn.appendChild(document.createTextNode(icon + "\u00A0" + label));
+ btn.addEventListener("click", on_click);
+ return btn;
+}
+
+function _format_metric_name(key)
+{
+ // Strip unit suffix, then split CamelCase into words
+ const name = key.replace(/(Bytes|Size|Usage|Ms)$/, "");
+ return name.replace(/([A-Z])/g, " $1").trim();
+}
+
+function _format_metric_value(key, value)
+{
+ if (key.endsWith("Ms")) { return _format_ms(value); }
+ if (key.endsWith("Bytes") || key.endsWith("Size") || key.endsWith("Usage")) { return Friendly.bytes(value); }
+ return Friendly.sep(value);
+}
+
+function _format_ms(ms)
+{
+ if (ms < 1000) { return `${ms} ms`; }
+ if (ms < 60000) { return `${(ms / 1000).toFixed(3)} s`; }
+ const h = Math.floor(ms / 3600000);
+ const m = Math.floor((ms % 3600000) / 60000);
+ const s = Math.floor((ms % 60000) / 1000);
+ if (h > 0) { return `${Friendly.sep(h)}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`; }
+ return `${m}:${String(s).padStart(2, "0")}`;
+}
////////////////////////////////////////////////////////////////////////////////
export class Page extends ZenPage
@@ -15,13 +82,92 @@ export class Page extends ZenPage
this.set_title("hub");
// Capacity
- const stats_section = this.add_section("Capacity");
+ const stats_section = this._collapsible_section("Hub Service Stats");
this._stats_grid = stats_section.tag().classify("grid").classify("stats-tiles");
// Modules
const mod_section = this.add_section("Modules");
- this._mod_host = mod_section;
- this._mod_table = null;
+ const mod_host = mod_section.tag().inner();
+
+ // Toolbar: selection actions on left, "All" actions on right, always visible
+ this._bulk_bar = document.createElement("div");
+ this._bulk_bar.className = "module-bulk-bar";
+ this._bulk_label = document.createElement("span");
+ this._bulk_label.className = "module-bulk-label";
+ this._btn_bulk_hibernate = _make_bulk_btn("\u23F8", "Hibernate", () => this._exec_action("hibernate", [...this._selected]));
+ this._btn_bulk_wake = _make_bulk_btn("\u25B6", "Wake", () => this._exec_action("wake", [...this._selected]));
+ this._btn_bulk_deprov = _make_bulk_btn("\u2715", "Deprovision",() => this._confirm_deprovision([...this._selected]));
+ const bulk_sep = document.createElement("div");
+ bulk_sep.className = "module-bulk-sep";
+ this._btn_hibernate_all = _make_bulk_btn("\u23F8", "Hibernate All", () => this._confirm_all("hibernate", "Hibernate All"));
+ this._btn_wake_all = _make_bulk_btn("\u25B6", "Wake All", () => this._confirm_all("wake", "Wake All"));
+ this._btn_deprov_all = _make_bulk_btn("\u2715", "Deprovision All",() => this._confirm_all("deprovision", "Deprovision All"));
+ this._bulk_bar.appendChild(this._bulk_label);
+ this._bulk_bar.appendChild(this._btn_bulk_hibernate);
+ this._bulk_bar.appendChild(this._btn_bulk_wake);
+ this._bulk_bar.appendChild(this._btn_bulk_deprov);
+ this._bulk_bar.appendChild(bulk_sep);
+ this._bulk_bar.appendChild(this._btn_hibernate_all);
+ this._bulk_bar.appendChild(this._btn_wake_all);
+ this._bulk_bar.appendChild(this._btn_deprov_all);
+ mod_host.appendChild(this._bulk_bar);
+
+ // Module table
+ const table = document.createElement("table");
+ table.className = "module-table";
+ const thead = document.createElement("thead");
+ const hrow = document.createElement("tr");
+
+ const th_check = document.createElement("th");
+ th_check.style.width = "28px";
+ this._select_all_cb = document.createElement("input");
+ this._select_all_cb.type = "checkbox";
+ this._select_all_cb.addEventListener("change", () => this._on_select_all());
+ th_check.appendChild(this._select_all_cb);
+ hrow.appendChild(th_check);
+
+ for (const label of ["#", "MODULE ID", "STATUS", "PORT", "ACTIONS"])
+ {
+ const th = document.createElement("th");
+ th.textContent = label;
+ hrow.appendChild(th);
+ }
+
+ thead.appendChild(hrow);
+ table.appendChild(thead);
+
+ this._tbody = document.createElement("tbody");
+ table.appendChild(this._tbody);
+ mod_host.appendChild(table);
+
+ // Pagination controls — direct child of zen_sector so CSS can pin it beside the heading
+ const pager = mod_section.tag().classify("module-pager").inner();
+ this._btn_prev = document.createElement("button");
+ this._btn_prev.className = "module-pager-btn";
+ this._btn_prev.textContent = "\u2190 Prev";
+ this._btn_prev.addEventListener("click", () => this._go_page(this._page - 1));
+ this._pager_label = document.createElement("span");
+ this._pager_label.className = "module-pager-label";
+ this._btn_next = document.createElement("button");
+ this._btn_next.className = "module-pager-btn";
+ this._btn_next.textContent = "Next \u2192";
+ this._btn_next.addEventListener("click", () => this._go_page(this._page + 1));
+ this._btn_provision = _make_bulk_btn("+", "Provision", () => this._show_provision_modal());
+ pager.appendChild(this._btn_provision);
+ pager.appendChild(this._btn_prev);
+ pager.appendChild(this._pager_label);
+ pager.appendChild(this._btn_next);
+
+ // State
+ this._selected = new Set();
+ this._modules_data = [];
+ this._module_map = new Map(); // moduleId → module, for O(1) lookup
+ this._prev_states = new Map(); // moduleId → last stable state, for deprovisioning dot
+ this._row_cache = new Map(); // moduleId → row refs, for in-place DOM updates
+ this._updating = false;
+ this._page = 0;
+ this._page_size = 50;
+ this._expanded = new Set(); // moduleIds with open metrics panel
await this._update();
this._poll_timer = setInterval(() => this._update(), 2000);
@@ -29,10 +175,12 @@ export class Page extends ZenPage
async _update()
{
+ if (this._updating) { return; }
+ this._updating = true;
try
{
const [stats, status] = await Promise.all([
- new Fetcher().resource("/hub/stats").json(),
+ new Fetcher().resource("stats", "hub").json(),
new Fetcher().resource("/hub/status").json(),
]);
@@ -40,6 +188,7 @@ export class Page extends ZenPage
this._render_modules(status);
}
catch (e) { /* service unavailable */ }
+ finally { this._updating = false; }
}
_render_capacity(data)
@@ -48,32 +197,54 @@ export class Page extends ZenPage
grid.inner().innerHTML = "";
const current = data.currentInstanceCount || 0;
- const max = data.maxInstanceCount || 0;
- const limit = data.instanceLimit || 0;
+ const max = data.maxInstanceCount || 0;
+ const limit = data.instanceLimit || 0;
+
+ // HTTP Requests tile
+ this._render_http_requests_tile(grid, data.requests);
{
const tile = grid.tag().classify("card").classify("stats-tile");
- tile.tag().classify("card-title").text("Active Modules");
+ tile.tag().classify("card-title").text("Instances");
const body = tile.tag().classify("tile-metrics");
this._metric(body, Friendly.sep(current), "currently provisioned", true);
+ this._metric(body, Friendly.sep(max), "high watermark");
+ this._metric(body, Friendly.sep(limit), "maximum allowed");
+ if (limit > 0)
+ {
+ const pct = ((current / limit) * 100).toFixed(0) + "%";
+ this._metric(body, pct, "utilization");
+ }
}
+ const machine = data.machine || {};
+ const limits = data.resource_limits || {};
+ if (machine.disk_total_bytes > 0 || machine.memory_total_mib > 0)
{
- const tile = grid.tag().classify("card").classify("stats-tile");
- tile.tag().classify("card-title").text("Peak Modules");
- const body = tile.tag().classify("tile-metrics");
- this._metric(body, Friendly.sep(max), "high watermark", true);
- }
+ const disk_used = Math.max(0, (machine.disk_total_bytes || 0) - (machine.disk_free_bytes || 0));
+ const mem_used = Math.max(0, (machine.memory_total_mib || 0) - (machine.memory_avail_mib || 0)) * 1024 * 1024;
+ const vmem_used = Math.max(0, (machine.virtual_memory_total_mib || 0) - (machine.virtual_memory_avail_mib || 0)) * 1024 * 1024;
+ const disk_limit = limits.disk_bytes || 0;
+ const mem_limit = limits.memory_bytes || 0;
+ const disk_over = disk_limit > 0 && disk_used > disk_limit;
+ const mem_over = mem_limit > 0 && mem_used > mem_limit;
- {
const tile = grid.tag().classify("card").classify("stats-tile");
- tile.tag().classify("card-title").text("Instance Limit");
- const body = tile.tag().classify("tile-metrics");
- this._metric(body, Friendly.sep(limit), "maximum allowed", true);
- if (limit > 0)
+ if (disk_over || mem_over) { tile.inner().setAttribute("data-over", "true"); }
+ tile.tag().classify("card-title").text("Resources");
+ const columns = tile.tag().classify("tile-columns");
+
+ const left = columns.tag().classify("tile-metrics");
+ this._metric(left, Friendly.bytes(disk_used), "disk used", true);
+ if (disk_limit > 0) { this._metric(left, Friendly.bytes(disk_limit), "disk limit"); }
+
+ const right = columns.tag().classify("tile-metrics");
+ this._metric(right, Friendly.bytes(mem_used), "memory used", true);
+ if (mem_limit > 0) { this._metric(right, Friendly.bytes(mem_limit), "memory limit"); }
+ if (machine.virtual_memory_total_mib > 0)
{
- const pct = ((current / limit) * 100).toFixed(0) + "%";
- this._metric(body, pct, "utilization");
+ this._metric(right, Friendly.bytes(vmem_used), "vmem used", true);
+ this._metric(right, Friendly.bytes(machine.virtual_memory_total_mib * 1024 * 1024), "vmem total");
}
}
}
@@ -81,42 +252,548 @@ export class Page extends ZenPage
_render_modules(data)
{
const modules = data.modules || [];
+ this._modules_data = modules;
+ this._module_map = new Map(modules.map(m => [m.moduleId, m]));
+
+ // Update previous-state tracking (for deprovisioning dot animation)
+ for (const m of modules)
+ {
+ if (STABLE_STATES.has(m.state))
+ {
+ this._prev_states.set(m.moduleId, m.state);
+ }
+ }
+
+ this._prune_stale(this._selected);
+ this._prune_stale(this._prev_states);
+ this._prune_stale(this._expanded);
+
+ for (const [id, row] of this._row_cache)
+ {
+ if (!this._module_map.has(id))
+ {
+ row.tr.remove();
+ row.metrics_tr.remove();
+ this._row_cache.delete(id);
+ }
+ }
+
+ // Create or update rows, then reorder tbody to match response order.
+ // appendChild on an existing node moves it, so iterating in response order
+ // achieves a correct sort without touching rows already in the right position.
+ for (let i = 0; i < modules.length; i++)
+ {
+ const m = modules[i];
+ const id = m.moduleId || "";
+ const state = m.state || "unprovisioned";
+ const prev = this._prev_states.get(id) || "provisioned";
+
+ let row = this._row_cache.get(id);
+ if (row)
+ {
+ // Update in-place — preserves DOM node identity so CSS animations are not reset
+ row.idx.textContent = i + 1;
+ row.cb.checked = this._selected.has(id);
+ row.dot.setAttribute("data-state", state);
+ if (state === "deprovisioning")
+ {
+ row.dot.setAttribute("data-prev-state", prev);
+ }
+ else
+ {
+ row.dot.removeAttribute("data-prev-state");
+ }
+ row.state_text.nodeValue = state;
+ row.port_text.nodeValue = m.port ? String(m.port) : "";
+ if (m.state_change_time)
+ {
+ const state_label = state.charAt(0).toUpperCase() + state.slice(1);
+ row.state_since_label.textContent = state_label + " since";
+ row.state_age_label.textContent = state_label + " for";
+ row.state_since_node.nodeValue = m.state_change_time;
+ row.state_age_node.nodeValue = Friendly.timespan(Date.now() - new Date(m.state_change_time).getTime());
+ }
+ row.btn_open.disabled = state !== "provisioned";
+ row.btn_hibernate.disabled = !_btn_enabled(state, "hibernate");
+ row.btn_wake.disabled = !_btn_enabled(state, "wake");
+ row.btn_deprov.disabled = !_btn_enabled(state, "deprovision");
+
+ if (m.process_metrics)
+ {
+ for (const [key, node] of row.metric_nodes)
+ {
+ const val = m.process_metrics[key];
+ if (val !== undefined) { node.nodeValue = _format_metric_value(key, val); }
+ }
+ }
+ }
+ else
+ {
+ // Create new row
+ const tr = document.createElement("tr");
+
+ // Metrics sub-row (created first so the expand handler can reference it)
+ const metrics_tr = document.createElement("tr");
+ metrics_tr.className = "module-metrics-row";
+ metrics_tr.style.display = this._expanded.has(id) ? "" : "none";
+
+ const td_check = document.createElement("td");
+ const cb = document.createElement("input");
+ cb.type = "checkbox";
+ cb.checked = this._selected.has(id);
+ cb.addEventListener("change", () => {
+ if (cb.checked) { this._selected.add(id); }
+ else { this._selected.delete(id); }
+ this._update_selection_ui();
+ });
+ td_check.appendChild(cb);
+ tr.appendChild(td_check);
- if (this._mod_table)
+ const td_idx = document.createElement("td");
+ td_idx.textContent = i + 1;
+ tr.appendChild(td_idx);
+
+ const btn_expand = document.createElement("button");
+ btn_expand.className = "module-expand-btn";
+ btn_expand.textContent = this._expanded.has(id) ? "\u25BE" : "\u25B8";
+ btn_expand.addEventListener("click", () => {
+ if (this._expanded.has(id))
+ {
+ this._expanded.delete(id);
+ metrics_tr.style.display = "none";
+ btn_expand.textContent = "\u25B8";
+ }
+ else
+ {
+ this._expanded.add(id);
+ metrics_tr.style.display = "";
+ btn_expand.textContent = "\u25BE";
+ }
+ });
+
+ const td_id = document.createElement("td");
+ const id_wrap = document.createElement("span");
+ id_wrap.style.cssText = "display:inline-flex;align-items:center;font-family:monospace;font-size:14px;";
+ id_wrap.appendChild(btn_expand);
+ id_wrap.appendChild(document.createTextNode("\u00A0" + id));
+ td_id.appendChild(id_wrap);
+ tr.appendChild(td_id);
+
+ const td_status = document.createElement("td");
+ const dot = document.createElement("span");
+ dot.className = "module-state-dot";
+ dot.setAttribute("data-state", state);
+ if (state === "deprovisioning")
+ {
+ dot.setAttribute("data-prev-state", prev);
+ }
+ const state_node = document.createTextNode(state);
+ td_status.appendChild(dot);
+ td_status.appendChild(state_node);
+ tr.appendChild(td_status);
+
+ const port = m.port || 0;
+ const td_port = document.createElement("td");
+ td_port.style.cssText = "font-variant-numeric:tabular-nums;";
+ const port_node = document.createTextNode(port ? String(port) : "");
+ td_port.appendChild(port_node);
+ tr.appendChild(td_port);
+
+ const td_action = document.createElement("td");
+ td_action.className = "module-action-cell";
+ const [wrap_o, btn_o] = _make_action_btn("\u2197", "Open dashboard", () => {
+ window.open(`/hub/proxy/${port}/dashboard/`, "_blank");
+ });
+ btn_o.disabled = state !== "provisioned";
+ const [wrap_h, btn_h] = _make_action_btn("\u23F8", "Hibernate", () => this._post_module_action(id, "hibernate").then(() => this._update()));
+ const [wrap_w, btn_w] = _make_action_btn("\u25B6", "Wake", () => this._post_module_action(id, "wake").then(() => this._update()));
+ const [wrap_d, btn_d] = _make_action_btn("\u2715", "Deprovision", () => this._confirm_deprovision([id]));
+ btn_h.disabled = !_btn_enabled(state, "hibernate");
+ btn_w.disabled = !_btn_enabled(state, "wake");
+ btn_d.disabled = !_btn_enabled(state, "deprovision");
+ td_action.appendChild(wrap_h);
+ td_action.appendChild(wrap_w);
+ td_action.appendChild(wrap_d);
+ td_action.appendChild(wrap_o);
+ tr.appendChild(td_action);
+
+ // Build metrics grid: fixed state-time rows followed by process_metrics keys.
+ // Keys are split into two halves and interleaved so the grid fills
+ // top-to-bottom in the left column before continuing in the right column.
+ const metric_nodes = new Map();
+ const metrics_td = document.createElement("td");
+ metrics_td.colSpan = 6;
+ const metrics_grid = document.createElement("div");
+ metrics_grid.className = "module-metrics-grid";
+
+ const _add_fixed_pair = (label, value_str) => {
+ const label_el = document.createElement("span");
+ label_el.className = "module-metrics-label";
+ label_el.textContent = label;
+ const value_node = document.createTextNode(value_str);
+ const value_el = document.createElement("span");
+ value_el.className = "module-metrics-value";
+ value_el.appendChild(value_node);
+ metrics_grid.appendChild(label_el);
+ metrics_grid.appendChild(value_el);
+ return { label_el, value_node };
+ };
+
+ const state_label = m.state ? m.state.charAt(0).toUpperCase() + m.state.slice(1) : "State";
+ const state_since_str = m.state_change_time || "";
+ const state_age_str = m.state_change_time
+ ? Friendly.timespan(Date.now() - new Date(m.state_change_time).getTime())
+ : "";
+ const { label_el: state_since_label, value_node: state_since_node } = _add_fixed_pair(state_label + " since", state_since_str);
+ const { label_el: state_age_label, value_node: state_age_node } = _add_fixed_pair(state_label + " for", state_age_str);
+
+ const keys = Object.keys(m.process_metrics || {});
+ const half = Math.ceil(keys.length / 2);
+ const add_metric_pair = (key) => {
+ const label_el = document.createElement("span");
+ label_el.className = "module-metrics-label";
+ label_el.textContent = _format_metric_name(key);
+ const value_node = document.createTextNode(_format_metric_value(key, m.process_metrics[key]));
+ const value_el = document.createElement("span");
+ value_el.className = "module-metrics-value";
+ value_el.appendChild(value_node);
+ metrics_grid.appendChild(label_el);
+ metrics_grid.appendChild(value_el);
+ metric_nodes.set(key, value_node);
+ };
+ for (let i = 0; i < half; i++)
+ {
+ add_metric_pair(keys[i]);
+ if (i + half < keys.length) { add_metric_pair(keys[i + half]); }
+ else
+ {
+ metrics_grid.appendChild(document.createElement("span"));
+ metrics_grid.appendChild(document.createElement("span"));
+ }
+ }
+ metrics_td.appendChild(metrics_grid);
+ metrics_tr.appendChild(metrics_td);
+
+ row = { tr, metrics_tr, idx: td_idx, cb, dot, state_text: state_node, port_text: port_node, btn_expand, btn_open: btn_o, btn_hibernate: btn_h, btn_wake: btn_w, btn_deprov: btn_d, metric_nodes, state_since_node, state_age_node, state_since_label, state_age_label };
+ this._row_cache.set(id, row);
+ }
+
+ }
+
+ // Clamp page in case the total shrank
+ const max_page = Math.max(0, Math.ceil(modules.length / this._page_size) - 1);
+ if (this._page > max_page) { this._page = max_page; }
+
+ this._render_page();
+ this._update_selection_ui();
+ this._update_all_toolbar();
+ }
+
+ // Removes IDs from a Set or Map that are no longer present in _module_map.
+ // _row_cache is handled separately because removal has DOM side effects.
+ _prune_stale(collection)
+ {
+ for (const id of collection.keys())
{
- this._mod_table.clear();
+ if (!this._module_map.has(id))
+ {
+ collection.delete(id);
+ }
+ }
+ }
+
+ _render_page()
+ {
+ const start = this._page * this._page_size;
+ const end = Math.min(start + this._page_size, this._modules_data.length);
+ const page_ids = new Set();
+ for (let i = start; i < end; i++)
+ {
+ page_ids.add(this._modules_data[i].moduleId || "");
+ }
+
+ // Remove rows not on this page from tbody
+ for (const [id, row] of this._row_cache)
+ {
+ if (!page_ids.has(id) && row.tr.parentNode === this._tbody)
+ {
+ row.tr.remove();
+ row.metrics_tr.remove();
+ }
+ }
+
+ // Append/reorder current page rows in response order
+ for (let i = start; i < end; i++)
+ {
+ const id = this._modules_data[i].moduleId || "";
+ const row = this._row_cache.get(id);
+ if (row)
+ {
+ this._tbody.appendChild(row.tr);
+ this._tbody.appendChild(row.metrics_tr);
+ }
+ }
+
+ this._update_pagination_ui();
+ }
+
+ _go_page(n)
+ {
+ const max = Math.max(0, Math.ceil(this._modules_data.length / this._page_size) - 1);
+ this._page = Math.max(0, Math.min(n, max));
+ this._render_page();
+ }
+
+ _update_pagination_ui()
+ {
+ const total = this._modules_data.length;
+ const page_count = Math.max(1, Math.ceil(total / this._page_size));
+ const start = this._page * this._page_size + 1;
+ const end = Math.min(start + this._page_size - 1, total);
+
+ this._btn_prev.disabled = this._page === 0;
+ this._btn_next.disabled = this._page >= page_count - 1;
+ this._pager_label.textContent = total === 0
+ ? "No modules"
+ : `${start}\u2013${end} of ${total}`;
+ }
+
+ _module_state(id)
+ {
+ const m = this._module_map.get(id);
+ return m ? m.state : undefined;
+ }
+
+ _all_selected_in_state(state)
+ {
+ if (this._selected.size === 0) { return false; }
+ for (const id of this._selected)
+ {
+ if (this._module_state(id) !== state) { return false; }
+ }
+ return true;
+ }
+
+ _update_selection_ui()
+ {
+ const total = this._modules_data.length;
+ const selected = this._selected.size;
+
+ this._bulk_label.textContent = `${selected} module${selected !== 1 ? "s" : ""} selected`;
+
+ this._btn_bulk_hibernate.disabled = !this._all_selected_in_state("provisioned");
+ this._btn_bulk_wake.disabled = !this._all_selected_in_state("hibernated");
+ this._btn_bulk_deprov.disabled = selected === 0;
+
+ this._select_all_cb.disabled = total === 0;
+ this._select_all_cb.checked = selected === total && total > 0;
+ this._select_all_cb.indeterminate = selected > 0 && selected < total;
+ }
+
+ _update_all_toolbar()
+ {
+ const empty = this._modules_data.length === 0;
+ this._btn_hibernate_all.disabled = empty;
+ this._btn_wake_all.disabled = empty;
+ this._btn_deprov_all.disabled = empty;
+ }
+
+ _on_select_all()
+ {
+ if (this._select_all_cb.checked)
+ {
+ for (const m of this._modules_data)
+ {
+ this._selected.add(m.moduleId);
+ }
}
else
{
- this._mod_table = this._mod_host.add_widget(
- Table,
- ["module ID", "status"],
- Table.Flag_FitLeft|Table.Flag_PackRight
- );
+ this._selected.clear();
}
- if (modules.length === 0)
+ for (const cb of this._tbody.querySelectorAll("input[type=checkbox]"))
{
- return;
+ cb.checked = this._select_all_cb.checked;
}
- for (const m of modules)
+ this._update_selection_ui();
+ }
+
+ _confirm_deprovision(ids)
+ {
+ let message;
+ if (ids.length === 1)
{
- this._mod_table.add_row(
- m.moduleId || "",
- m.provisioned ? "provisioned" : "inactive",
- );
+ const id = ids[0];
+ const state = this._module_state(id) || "unknown";
+ message = `Are you sure you want to deprovision this module?\n\nModule ID: ${id}\nCurrent state: ${state}`;
}
+ else
+ {
+ message = `Deprovision ${ids.length} selected modules?`;
+ }
+
+ new Modal()
+ .title("Confirm Deprovision")
+ .message(message)
+ .option("Cancel", null)
+ .option("Deprovision", () => this._exec_action("deprovision", ids));
+ }
+
+ _confirm_all(action, label)
+ {
+ // Capture IDs at modal-open time so action targets the displayed list
+ const ids = this._modules_data.map(m => m.moduleId);
+ const n = ids.length;
+ const verb = action.charAt(0).toUpperCase() + action.slice(1);
+ new Modal()
+ .title(`Confirm ${label}`)
+ .message(`${verb} all ${n} module${n !== 1 ? "s" : ""}?`)
+ .option("Cancel", null)
+ .option(label, () => this._exec_action(action, ids));
+ }
+
+ async _exec_action(action, ids)
+ {
+ await Promise.allSettled(ids.map(id => this._post_module_action(id, action)));
+ await this._update();
+ }
+
+ async _post_module_action(moduleId, action)
+ {
+ await fetch(`/hub/modules/${moduleId}/${action}`, { method: "POST" });
}
- _metric(parent, value, label, hero = false)
+ _show_provision_modal()
{
- const m = parent.tag().classify("tile-metric");
- if (hero)
+ const MODULE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
+
+ const overlay = document.createElement("div");
+ overlay.className = "zen_modal";
+
+ const bg = document.createElement("div");
+ bg.className = "zen_modal_bg";
+ bg.addEventListener("click", () => overlay.remove());
+ overlay.appendChild(bg);
+
+ const dialog = document.createElement("div");
+ overlay.appendChild(dialog);
+
+ const title = document.createElement("div");
+ title.className = "zen_modal_title";
+ title.textContent = "Provision Module";
+ dialog.appendChild(title);
+
+ const content = document.createElement("div");
+ content.className = "zen_modal_message";
+ content.style.textAlign = "center";
+
+ const input = document.createElement("input");
+ input.type = "text";
+ input.placeholder = "module-name";
+ input.style.cssText = "width:100%;font-size:14px;padding:8px 12px;";
+ content.appendChild(input);
+
+ const error_div = document.createElement("div");
+ error_div.style.cssText = "color:var(--theme_fail);font-size:12px;margin-top:8px;min-height:1.2em;";
+ content.appendChild(error_div);
+
+ dialog.appendChild(content);
+
+ const buttons = document.createElement("div");
+ buttons.className = "zen_modal_buttons";
+
+ const btn_cancel = document.createElement("div");
+ btn_cancel.textContent = "Cancel";
+ btn_cancel.addEventListener("click", () => overlay.remove());
+
+ const btn_submit = document.createElement("div");
+ btn_submit.textContent = "Provision";
+
+ buttons.appendChild(btn_cancel);
+ buttons.appendChild(btn_submit);
+ dialog.appendChild(buttons);
+
+ let submitting = false;
+
+ const set_submit_enabled = (enabled) => {
+ btn_submit.style.opacity = enabled ? "" : "0.4";
+ btn_submit.style.pointerEvents = enabled ? "" : "none";
+ };
+
+ set_submit_enabled(false);
+
+ const validate = () => {
+ if (submitting) { return false; }
+ const val = input.value.trim();
+ if (val.length === 0)
+ {
+ error_div.textContent = "";
+ set_submit_enabled(false);
+ return false;
+ }
+ if (!MODULE_ID_RE.test(val))
+ {
+ error_div.textContent = "Only letters, numbers, and hyphens allowed (must start with a letter or number)";
+ set_submit_enabled(false);
+ return false;
+ }
+ error_div.textContent = "";
+ set_submit_enabled(true);
+ return true;
+ };
+
+ input.addEventListener("input", validate);
+
+ const submit = async () => {
+ if (submitting) { return; }
+ const moduleId = input.value.trim();
+ if (!MODULE_ID_RE.test(moduleId)) { return; }
+
+ submitting = true;
+ set_submit_enabled(false);
+ error_div.textContent = "";
+
+ try
+ {
+ const resp = await fetch(`/hub/modules/${encodeURIComponent(moduleId)}/provision`, { method: "POST" });
+ if (resp.ok)
+ {
+ overlay.remove();
+ await this._update();
+ this._navigate_to_module(moduleId);
+ return;
+ }
+ const msg = await resp.text();
+ error_div.textContent = msg || ("HTTP " + resp.status);
+ }
+ catch (e)
+ {
+ error_div.textContent = e.message || "Request failed";
+ }
+ submitting = false;
+ set_submit_enabled(true);
+ };
+
+ btn_submit.addEventListener("click", submit);
+ input.addEventListener("keydown", (e) => {
+ if (e.key === "Enter" && validate()) { submit(); }
+ if (e.key === "Escape") { overlay.remove(); }
+ });
+
+ document.body.appendChild(overlay);
+ input.focus();
+ }
+
+ _navigate_to_module(moduleId)
+ {
+ const idx = this._modules_data.findIndex(m => m.moduleId === moduleId);
+ if (idx >= 0)
{
- m.classify("tile-metric-hero");
+ this._page = Math.floor(idx / this._page_size);
+ this._render_page();
}
- m.tag().classify("metric-value").text(value);
- m.tag().classify("metric-label").text(label);
}
+
}
diff --git a/src/zenserver/frontend/html/pages/info.js b/src/zenserver/frontend/html/pages/info.js
index f92765c78..87b565f1e 100644
--- a/src/zenserver/frontend/html/pages/info.js
+++ b/src/zenserver/frontend/html/pages/info.js
@@ -9,6 +9,8 @@ import { Friendly } from "../util/friendly.js"
////////////////////////////////////////////////////////////////////////////////
export class Page extends ZenPage
{
+ generate_crumbs() {}
+
async main()
{
this.set_title("info");
@@ -54,6 +56,10 @@ export class Page extends ZenPage
const list = tile.tag().classify("info-props");
this._prop(list, "hostname", info.Hostname || "-");
+ if (info.IpAddresses && info.IpAddresses.length > 0)
+ {
+ this._prop(list, "ip addresses", info.IpAddresses.join(", "));
+ }
this._prop(list, "platform", info.Platform || "-");
this._prop(list, "os", info.OS || "-");
this._prop(list, "arch", info.Arch || "-");
diff --git a/src/zenserver/frontend/html/pages/network.js b/src/zenserver/frontend/html/pages/network.js
new file mode 100644
index 000000000..c41a6ed85
--- /dev/null
+++ b/src/zenserver/frontend/html/pages/network.js
@@ -0,0 +1,247 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+import { ZenPage } from "./page.js"
+import { Fetcher } from "../util/fetcher.js"
+import { Friendly } from "../util/friendly.js"
+import { Table } from "../util/widgets.js"
+
+////////////////////////////////////////////////////////////////////////////////
+export class Page extends ZenPage
+{
+ generate_crumbs() {}
+
+ async main()
+ {
+ this.set_title("network");
+
+ const providers_data = await new Fetcher().resource("stats").json();
+ const provider_list = providers_data["providers"] || [];
+ const all_stats = {};
+ await Promise.all(provider_list.map(async (provider) => {
+ all_stats[provider] = await new Fetcher().resource("stats", provider).json();
+ }));
+
+ this._all_stats = all_stats;
+
+ // Overview
+ this._render_overview(all_stats);
+
+ // Per-service request breakdown
+ this._render_services(all_stats, provider_list);
+
+ // Proxy connections (if available)
+ if (all_stats["proxy"])
+ {
+ this._render_proxy(all_stats["proxy"]);
+ }
+
+ // WebSocket live updates
+ this.connect_stats_ws((all_stats) => {
+ this._all_stats = all_stats;
+ this._populate_overview(all_stats);
+ this._populate_services(all_stats, Object.keys(all_stats));
+ });
+ }
+
+ _render_overview(all_stats)
+ {
+ const section = this.add_section("Overview");
+ this._overview_grid = section.tag().classify("grid").classify("info-tiles");
+ this._populate_overview(all_stats);
+ }
+
+ _populate_overview(all_stats)
+ {
+ this._overview_grid.inner().innerHTML = "";
+
+ const safe = (obj, path) => path.split(".").reduce((a, b) => a && a[b], obj);
+
+ // HTTP overview tile
+ {
+ const tile = this._overview_grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("HTTP");
+ const list = tile.tag().classify("info-props");
+
+ let totalRequests = 0;
+ let totalRate = 0;
+ for (const p in all_stats)
+ {
+ totalRequests += (safe(all_stats[p], "requests.count") || 0);
+ totalRate += (safe(all_stats[p], "requests.rate_1") || 0);
+ }
+
+ this._prop(list, "total requests", Friendly.sep(totalRequests));
+ if (totalRate > 0)
+ {
+ this._prop(list, "req/sec (1m)", Friendly.sep(totalRate, 1) + "/s");
+ }
+
+ const httpStats = all_stats["http"];
+ if (httpStats)
+ {
+ if (httpStats.distinct_clients)
+ {
+ this._prop(list, "distinct clients", Friendly.sep(httpStats.distinct_clients));
+ }
+ if (httpStats.distinct_sessions)
+ {
+ this._prop(list, "distinct sessions", Friendly.sep(httpStats.distinct_sessions));
+ }
+
+ const bytes = httpStats.bytes || {};
+ if (bytes.received)
+ {
+ this._prop(list, "received", Friendly.bytes(bytes.received));
+ }
+ if (bytes.sent)
+ {
+ this._prop(list, "sent", Friendly.bytes(bytes.sent));
+ }
+
+ const req = httpStats.requests || {};
+ if (req.t_avg)
+ {
+ this._prop(list, "avg latency", Friendly.duration(req.t_avg));
+ }
+ if (req.t_p95)
+ {
+ this._prop(list, "p95 latency", Friendly.duration(req.t_p95));
+ }
+ if (req.t_p99)
+ {
+ this._prop(list, "p99 latency", Friendly.duration(req.t_p99));
+ }
+ }
+ }
+
+ // WebSocket tile
+ {
+ const ws = all_stats["http"] ? (all_stats["http"]["websockets"] || {}) : {};
+ const tile = this._overview_grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("WebSocket");
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "active connections", Friendly.sep(ws.active_connections || 0));
+ this._prop(list, "frames received", Friendly.sep(ws.frames_received || 0));
+ this._prop(list, "frames sent", Friendly.sep(ws.frames_sent || 0));
+
+ const totalBytes = (ws.bytes_received || 0) + (ws.bytes_sent || 0);
+ if (totalBytes > 0)
+ {
+ this._prop(list, "bytes received", Friendly.bytes(ws.bytes_received || 0));
+ this._prop(list, "bytes sent", Friendly.bytes(ws.bytes_sent || 0));
+ }
+ }
+ }
+
+ _render_services(all_stats, provider_list)
+ {
+ const section = this.add_section("Requests by Service");
+ this._services_host = section.tag();
+ this._populate_services(all_stats, provider_list);
+ }
+
+ _populate_services(all_stats, provider_list)
+ {
+ this._services_host.inner().innerHTML = "";
+
+ const safe = (obj, path) => path.split(".").reduce((a, b) => a && a[b], obj);
+
+ const table = new Table(this._services_host,
+ ["service", "requests", "req/sec", "avg", "p95", "p99", "received", "sent"],
+ Table.Flag_FitLeft | Table.Flag_PackRight | Table.Flag_AlignNumeric, -1);
+
+ // Sort providers by request count (descending)
+ const sorted = provider_list
+ .filter(p => all_stats[p] && (safe(all_stats[p], "requests.count") || 0) > 0)
+ .sort((a, b) => (safe(all_stats[b], "requests.count") || 0) - (safe(all_stats[a], "requests.count") || 0));
+
+ for (const provider of sorted)
+ {
+ const stats = all_stats[provider];
+ const req = stats.requests || {};
+ const bytes = stats.bytes || {};
+
+ table.add_row(
+ provider,
+ Friendly.sep(req.count || 0),
+ req.rate_1 ? Friendly.sep(req.rate_1, 1) + "/s" : "-",
+ req.t_avg ? Friendly.duration(req.t_avg) : "-",
+ req.t_p95 ? Friendly.duration(req.t_p95) : "-",
+ req.t_p99 ? Friendly.duration(req.t_p99) : "-",
+ bytes.received ? Friendly.bytes(bytes.received) : "-",
+ bytes.sent ? Friendly.bytes(bytes.sent) : "-",
+ );
+ }
+ }
+
+ _render_proxy(proxyStats)
+ {
+ const mappings = proxyStats.mappings || [];
+ if (mappings.length === 0)
+ {
+ return;
+ }
+
+ const section = this.add_section("Proxy");
+
+ for (const mapping of mappings)
+ {
+ const sub = section.tag().classify("card").style("marginBottom", "16px");
+ sub.tag().classify("card-title").text(mapping.name || "mapping");
+
+ const grid = sub.tag().classify("grid").classify("info-tiles");
+
+ // Overview tile
+ {
+ const tile = grid.tag().classify("info-tile");
+ tile.tag().style("fontWeight", "600").style("fontSize", "12px")
+ .style("color", "var(--theme_g1)").style("textTransform", "uppercase")
+ .style("letterSpacing", "0.5px").style("marginBottom", "8px")
+ .text("Stats");
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "active connections", Friendly.sep(mapping.activeConnections || 0));
+ this._prop(list, "peak connections", Friendly.sep(mapping.peakActiveConnections || 0));
+ this._prop(list, "total connections", Friendly.sep(mapping.totalConnections || 0));
+ this._prop(list, "from client", Friendly.bytes(mapping.bytesFromClient || 0));
+ this._prop(list, "to client", Friendly.bytes(mapping.bytesToClient || 0));
+ if (mapping.requestRate1)
+ {
+ this._prop(list, "req/sec (1m)", Friendly.sep(mapping.requestRate1, 1) + "/s");
+ }
+ }
+
+ // Active connections table
+ const connections = mapping.connections || [];
+ if (connections.length > 0)
+ {
+ const connHost = sub.tag().style("marginTop", "12px");
+ const connTable = new Table(connHost,
+ ["client", "requests", "from client", "to client", "duration", "websocket"],
+ Table.Flag_FitLeft | Table.Flag_PackRight, -1);
+
+ for (const conn of connections)
+ {
+ connTable.add_row(
+ conn.client || "-",
+ Friendly.sep(conn.requests || 0),
+ Friendly.bytes(conn.bytesFromClient || 0),
+ Friendly.bytes(conn.bytesToClient || 0),
+ conn.durationMs ? Friendly.duration(conn.durationMs / 1000) : "-",
+ conn.websocket ? "yes" : "no",
+ );
+ }
+ }
+ }
+ }
+
+ _prop(parent, label, value)
+ {
+ const row = parent.tag().classify("info-prop");
+ row.tag().classify("info-prop-label").text(label);
+ row.tag().classify("info-prop-value").text(String(value));
+ }
+}
diff --git a/src/zenserver/frontend/html/pages/objectstore.js b/src/zenserver/frontend/html/pages/objectstore.js
new file mode 100644
index 000000000..6b4890614
--- /dev/null
+++ b/src/zenserver/frontend/html/pages/objectstore.js
@@ -0,0 +1,210 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+import { ZenPage } from "./page.js"
+import { Fetcher } from "../util/fetcher.js"
+import { Friendly } from "../util/friendly.js"
+import { Table } from "../util/widgets.js"
+
+////////////////////////////////////////////////////////////////////////////////
+export class Page extends ZenPage
+{
+ generate_crumbs() {}
+
+ async main()
+ {
+ this.set_title("object store");
+
+ const section = this.add_section("Object Store");
+ this._stats_host = section;
+
+ const buckets_section = this.add_section("Buckets");
+ this._buckets_host = buckets_section;
+
+ await this._update();
+ this._poll_timer = setInterval(() => this._update(), 5000);
+ }
+
+ async _update()
+ {
+ try
+ {
+ const [data, stats] = await Promise.all([
+ new Fetcher().resource("/obj/").json(),
+ new Fetcher().resource("stats", "obj").json().catch(() => null),
+ ]);
+ this._render(data, stats);
+ }
+ catch (e) { /* service unavailable */ }
+ }
+
+ _render(data, stats)
+ {
+ const buckets = data.buckets || [];
+
+ // Stats summary
+ {
+ const host = this._stats_host;
+ if (!this._stats_grid)
+ {
+ this._stats_grid = host.tag().classify("grid").classify("stats-tiles");
+ }
+ const grid = this._stats_grid;
+ grid.inner().innerHTML = "";
+
+ const total_objects = buckets.reduce((sum, b) => sum + (b.object_count || 0), 0);
+ const total_size = buckets.reduce((sum, b) => sum + (b.size || 0), 0);
+
+ // HTTP Requests tile
+ this._render_http_requests_tile(grid, stats && stats.requests);
+
+ {
+ const tile = grid.tag().classify("card").classify("stats-tile");
+ tile.tag().classify("card-title").text("Object Store");
+ const body = tile.tag().classify("tile-metrics");
+ this._metric(body, Friendly.sep(buckets.length), "buckets", true);
+ this._metric(body, Friendly.sep(total_objects), "objects");
+ this._metric(body, Friendly.bytes(total_size), "storage");
+ this._metric(body, Friendly.bytes(data.total_bytes_served || 0), "bytes served");
+ }
+ }
+
+ // Buckets table
+ {
+ const host = this._buckets_host;
+ if (this._buckets_table)
+ {
+ this._buckets_table.clear();
+ }
+ else
+ {
+ this._buckets_table = host.add_widget(
+ Table,
+ ["name", "objects", "size"],
+ Table.Flag_FitLeft
+ );
+ }
+
+ if (buckets.length === 0)
+ {
+ return;
+ }
+
+ for (const bucket of buckets)
+ {
+ const row = this._buckets_table.add_row(
+ bucket.name || "-",
+ Friendly.sep(bucket.object_count || 0),
+ Friendly.bytes(bucket.size || 0),
+ );
+
+ const row_elem = row.inner();
+ for (const cell of row_elem.children)
+ {
+ cell.style.cursor = "pointer";
+ cell.addEventListener("click", () => this._toggle_bucket(bucket.name, row));
+ }
+ }
+ }
+ }
+
+ async _toggle_bucket(name, row)
+ {
+ // If already expanded, collapse
+ if (this._expanded_bucket === name)
+ {
+ if (this._expanded_el)
+ {
+ this._expanded_el.remove();
+ this._expanded_el = null;
+ }
+ this._expanded_bucket = null;
+ return;
+ }
+
+ // Collapse any previous
+ if (this._expanded_el)
+ {
+ this._expanded_el.remove();
+ this._expanded_el = null;
+ }
+
+ this._expanded_bucket = name;
+
+ try
+ {
+ const data = await new Fetcher().resource("/obj/bucket/" + encodeURIComponent(name) + "/").json();
+ const result = data.ListBucketResult || {};
+ const contents = result.Contents || [];
+
+ const detail = document.createElement("div");
+ detail.className = "objectstore-bucket-detail";
+
+ if (contents.length === 0)
+ {
+ detail.textContent = "Bucket is empty.";
+ }
+ else
+ {
+ const tbl = document.createElement("table");
+ tbl.className = "objectstore-objects-table";
+
+ const thead = document.createElement("thead");
+ const hdr = document.createElement("tr");
+ for (const col of ["key", "size"])
+ {
+ const th = document.createElement("th");
+ th.textContent = col;
+ hdr.appendChild(th);
+ }
+ thead.appendChild(hdr);
+ tbl.appendChild(thead);
+
+ const tbody = document.createElement("tbody");
+ const limit = Math.min(contents.length, 100);
+ for (let i = 0; i < limit; i++)
+ {
+ const obj = contents[i];
+ const tr = document.createElement("tr");
+
+ const td_key = document.createElement("td");
+ td_key.textContent = obj.Key || "-";
+ tr.appendChild(td_key);
+
+ const td_size = document.createElement("td");
+ td_size.textContent = Friendly.bytes(obj.Size || 0);
+ td_size.style.textAlign = "right";
+ tr.appendChild(td_size);
+
+ tbody.appendChild(tr);
+ }
+ tbl.appendChild(tbody);
+ detail.appendChild(tbl);
+
+ if (contents.length > limit)
+ {
+ const more = document.createElement("div");
+ more.style.opacity = "0.7";
+ more.style.fontSize = "0.85em";
+ more.style.marginTop = "4px";
+ more.textContent = `Showing ${limit} of ${contents.length} objects.`;
+ detail.appendChild(more);
+ }
+ }
+
+ // Insert after the row's last cell
+ const last_cell = row.inner().lastElementChild;
+ if (last_cell)
+ {
+ last_cell.after(detail);
+ }
+ this._expanded_el = detail;
+ }
+ catch (e)
+ {
+ this._expanded_bucket = null;
+ }
+ }
+
+}
diff --git a/src/zenserver/frontend/html/pages/orchestrator.js b/src/zenserver/frontend/html/pages/orchestrator.js
index 24805c722..a280fabdb 100644
--- a/src/zenserver/frontend/html/pages/orchestrator.js
+++ b/src/zenserver/frontend/html/pages/orchestrator.js
@@ -46,39 +46,6 @@ export class Page extends ZenPage
this._connect_ws();
}
- _collapsible_section(name)
- {
- const section = this.add_section(name);
- const container = section._parent.inner();
- const heading = container.firstElementChild;
-
- heading.style.cursor = "pointer";
- heading.style.userSelect = "none";
-
- const indicator = document.createElement("span");
- indicator.textContent = " \u25BC";
- indicator.style.fontSize = "0.7em";
- heading.appendChild(indicator);
-
- let collapsed = false;
- heading.addEventListener("click", (e) => {
- if (e.target !== heading && e.target !== indicator)
- {
- return;
- }
- collapsed = !collapsed;
- indicator.textContent = collapsed ? " \u25B6" : " \u25BC";
- let sibling = heading.nextElementSibling;
- while (sibling)
- {
- sibling.style.display = collapsed ? "none" : "";
- sibling = sibling.nextElementSibling;
- }
- });
-
- return section;
- }
-
async _fetch_all()
{
try
@@ -113,7 +80,6 @@ export class Page extends ZenPage
{
const proto = location.protocol === "https:" ? "wss:" : "ws:";
const ws = new WebSocket(`${proto}//${location.host}/orch/ws`);
-
ws.onopen = () => {
if (this._poll_timer)
{
diff --git a/src/zenserver/frontend/html/pages/page.js b/src/zenserver/frontend/html/pages/page.js
index 89a86a044..ff530ff8e 100644
--- a/src/zenserver/frontend/html/pages/page.js
+++ b/src/zenserver/frontend/html/pages/page.js
@@ -4,6 +4,7 @@
import { WidgetHost } from "../util/widgets.js"
import { Fetcher } from "../util/fetcher.js"
+import { Friendly } from "../util/friendly.js"
////////////////////////////////////////////////////////////////////////////////
export class PageBase extends WidgetHost
@@ -105,8 +106,24 @@ export class ZenPage extends PageBase
var hostname = obj.find("hostname");
if (hostname)
+ {
tagline += " \u2014 " + hostname.as_value();
+ var ipField = obj.find("ipAddresses");
+ if (ipField)
+ {
+ var ips = [];
+ for (const item of ipField.as_array())
+ {
+ ips.push(item.as_value());
+ }
+ if (ips.length > 0)
+ {
+ tagline += " (" + ips.join(", ") + ")";
+ }
+ }
+ }
+
this._banner.attr("tagline", tagline);
}
@@ -124,7 +141,7 @@ export class ZenPage extends PageBase
add_service_nav(parent)
{
- const nav = parent.tag().id("service_nav");
+ const nav = parent.tag("zen-nav");
// Map service base URIs to dashboard links, this table is also used to detemine
// which links to show based on the services that are currently registered.
@@ -132,7 +149,10 @@ export class ZenPage extends PageBase
const service_dashboards = [
{ base_uri: "/sessions/", label: "Sessions", href: "/dashboard/?page=sessions" },
{ base_uri: "/z$/", label: "Cache", href: "/dashboard/?page=cache" },
+ { base_uri: "/builds/", label: "Build Store", href: "/dashboard/?page=builds" },
{ base_uri: "/prj/", label: "Projects", href: "/dashboard/?page=projects" },
+ { base_uri: "/obj/", label: "Object Store", href: "/dashboard/?page=objectstore" },
+ { base_uri: "/ws/", label: "Workspaces", href: "/dashboard/?page=workspaces" },
{ base_uri: "/compute/", label: "Compute", href: "/dashboard/?page=compute" },
{ base_uri: "/orch/", label: "Orchestrator", href: "/dashboard/?page=orchestrator" },
{ base_uri: "/hub/", label: "Hub", href: "/dashboard/?page=hub" },
@@ -141,7 +161,10 @@ export class ZenPage extends PageBase
nav.tag("a").text("Home").attr("href", "/dashboard/");
+ this._storage_link = nav.tag("a").text("Storage").attr("href", "/dashboard/?page=storage");
+ nav.tag("a").text("Network").attr("href", "/dashboard/?page=network");
this._info_link = nav.tag("a").text("Info").attr("href", "/dashboard/?page=info");
+ nav.tag("a").text("Docs").attr("href", "/dashboard/?page=docs").attr("data-align", "right");
new Fetcher().resource("/api/").json().then((data) => {
const services = data.services || [];
@@ -149,18 +172,52 @@ export class ZenPage extends PageBase
const links = service_dashboards.filter(d => uris.has(d.base_uri));
- // Insert service links before the Info link
- const info_elem = this._info_link.inner();
+ // Insert service links before the Storage link
+ const storage_elem = this._storage_link.inner();
for (const link of links)
{
const a = document.createElement("a");
a.textContent = link.label;
a.href = link.href;
- info_elem.parentNode.insertBefore(a, info_elem);
+ storage_elem.parentNode.insertBefore(a, storage_elem);
}
}).catch(() => {});
}
+ /** Connect to the /stats WebSocket and invoke callback with parsed stats on each update.
+ * Handles protocol selection, pause toggle, and error/close cleanup.
+ */
+ connect_stats_ws(callback)
+ {
+ try
+ {
+ const proto = location.protocol === "https:" ? "wss:" : "ws:";
+ const ws = new WebSocket(`${proto}//${location.host}/stats`);
+ try { this._ws_paused = localStorage.getItem("zen-ws-paused") === "true"; } catch (e) { this._ws_paused = false; }
+ document.addEventListener("zen-ws-toggle", (e) => {
+ this._ws_paused = e.detail.paused;
+ });
+
+ ws.onmessage = (ev) => {
+ if (this._ws_paused)
+ {
+ return;
+ }
+ try
+ {
+ callback(JSON.parse(ev.data));
+ }
+ catch (e) { /* ignore parse errors */ }
+ };
+
+ ws.onclose = () => { this._stats_ws = null; };
+ ws.onerror = () => { ws.close(); };
+
+ this._stats_ws = ws;
+ }
+ catch (e) { /* WebSocket not available */ }
+ }
+
set_title(...args)
{
super.set_title(...args);
@@ -211,4 +268,106 @@ export class ZenPage extends PageBase
new_crumb(auto_name);
}
+
+ _metric(parent, value, label, hero = false)
+ {
+ const m = parent.tag().classify("tile-metric");
+ if (hero)
+ {
+ m.classify("tile-metric-hero");
+ }
+ m.tag().classify("metric-value").text(value);
+ m.tag().classify("metric-label").text(label);
+ }
+
+ _render_http_requests_tile(grid, req, bad_requests = undefined)
+ {
+ if (!req)
+ {
+ return;
+ }
+ const tile = grid.tag().classify("card").classify("stats-tile");
+ tile.tag().classify("card-title").text("HTTP Requests");
+ const columns = tile.tag().classify("tile-columns");
+
+ const left = columns.tag().classify("tile-metrics");
+ const reqData = req.requests || req;
+ this._metric(left, Friendly.sep(reqData.count || 0), "total requests", true);
+ if (reqData.rate_mean > 0)
+ {
+ this._metric(left, Friendly.sep(reqData.rate_mean, 1) + "/s", "req/sec (mean)");
+ }
+ if (reqData.rate_1 > 0)
+ {
+ this._metric(left, Friendly.sep(reqData.rate_1, 1) + "/s", "req/sec (1m)");
+ }
+ if (reqData.rate_5 > 0)
+ {
+ this._metric(left, Friendly.sep(reqData.rate_5, 1) + "/s", "req/sec (5m)");
+ }
+ if (reqData.rate_15 > 0)
+ {
+ this._metric(left, Friendly.sep(reqData.rate_15, 1) + "/s", "req/sec (15m)");
+ }
+ if (bad_requests !== undefined)
+ {
+ this._metric(left, Friendly.sep(bad_requests), "bad requests");
+ }
+
+ const right = columns.tag().classify("tile-metrics");
+ this._metric(right, Friendly.duration(reqData.t_avg || 0), "avg latency", true);
+ if (reqData.t_p75)
+ {
+ this._metric(right, Friendly.duration(reqData.t_p75), "p75");
+ }
+ if (reqData.t_p95)
+ {
+ this._metric(right, Friendly.duration(reqData.t_p95), "p95");
+ }
+ if (reqData.t_p99)
+ {
+ this._metric(right, Friendly.duration(reqData.t_p99), "p99");
+ }
+ if (reqData.t_p999)
+ {
+ this._metric(right, Friendly.duration(reqData.t_p999), "p999");
+ }
+ if (reqData.t_max)
+ {
+ this._metric(right, Friendly.duration(reqData.t_max), "max");
+ }
+ }
+
+ _collapsible_section(name)
+ {
+ const section = this.add_section(name);
+ const container = section._parent.inner();
+ const heading = container.firstElementChild;
+
+ heading.style.cursor = "pointer";
+ heading.style.userSelect = "none";
+
+ const indicator = document.createElement("span");
+ indicator.textContent = " \u25BC";
+ indicator.style.fontSize = "0.7em";
+ heading.appendChild(indicator);
+
+ let collapsed = false;
+ heading.addEventListener("click", (e) => {
+ if (e.target !== heading && e.target !== indicator)
+ {
+ return;
+ }
+ collapsed = !collapsed;
+ indicator.textContent = collapsed ? " \u25B6" : " \u25BC";
+ let sibling = heading.nextElementSibling;
+ while (sibling)
+ {
+ sibling.style.display = collapsed ? "none" : "";
+ sibling = sibling.nextElementSibling;
+ }
+ });
+
+ return section;
+ }
}
diff --git a/src/zenserver/frontend/html/pages/projects.js b/src/zenserver/frontend/html/pages/projects.js
index 9c1e519d4..dfe4faeb8 100644
--- a/src/zenserver/frontend/html/pages/projects.js
+++ b/src/zenserver/frontend/html/pages/projects.js
@@ -28,7 +28,13 @@ export class Page extends ZenPage
this._render_stats(stats);
}
- this._connect_stats_ws();
+ this.connect_stats_ws((all_stats) => {
+ const stats = all_stats["prj"];
+ if (stats)
+ {
+ this._render_stats(stats);
+ }
+ });
// Projects list
var section = this._collapsible_section("Projects");
@@ -104,39 +110,6 @@ export class Page extends ZenPage
}
}
- _collapsible_section(name)
- {
- const section = this.add_section(name);
- const container = section._parent.inner();
- const heading = container.firstElementChild;
-
- heading.style.cursor = "pointer";
- heading.style.userSelect = "none";
-
- const indicator = document.createElement("span");
- indicator.textContent = " \u25BC";
- indicator.style.fontSize = "0.7em";
- heading.appendChild(indicator);
-
- let collapsed = false;
- heading.addEventListener("click", (e) => {
- if (e.target !== heading && e.target !== indicator)
- {
- return;
- }
- collapsed = !collapsed;
- indicator.textContent = collapsed ? " \u25B6" : " \u25BC";
- let sibling = heading.nextElementSibling;
- while (sibling)
- {
- sibling.style.display = collapsed ? "none" : "";
- sibling = sibling.nextElementSibling;
- }
- });
-
- return section;
- }
-
_clear_param(name)
{
this._params.delete(name);
@@ -145,43 +118,6 @@ export class Page extends ZenPage
history.replaceState(null, "", url);
}
- _connect_stats_ws()
- {
- try
- {
- const proto = location.protocol === "https:" ? "wss:" : "ws:";
- const ws = new WebSocket(`${proto}//${location.host}/stats`);
-
- try { this._ws_paused = localStorage.getItem("zen-ws-paused") === "true"; } catch (e) { this._ws_paused = false; }
- document.addEventListener("zen-ws-toggle", (e) => {
- this._ws_paused = e.detail.paused;
- });
-
- ws.onmessage = (ev) => {
- if (this._ws_paused)
- {
- return;
- }
- try
- {
- const all_stats = JSON.parse(ev.data);
- const stats = all_stats["prj"];
- if (stats)
- {
- this._render_stats(stats);
- }
- }
- catch (e) { /* ignore parse errors */ }
- };
-
- ws.onclose = () => { this._stats_ws = null; };
- ws.onerror = () => { ws.close(); };
-
- this._stats_ws = ws;
- }
- catch (e) { /* WebSocket not available */ }
- }
-
_render_stats(stats)
{
const safe = (obj, path) => path.split(".").reduce((a, b) => a && a[b], obj);
@@ -190,44 +126,7 @@ export class Page extends ZenPage
grid.inner().innerHTML = "";
// HTTP Requests tile
- {
- const req = safe(stats, "requests");
- if (req)
- {
- const tile = grid.tag().classify("card").classify("stats-tile");
- tile.tag().classify("card-title").text("HTTP Requests");
- const columns = tile.tag().classify("tile-columns");
-
- const left = columns.tag().classify("tile-metrics");
- const reqData = req.requests || req;
- this._metric(left, Friendly.sep(safe(stats, "store.requestcount") || 0), "total requests", true);
- if (reqData.rate_mean > 0)
- {
- this._metric(left, Friendly.sep(reqData.rate_mean, 1) + "/s", "req/sec (mean)");
- }
- if (reqData.rate_1 > 0)
- {
- this._metric(left, Friendly.sep(reqData.rate_1, 1) + "/s", "req/sec (1m)");
- }
- const badRequests = safe(stats, "store.badrequestcount") || 0;
- this._metric(left, Friendly.sep(badRequests), "bad requests");
-
- const right = columns.tag().classify("tile-metrics");
- this._metric(right, Friendly.duration(reqData.t_avg || 0), "avg latency", true);
- if (reqData.t_p75)
- {
- this._metric(right, Friendly.duration(reqData.t_p75), "p75");
- }
- if (reqData.t_p95)
- {
- this._metric(right, Friendly.duration(reqData.t_p95), "p95");
- }
- if (reqData.t_p99)
- {
- this._metric(right, Friendly.duration(reqData.t_p99), "p99");
- }
- }
- }
+ this._render_http_requests_tile(grid, safe(stats, "requests"), safe(stats, "store.badrequestcount") || 0);
// Store Operations tile
{
@@ -299,17 +198,6 @@ export class Page extends ZenPage
}
}
- _metric(parent, value, label, hero = false)
- {
- const m = parent.tag().classify("tile-metric");
- if (hero)
- {
- m.classify("tile-metric-hero");
- }
- m.tag().classify("metric-value").text(value);
- m.tag().classify("metric-label").text(label);
- }
-
async view_project(project_id)
{
// Toggle off if already selected
diff --git a/src/zenserver/frontend/html/pages/proxy.js b/src/zenserver/frontend/html/pages/proxy.js
index 50e1f255a..4a3524fe3 100644
--- a/src/zenserver/frontend/html/pages/proxy.js
+++ b/src/zenserver/frontend/html/pages/proxy.js
@@ -39,7 +39,15 @@ export class Page extends ZenPage
this._init_view_tabs(connections_section);
await this._update();
- this._connect_stats_ws();
+ this.connect_stats_ws((all_stats) => {
+ const data = all_stats["proxy"];
+ if (data)
+ {
+ this._render_summary(data);
+ this._render_mappings(data);
+ this._render_connections(data);
+ }
+ });
}
async _update()
@@ -54,45 +62,6 @@ export class Page extends ZenPage
catch (e) { /* service unavailable */ }
}
- _connect_stats_ws()
- {
- try
- {
- const proto = location.protocol === "https:" ? "wss:" : "ws:";
- const ws = new WebSocket(`${proto}//${location.host}/stats`);
-
- try { this._ws_paused = localStorage.getItem("zen-ws-paused") === "true"; } catch (e) { this._ws_paused = false; }
- document.addEventListener("zen-ws-toggle", (e) => {
- this._ws_paused = e.detail.paused;
- });
-
- ws.onmessage = (ev) => {
- if (this._ws_paused)
- {
- return;
- }
- try
- {
- const all_stats = JSON.parse(ev.data);
- const data = all_stats["proxy"];
- if (data)
- {
- this._render_summary(data);
- this._render_mappings(data);
- this._render_connections(data);
- }
- }
- catch (e) { /* ignore parse errors */ }
- };
-
- ws.onclose = () => { this._stats_ws = null; };
- ws.onerror = () => { ws.close(); };
-
- this._stats_ws = ws;
- }
- catch (e) { /* WebSocket not available */ }
- }
-
_init_record_controls(host)
{
const container = host.tag().classify("card");
diff --git a/src/zenserver/frontend/html/pages/sessions.js b/src/zenserver/frontend/html/pages/sessions.js
index 95533aa96..c74ede14e 100644
--- a/src/zenserver/frontend/html/pages/sessions.js
+++ b/src/zenserver/frontend/html/pages/sessions.js
@@ -4,58 +4,621 @@
import { ZenPage } from "./page.js"
import { Fetcher } from "../util/fetcher.js"
-import { Table } from "../util/widgets.js"
+import { Table, PropTable } from "../util/widgets.js"
+
+function fmt_date(iso)
+{
+ if (!iso) { return "-"; }
+ const d = new Date(iso);
+ const now = new Date();
+ if (d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth() && d.getDate() === now.getDate())
+ {
+ return d.toLocaleTimeString();
+ }
+ return d.toLocaleString();
+}
+
+function fmt_time(iso)
+{
+ if (!iso) { return ""; }
+ return new Date(iso).toLocaleTimeString();
+}
////////////////////////////////////////////////////////////////////////////////
export class Page extends ZenPage
{
+ generate_crumbs() {}
+
async main()
{
this.set_title("sessions");
- const data = await new Fetcher().resource("/sessions/").json();
- const sessions = data.sessions || [];
+ this._status = this.get_param("status", "active");
const section = this.add_section("Sessions");
+ section._parent.inner().classList.add("sessions-section");
+
+ this._init_status_tabs(section, this._status);
+
+ const query = (this._status === "ended" || this._status === "all") ? "?status=" + this._status : "";
+ const data = await new Fetcher().resource("/sessions/" + query).json();
+ const sessions = data.sessions || [];
+ this._self_id = data.self_id || null;
+
+ // Layout: table on the left, detail panel on the right
+ this._container = section.tag().classify("sessions-layout");
+ this._table_host = this._container.tag().classify("sessions-table");
+ this._detail_panel = this._container.tag().classify("sessions-detail");
+ this._detail_panel.tag().classify("sessions-detail-placeholder").text("Select a session to view details.");
+ this._selected_id = this._self_id;
+ this._selected_row = null;
+ this._page_size = 25;
+ this._page = 0;
+
+ // Log panel below the table/detail layout
+ this._log_panel = section.tag().classify("sessions-log-panel");
+ this._log_panel.inner().style.display = "none";
+ this._log_poll_timer = null;
+
+ this._render_sessions(sessions);
+ this._connect_ws();
+ }
+
+ _render_sessions(sessions)
+ {
+ const status = this._status;
+
+ // Clear existing table content
+ this._table_host.inner().replaceChildren();
if (sessions.length === 0)
{
- section.tag().classify("empty-state").text("No active sessions.");
+ const labels = { active: "No active sessions.", ended: "No ended sessions.", all: "No sessions." };
+ this._table_host.tag().classify("empty-state").text(labels[status] || labels.all);
+ this._selected_row = null;
+ return;
+ }
+
+ let columns;
+ if (status === "all")
+ {
+ columns = ["id", "appname", "mode", "created", "last activity"];
+ }
+ else if (status === "ended")
+ {
+ columns = ["id", "appname", "mode", "created", "ended"];
+ }
+ else
+ {
+ columns = ["id", "appname", "mode", "created", "updated"];
+ }
+ this._last_sessions = sessions;
+ const total = sessions.length;
+ const page_count = this._page_size > 0 ? Math.ceil(total / this._page_size) : 1;
+ if (this._page >= page_count) { this._page = Math.max(0, page_count - 1); }
+ const start = this._page_size > 0 ? this._page * this._page_size : 0;
+ const visible = this._page_size > 0 ? sessions.slice(start, start + this._page_size) : sessions;
+
+ const table = new Table(this._table_host, columns, Table.Flag_FitLeft);
+
+ let new_selected_row = null;
+ let new_selected_session = null;
+
+ for (const session of visible)
+ {
+ const created = fmt_date(session.created_at);
+ const updated = fmt_date(session.updated_at);
+ const ended = fmt_date(session.ended_at);
+
+ const mode = session.mode || "-";
+
+ let row_values;
+ if (status === "all")
+ {
+ const last_activity = session.ended_at ? ended : updated;
+ row_values = [session.id || "-", session.appname || "-", mode, created, last_activity];
+ }
+ else if (status === "ended")
+ {
+ row_values = [session.id || "-", session.appname || "-", mode, created, ended];
+ }
+ else
+ {
+ row_values = [session.id || "-", session.appname || "-", mode, created, updated];
+ }
+
+ const row = table.add_row(...row_values);
+
+ if (status === "all" && !session.ended_at)
+ {
+ const id_cell = row.get_cell(0);
+ const dot = document.createElement("span");
+ dot.className = "health-dot health-green";
+ dot.style.marginRight = "6px";
+ dot.style.width = "8px";
+ dot.style.height = "8px";
+ dot.title = "active";
+ id_cell.inner().prepend(dot);
+ }
+
+ if (this._self_id && session.id === this._self_id)
+ {
+ const pill = document.createElement("span");
+ pill.className = "sessions-self-pill";
+ pill.textContent = "this";
+ row.get_cell(1).inner().prepend(pill);
+ }
+
+ // Restore selection
+ if (this._selected_id && session.id === this._selected_id)
+ {
+ new_selected_row = row;
+ new_selected_session = session;
+ }
+
+ // Table rows use display:contents so we attach click to each cell
+ const row_elem = row.inner();
+ for (const cell of row_elem.children)
+ {
+ cell.style.cursor = "pointer";
+ cell.addEventListener("click", () => this._select_session(row, session));
+ }
+ }
+
+ this._selected_row = null;
+ if (new_selected_row)
+ {
+ this._select_session(new_selected_row, new_selected_session);
+ }
+
+ if (this._page_size > 0 && total > this._page_size)
+ {
+ const footer = document.createElement("div");
+ footer.className = "sessions-pager";
+
+ const make_btn = (label, enabled, on_click) => {
+ const btn = document.createElement("button");
+ btn.className = "history-tab";
+ btn.textContent = label;
+ btn.disabled = !enabled;
+ if (enabled)
+ {
+ btn.addEventListener("click", on_click);
+ }
+ return btn;
+ };
+
+ footer.appendChild(make_btn("\u25C0", this._page > 0, () => {
+ this._page--;
+ this._render_sessions(sessions);
+ }));
+
+ const label = document.createElement("span");
+ label.className = "sessions-pager-label";
+ label.textContent = `${this._page + 1} / ${page_count}`;
+ footer.appendChild(label);
+
+ footer.appendChild(make_btn("\u25B6", this._page < page_count - 1, () => {
+ this._page++;
+ this._render_sessions(sessions);
+ }));
+
+ this._table_host.inner().appendChild(footer);
+ }
+ }
+
+ _filter_sessions(all_sessions)
+ {
+ if (this._status === "active")
+ {
+ return all_sessions.filter(s => !s.ended_at);
+ }
+ if (this._status === "ended")
+ {
+ return all_sessions.filter(s => s.ended_at);
+ }
+ return all_sessions;
+ }
+
+ _connect_ws()
+ {
+ try
+ {
+ const proto = location.protocol === "https:" ? "wss:" : "ws:";
+ const ws = new WebSocket(`${proto}//${location.host}/sessions/ws`);
+ try { this._ws_paused = localStorage.getItem("zen-ws-paused") === "true"; } catch (e) { this._ws_paused = false; }
+ document.addEventListener("zen-ws-toggle", (e) => {
+ this._ws_paused = e.detail.paused;
+ });
+
+ ws.onmessage = (ev) => {
+ if (this._ws_paused)
+ {
+ return;
+ }
+ try
+ {
+ const data = JSON.parse(ev.data);
+ if (data.self_id) { this._self_id = data.self_id; }
+ const all_sessions = data.sessions || [];
+ const filtered = this._filter_sessions(all_sessions);
+ this._render_sessions(filtered);
+ }
+ catch (e) { /* ignore parse errors */ }
+ };
+
+ ws.onclose = () => { this._ws = null; };
+ ws.onerror = () => { ws.close(); };
+
+ this._ws = ws;
+ }
+ catch (e) { /* WebSocket not available */ }
+ }
+
+ _init_status_tabs(host, active_status)
+ {
+ const tabs_el = document.createElement("div");
+ tabs_el.className = "history-tabs";
+ tabs_el.style.marginBottom = "8px";
+ tabs_el.style.width = "fit-content";
+ host.tag().inner().appendChild(tabs_el);
+
+ const make_tab = (label, mode) => {
+ const btn = document.createElement("button");
+ btn.className = "history-tab";
+ btn.textContent = label;
+ if (mode === active_status)
+ {
+ btn.classList.add("active");
+ }
+ btn.addEventListener("click", () => {
+ if (mode === active_status) { return; }
+ this.set_param("status", mode);
+ this.reload();
+ });
+ tabs_el.appendChild(btn);
+ };
+
+ make_tab("Active", "active");
+ make_tab("Ended", "ended");
+ make_tab("All", "all");
+ }
+
+ _select_session(row, session)
+ {
+ const changed = (this._selected_id !== session.id) || !this._log_session_id;
+
+ // Deselect previous
+ if (this._selected_row)
+ {
+ for (const cell of this._selected_row.inner().children)
+ {
+ cell.classList.remove("sessions-selected");
+ }
+ }
+
+ this._selected_row = row;
+ this._selected_id = session.id;
+ for (const cell of row.inner().children)
+ {
+ cell.classList.add("sessions-selected");
+ }
+
+ // Only rebuild the detail panel and log when the session changes
+ if (!changed)
+ {
+ return;
+ }
+
+ // Rebuild detail panel
+ const panel = this._detail_panel;
+ panel.inner().replaceChildren();
+
+ panel.tag("h3").text("Session Details");
+
+ const props = new PropTable(panel);
+ props.add_property("id", session.id || "-");
+ props.add_property("appname", session.appname || "-");
+ if (session.mode)
+ {
+ props.add_property("mode", session.mode);
+ }
+ if (session.jobid)
+ {
+ props.add_property("jobid", session.jobid);
+ }
+ props.add_property("created", fmt_date(session.created_at));
+ props.add_property("updated", fmt_date(session.updated_at));
+ if (session.ended_at)
+ {
+ props.add_property("ended", fmt_date(session.ended_at));
+ }
+
+ if (session.metadata && Object.keys(session.metadata).length > 0)
+ {
+ panel.tag("h3").text("Metadata");
+ const meta_props = new PropTable(panel);
+ meta_props.add_object(session.metadata);
+ }
+
+ // Show log panel for this session
+ this._show_log(session.id);
+ }
+
+ _show_log(session_id)
+ {
+ // Stop any existing poll
+ if (this._log_poll_timer)
+ {
+ clearInterval(this._log_poll_timer);
+ this._log_poll_timer = null;
+ }
+
+ this._log_session_id = session_id;
+ this._log_cursor = 0; // monotonic cursor for incremental fetching
+ this._log_follow = true;
+ this._log_newest_first = true;
+
+ this._log_panel.inner().style.display = "";
+ this._log_panel.inner().replaceChildren();
+
+ // Header
+ const header = document.createElement("div");
+ header.className = "sessions-log-header";
+
+ const title = document.createElement("span");
+ title.className = "sessions-log-title";
+ title.textContent = "Log";
+ header.appendChild(title);
+
+ const filter_input = document.createElement("input");
+ filter_input.type = "text";
+ filter_input.className = "sessions-log-filter";
+ filter_input.placeholder = "Filter\u2026";
+ filter_input.addEventListener("input", () => {
+ this._log_filter = filter_input.value.toLowerCase();
+ this._apply_log_filter();
+ });
+ header.appendChild(filter_input);
+ this._log_filter = "";
+
+ const spacer = document.createElement("span");
+ spacer.style.flex = "1";
+ header.appendChild(spacer);
+
+ const order_btn = document.createElement("button");
+ order_btn.className = "history-tab active";
+ order_btn.textContent = "Newest first";
+ order_btn.addEventListener("click", () => {
+ this._log_newest_first = !this._log_newest_first;
+ order_btn.classList.toggle("active", this._log_newest_first);
+ this._reorder_log();
+ });
+ header.appendChild(order_btn);
+
+ const follow_btn = document.createElement("button");
+ follow_btn.className = "history-tab active";
+ follow_btn.textContent = "Follow";
+ follow_btn.addEventListener("click", () => {
+ this._log_follow = !this._log_follow;
+ follow_btn.classList.toggle("active", this._log_follow);
+ if (this._log_follow && this._log_body)
+ {
+ this._scroll_to_follow();
+ }
+ });
+ header.appendChild(follow_btn);
+ this._log_follow_btn = follow_btn;
+
+ this._log_panel.inner().appendChild(header);
+
+ // Log body
+ const body = document.createElement("div");
+ body.className = "sessions-log-body";
+ body.addEventListener("scroll", () => {
+ const at_follow_edge = this._log_newest_first
+ ? (body.scrollTop <= 4)
+ : (body.scrollTop + body.clientHeight >= body.scrollHeight - 4);
+ if (this._log_follow !== at_follow_edge)
+ {
+ this._log_follow = at_follow_edge;
+ this._log_follow_btn.classList.toggle("active", this._log_follow);
+ }
+ });
+ this._log_panel.inner().appendChild(body);
+ this._log_body = body;
+
+ // Initial fetch + start polling
+ this._fetch_log();
+ this._log_poll_timer = setInterval(() => this._fetch_log(), 2000);
+ }
+
+ async _fetch_log()
+ {
+ if (!this._log_session_id)
+ {
return;
}
- const columns = [
- "id",
- "created",
- "updated",
- "metadata",
- ];
- const table = section.add_widget(Table, columns, Table.Flag_FitLeft);
+ try
+ {
+ const data = await new Fetcher()
+ .resource("/sessions/" + this._log_session_id + "/log")
+ .param("cursor", String(this._log_cursor))
+ .json();
+
+ const entries = data.entries || [];
+ const cursor = data.cursor || 0;
+ const count = data.count || 0;
- for (const session of sessions)
+ if (cursor < this._log_cursor)
+ {
+ // Cursor went backwards — session was reset. Full re-render.
+ this._log_cursor = 0;
+ this._log_body.replaceChildren();
+ this._fetch_log();
+ return;
+ }
+
+ this._log_cursor = cursor;
+
+ if (entries.length > 0)
+ {
+ this._append_log_entries(entries);
+ }
+ else if (count === 0 && !this._log_body.hasChildNodes())
+ {
+ this._show_log_empty();
+ }
+ }
+ catch (e) { /* ignore */ }
+ }
+
+ _show_log_empty()
+ {
+ const body = this._log_body;
+ if (!body)
{
- const created = session.created_at ? new Date(session.created_at).toLocaleString() : "-";
- const updated = session.updated_at ? new Date(session.updated_at).toLocaleString() : "-";
- const meta = this._format_metadata(session.metadata);
+ return;
+ }
+ body.replaceChildren();
+ const empty = document.createElement("div");
+ empty.className = "sessions-log-empty";
+ empty.textContent = "No log entries.";
+ body.appendChild(empty);
+ }
- const row = table.add_row(
- session.id || "-",
- created,
- updated,
- meta,
- );
+ _append_log_entries(entries)
+ {
+ const body = this._log_body;
+ if (!body)
+ {
+ return;
+ }
+
+ // Remove the "No log entries." placeholder if present
+ const empty_el = body.querySelector(".sessions-log-empty");
+ if (empty_el)
+ {
+ empty_el.remove();
+ }
+
+ if (this._log_newest_first)
+ {
+ // Prepend in reverse so newest ends up at the top
+ const first_child = body.firstChild;
+ for (let i = entries.length - 1; i >= 0; i--)
+ {
+ body.insertBefore(this._create_log_line(entries[i]), first_child);
+ }
+ }
+ else
+ {
+ for (const entry of entries)
+ {
+ body.appendChild(this._create_log_line(entry));
+ }
+ }
+
+ if (this._log_follow)
+ {
+ this._scroll_to_follow();
}
}
- _format_metadata(metadata)
+ _scroll_to_follow()
{
- if (!metadata || Object.keys(metadata).length === 0)
+ if (!this._log_body)
{
- return "-";
+ return;
+ }
+ if (this._log_newest_first)
+ {
+ this._log_body.scrollTop = 0;
}
+ else
+ {
+ this._log_body.scrollTop = this._log_body.scrollHeight;
+ }
+ }
- return Object.entries(metadata)
- .map(([k, v]) => `${k}: ${v}`)
- .join(", ");
+ _reorder_log()
+ {
+ const body = this._log_body;
+ if (!body)
+ {
+ return;
+ }
+
+ // Reverse all log line elements in place
+ const lines = Array.from(body.querySelectorAll(".sessions-log-line"));
+ for (const line of lines)
+ {
+ body.prepend(line);
+ }
+
+ this._scroll_to_follow();
+ }
+
+ _create_log_line(entry)
+ {
+ const line = document.createElement("div");
+ line.className = "sessions-log-line";
+
+ const ts = document.createElement("span");
+ ts.className = "sessions-log-ts";
+ ts.textContent = fmt_time(entry.timestamp);
+ line.appendChild(ts);
+
+ if (entry.level)
+ {
+ const lvl = document.createElement("span");
+ lvl.className = "sessions-log-level sessions-log-level-" + entry.level.toLowerCase();
+ lvl.textContent = entry.level;
+ line.appendChild(lvl);
+ }
+
+ if (entry.message)
+ {
+ const msg = document.createElement("span");
+ msg.className = "sessions-log-msg";
+ msg.textContent = entry.message;
+ line.appendChild(msg);
+ }
+
+ if (entry.data && Object.keys(entry.data).length > 0)
+ {
+ const data_span = document.createElement("span");
+ data_span.className = "sessions-log-data";
+ data_span.textContent = JSON.stringify(entry.data);
+ line.appendChild(data_span);
+ }
+
+ if (this._log_filter && !line.textContent.toLowerCase().includes(this._log_filter))
+ {
+ line.style.display = "none";
+ }
+
+ return line;
+ }
+
+ _apply_log_filter()
+ {
+ if (!this._log_body)
+ {
+ return;
+ }
+ const filter = this._log_filter;
+ for (const line of this._log_body.querySelectorAll(".sessions-log-line"))
+ {
+ if (!filter || line.textContent.toLowerCase().includes(filter))
+ {
+ line.style.display = "";
+ }
+ else
+ {
+ line.style.display = "none";
+ }
+ }
}
}
diff --git a/src/zenserver/frontend/html/pages/start.js b/src/zenserver/frontend/html/pages/start.js
index 580045060..e5b4d14f1 100644
--- a/src/zenserver/frontend/html/pages/start.js
+++ b/src/zenserver/frontend/html/pages/start.js
@@ -17,6 +17,38 @@ export class Page extends ZenPage
const api_data = await new Fetcher().resource("/api/").json();
const available = new Set((api_data.services || []).map(s => s.base_uri));
+ // stats tiles
+ const safe_lookup = (obj, path, pretty=undefined) => {
+ const ret = path.split(".").reduce((a,b) => a && a[b], obj);
+ if (ret === undefined) return undefined;
+ return pretty ? pretty(ret) : ret;
+ };
+
+ var section = this.add_section("Activity");
+ section.tag().classify("dropall").text("metrics dashboard →").on_click(() => {
+ window.location = "?page=metrics";
+ });
+
+ var providers_data = await new Fetcher().resource("stats").json();
+ var provider_list = providers_data["providers"] || [];
+ var all_stats = {};
+ await Promise.all(provider_list.map(async (provider) => {
+ all_stats[provider] = await new Fetcher().resource("stats", provider).json();
+ }));
+
+ this._http_panel = section.tag().classify("card").classify("stats-tile").classify("stats-http-panel");
+ this._http_panel.inner().addEventListener("click", () => { window.location = "?page=metrics"; });
+ this._http_panel.tag().classify("http-title").text("HTTP");
+ const req_section = this._http_panel.tag().classify("http-section");
+ req_section.tag().classify("http-section-label").text("Requests");
+ this._http_req_metrics = req_section.tag().classify("tile-metrics");
+ const ws_section = this._http_panel.tag().classify("http-section");
+ ws_section.tag().classify("http-section-label").text("Websockets");
+ this._http_ws_metrics = ws_section.tag().classify("tile-metrics");
+ this._stats_grid = section.tag().classify("grid").classify("stats-tiles");
+ this._safe_lookup = safe_lookup;
+ this._render_stats(all_stats);
+
// project list
var project_table = null;
if (available.has("/prj/"))
@@ -90,7 +122,6 @@ export class Page extends ZenPage
);
var cell = row.get_cell(0);
cell.tag().text(namespace).on_click(() => this.view_zcache(namespace));
- row.get_cell(1).tag().text(namespace);
cell = row.get_cell(-1);
const action_tb = new Toolbar(cell, true);
@@ -102,29 +133,6 @@ export class Page extends ZenPage
}
}
- // stats tiles
- const safe_lookup = (obj, path, pretty=undefined) => {
- const ret = path.split(".").reduce((a,b) => a && a[b], obj);
- if (ret === undefined) return undefined;
- return pretty ? pretty(ret) : ret;
- };
-
- var section = this.add_section("Stats");
- section.tag().classify("dropall").text("metrics dashboard →").on_click(() => {
- window.location = "?page=metrics";
- });
-
- var providers_data = await new Fetcher().resource("stats").json();
- var provider_list = providers_data["providers"] || [];
- var all_stats = {};
- await Promise.all(provider_list.map(async (provider) => {
- all_stats[provider] = await new Fetcher().resource("stats", provider).json();
- }));
-
- this._stats_grid = section.tag().classify("grid").classify("stats-tiles");
- this._safe_lookup = safe_lookup;
- this._render_stats(all_stats);
-
// version
var ver_tag = this.tag().id("version");
var version = new Fetcher().resource("health", "version");
@@ -135,40 +143,7 @@ export class Page extends ZenPage
this._cache_table = cache_table;
// WebSocket for live stats updates
- this._connect_stats_ws();
- }
-
- _connect_stats_ws()
- {
- try
- {
- const proto = location.protocol === "https:" ? "wss:" : "ws:";
- const ws = new WebSocket(`${proto}//${location.host}/stats`);
-
- try { this._ws_paused = localStorage.getItem("zen-ws-paused") === "true"; } catch (e) { this._ws_paused = false; }
- document.addEventListener("zen-ws-toggle", (e) => {
- this._ws_paused = e.detail.paused;
- });
-
- ws.onmessage = (ev) => {
- if (this._ws_paused)
- {
- return;
- }
- try
- {
- const all_stats = JSON.parse(ev.data);
- this._render_stats(all_stats);
- }
- catch (e) { /* ignore parse errors */ }
- };
-
- ws.onclose = () => { this._stats_ws = null; };
- ws.onerror = () => { ws.close(); };
-
- this._stats_ws = ws;
- }
- catch (e) { /* WebSocket not available */ }
+ this.connect_stats_ws((all_stats) => this._render_stats(all_stats));
}
_render_stats(all_stats)
@@ -176,44 +151,43 @@ export class Page extends ZenPage
const grid = this._stats_grid;
const safe_lookup = this._safe_lookup;
- // Clear existing tiles
+ // Clear and repopulate service tiles grid
grid.inner().innerHTML = "";
- // HTTP tile — aggregate request stats across all providers
- {
- const tile = grid.tag().classify("card").classify("stats-tile");
- tile.tag().classify("card-title").text("HTTP");
- const columns = tile.tag().classify("tile-columns");
-
- // Left column: request stats
- const left = columns.tag().classify("tile-metrics");
-
- let total_requests = 0;
- let total_rate = 0;
- for (const p in all_stats)
- {
- total_requests += (safe_lookup(all_stats[p], "requests.count") || 0);
- total_rate += (safe_lookup(all_stats[p], "requests.rate_1") || 0);
- }
+ // HTTP panel — update metrics containers built once in main()
+ const left = this._http_req_metrics;
+ left.inner().innerHTML = "";
- this._add_tile_metric(left, Friendly.sep(total_requests), "total requests", true);
- if (total_rate > 0)
- this._add_tile_metric(left, Friendly.sep(total_rate, 1) + "/s", "req/sec (1m)");
+ let total_requests = 0;
+ let total_rate = 0;
+ for (const p in all_stats)
+ {
+ total_requests += (safe_lookup(all_stats[p], "requests.count") || 0);
+ total_rate += (safe_lookup(all_stats[p], "requests.rate_1") || 0);
+ }
- // Right column: websocket stats
- const ws = all_stats["http"] ? (all_stats["http"]["websockets"] || {}) : {};
- const right = columns.tag().classify("tile-metrics");
+ this._add_tile_metric(left, Friendly.sep(total_requests), "total requests", true);
+ if (total_rate > 0)
+ {
+ this._add_tile_metric(left, Friendly.sep(total_rate, 1) + "/s", "req/sec (1m)");
+ }
- this._add_tile_metric(right, Friendly.sep(ws.active_connections || 0), "ws connections", true);
- const ws_frames = (ws.frames_received || 0) + (ws.frames_sent || 0);
- if (ws_frames > 0)
- this._add_tile_metric(right, Friendly.sep(ws_frames), "ws frames");
- const ws_bytes = (ws.bytes_received || 0) + (ws.bytes_sent || 0);
- if (ws_bytes > 0)
- this._add_tile_metric(right, Friendly.bytes(ws_bytes), "ws traffic");
+ const right = this._http_ws_metrics;
+ right.inner().innerHTML = "";
- tile.on_click(() => { window.location = "?page=metrics"; });
+ const ws = all_stats["http"] ? (all_stats["http"]["websockets"] || {}) : {};
+ this._add_tile_metric(right, Friendly.sep(ws.active_connections || 0), "ws connections", true);
+ const ws_frames = (ws.frames_received || 0) + (ws.frames_sent || 0);
+ if (ws_frames > 0)
+ {
+ this._add_tile_metric(right, Friendly.sep(ws_frames), "ws frames");
}
+ const ws_bytes = (ws.bytes_received || 0) + (ws.bytes_sent || 0);
+ if (ws_bytes > 0)
+ {
+ this._add_tile_metric(right, Friendly.bytes(ws_bytes), "ws traffic");
+ }
+
// Cache tile (z$)
if (all_stats["z$"])
@@ -231,7 +205,7 @@ export class Page extends ZenPage
this._add_tile_metric(body, safe_lookup(s, "cache.size.disk", Friendly.bytes) || "-", "disk");
this._add_tile_metric(body, safe_lookup(s, "cache.size.memory", Friendly.bytes) || "-", "memory");
- tile.on_click(() => { window.location = "?page=stat&provider=z$"; });
+ tile.inner().addEventListener("click", () => { window.location = "?page=stat&provider=z$"; });
}
// Project Store tile (prj)
@@ -243,9 +217,9 @@ export class Page extends ZenPage
const body = tile.tag().classify("tile-metrics");
this._add_tile_metric(body, safe_lookup(s, "requests.count", Friendly.sep) || "-", "requests", true);
- this._add_tile_metric(body, safe_lookup(s, "store.size.disk", Friendly.bytes) || "-", "disk");
+ this._add_tile_metric(body, safe_lookup(s, "project_count", Friendly.sep) || "-", "projects");
- tile.on_click(() => { window.location = "?page=stat&provider=prj"; });
+ tile.inner().addEventListener("click", () => { window.location = "?page=stat&provider=prj"; });
}
// Build Store tile (builds)
@@ -259,7 +233,7 @@ export class Page extends ZenPage
this._add_tile_metric(body, safe_lookup(s, "requests.count", Friendly.sep) || "-", "requests", true);
this._add_tile_metric(body, safe_lookup(s, "store.size.disk", Friendly.bytes) || "-", "disk");
- tile.on_click(() => { window.location = "?page=stat&provider=builds"; });
+ tile.inner().addEventListener("click", () => { window.location = "?page=builds"; });
}
// Proxy tile
@@ -283,7 +257,37 @@ export class Page extends ZenPage
this._add_tile_metric(body, Friendly.sep(mappings.length), "mappings");
this._add_tile_metric(body, Friendly.bytes(totalBytes), "traffic");
- tile.on_click(() => { window.location = "?page=proxy"; });
+ tile.inner().addEventListener("click", () => { window.location = "?page=proxy"; });
+ }
+
+ // Hub tile
+ if (all_stats["hub"])
+ {
+ const s = all_stats["hub"];
+ const tile = grid.tag().classify("card").classify("stats-tile");
+ tile.tag().classify("card-title").text("Hub");
+ const body = tile.tag().classify("tile-metrics");
+
+ const current = safe_lookup(s, "currentInstanceCount") || 0;
+ const limit = safe_lookup(s, "instanceLimit") || safe_lookup(s, "maxInstanceCount") || 0;
+ this._add_tile_metric(body, `${current} / ${limit}`, "instances", true);
+ this._add_tile_metric(body, safe_lookup(s, "requests.count", Friendly.sep) || "-", "requests");
+
+ tile.inner().addEventListener("click", () => { window.location = "?page=stat&provider=hub"; });
+ }
+
+ // Object Store tile (obj)
+ if (all_stats["obj"])
+ {
+ const s = all_stats["obj"];
+ const tile = grid.tag().classify("card").classify("stats-tile");
+ tile.tag().classify("card-title").text("Object Store");
+ const body = tile.tag().classify("tile-metrics");
+
+ this._add_tile_metric(body, safe_lookup(s, "requests.count", Friendly.sep) || "-", "requests", true);
+ this._add_tile_metric(body, safe_lookup(s, "total_bytes_served", Friendly.bytes) || "-", "bytes served");
+
+ tile.inner().addEventListener("click", () => { window.location = "?page=stat&provider=obj"; });
}
// Workspace tile (ws)
@@ -295,9 +299,9 @@ export class Page extends ZenPage
const body = tile.tag().classify("tile-metrics");
this._add_tile_metric(body, safe_lookup(s, "requests.count", Friendly.sep) || "-", "requests", true);
- this._add_tile_metric(body, safe_lookup(s, "workspaces.filescount", Friendly.sep) || "-", "files");
+ this._add_tile_metric(body, safe_lookup(s, "workspaces", Friendly.sep) || "-", "workspaces");
- tile.on_click(() => { window.location = "?page=stat&provider=ws"; });
+ tile.inner().addEventListener("click", () => { window.location = "?page=stat&provider=ws"; });
}
}
diff --git a/src/zenserver/frontend/html/pages/storage.js b/src/zenserver/frontend/html/pages/storage.js
new file mode 100644
index 000000000..55f510ccd
--- /dev/null
+++ b/src/zenserver/frontend/html/pages/storage.js
@@ -0,0 +1,580 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+import { ZenPage } from "./page.js"
+import { Fetcher } from "../util/fetcher.js"
+import { Friendly } from "../util/friendly.js"
+
+////////////////////////////////////////////////////////////////////////////////
+export class Page extends ZenPage
+{
+ generate_crumbs() {}
+
+ async main()
+ {
+ this.set_title("storage");
+
+ const storage = await new Fetcher().resource("/admin/storage").json();
+ const volumes = storage.volumes || [];
+
+ for (let i = 0; i < volumes.length; i++)
+ {
+ const vol = volumes[i];
+ const label = volumes.length === 1 ? "Volume" : `Volume ${i + 1}`;
+ const section = this.add_section(label);
+ const grid = section.tag().classify("grid").classify("info-tiles");
+
+ // Volume overview tile
+ {
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("Disk");
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "total", Friendly.bytes(vol.total));
+ this._prop(list, "used", Friendly.bytes(vol.used));
+ this._prop(list, "free", Friendly.bytes(vol.free));
+
+ if (vol.total > 0)
+ {
+ const pct = ((vol.used / vol.total) * 100).toFixed(1) + "%";
+ this._prop(list, "utilization", pct);
+ }
+ }
+
+ // Per-directory tiles
+ const dirs = vol.directories || [];
+ for (const dir of dirs)
+ {
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text(dir.name);
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "size", Friendly.bytes(dir.bytes));
+ this._prop(list, "files", Friendly.sep(dir.files));
+ this._prop(list, "path", dir.path);
+ }
+ }
+
+ // Cache namespaces breakdown
+ try
+ {
+ const zcache = await new Fetcher().resource("/z$/").json();
+ const namespaces = zcache["Namespaces"] || [];
+
+ if (namespaces.length > 0)
+ {
+ const section = this.add_section("Cache Namespaces");
+ const grid = section.tag().classify("grid").classify("info-tiles");
+
+ await Promise.all(namespaces.map(async (ns) => {
+ try
+ {
+ const data = await new Fetcher().resource(`/z$/${ns}/`).json();
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text(ns);
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "disk", Friendly.bytes(data["StorageSize"].DiskSize));
+ this._prop(list, "memory", Friendly.bytes(data["StorageSize"].MemorySize));
+ this._prop(list, "entries", Friendly.sep(data["EntryCount"]));
+ this._prop(list, "buckets", data["Buckets"].length);
+ }
+ catch (e) { /* skip failed namespace */ }
+ }));
+ }
+ }
+ catch (e) { /* cache service unavailable */ }
+
+ // GC status
+ await this._render_gc_status();
+
+ // GC activity log
+ await this._render_gc_log();
+ }
+
+ async _render_gc_status()
+ {
+ try
+ {
+ const gc = await new Fetcher().resource("/admin/gc").json();
+ if (!gc)
+ {
+ return;
+ }
+
+ const section = this.add_section("Garbage Collection");
+ const grid = section.tag().classify("grid").classify("info-tiles");
+
+ // Status tile
+ {
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("Status");
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "status", gc.Status || "unknown");
+ if (gc.AreDiskWritesBlocked !== undefined)
+ {
+ this._prop(list, "disk writes blocked", gc.AreDiskWritesBlocked ? "yes" : "no");
+ }
+ if (gc.Config)
+ {
+ this._prop(list, "gc enabled", gc.Config.Enabled ? "yes" : "no");
+ }
+ }
+
+ // Full GC tile
+ if (gc.FullGC)
+ {
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("Full GC");
+ const list = tile.tag().classify("info-props");
+
+ if (gc.FullGC.TimeToNext)
+ {
+ this._prop(list, "next run", Friendly.timespan(gc.FullGC.TimeToNext));
+ }
+ if (gc.FullGC.LastTime)
+ {
+ this._prop(list, "last run", Friendly.datetime(gc.FullGC.LastTime));
+ }
+ if (gc.FullGC.Elapsed)
+ {
+ this._prop(list, "last duration", Friendly.timespan(gc.FullGC.Elapsed));
+ }
+ if (gc.FullGC.RemovedDisk)
+ {
+ this._prop(list, "last disk freed", gc.FullGC.RemovedDisk);
+ }
+ if (gc.FullGC.FreedMemory)
+ {
+ this._prop(list, "last memory freed", gc.FullGC.FreedMemory);
+ }
+ if (gc.Config && gc.Config.Interval)
+ {
+ this._prop(list, "interval", Friendly.timespan(gc.Config.Interval));
+ }
+ }
+
+ // Lightweight GC tile
+ if (gc.LightweightGC)
+ {
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("Lightweight GC");
+ const list = tile.tag().classify("info-props");
+
+ if (gc.LightweightGC.TimeToNext)
+ {
+ this._prop(list, "next run", Friendly.timespan(gc.LightweightGC.TimeToNext));
+ }
+ if (gc.LightweightGC.LastTime)
+ {
+ this._prop(list, "last run", Friendly.datetime(gc.LightweightGC.LastTime));
+ }
+ if (gc.LightweightGC.Elapsed)
+ {
+ this._prop(list, "last duration", Friendly.timespan(gc.LightweightGC.Elapsed));
+ }
+ if (gc.LightweightGC.RemovedDisk)
+ {
+ this._prop(list, "last disk freed", gc.LightweightGC.RemovedDisk);
+ }
+ if (gc.LightweightGC.FreedMemory)
+ {
+ this._prop(list, "last memory freed", gc.LightweightGC.FreedMemory);
+ }
+ if (gc.Config && gc.Config.LightweightInterval)
+ {
+ this._prop(list, "interval", Friendly.timespan(gc.Config.LightweightInterval));
+ }
+ }
+
+ // Expiration config tile
+ if (gc.Config)
+ {
+ const cfg = gc.Config;
+ const has_expiration = cfg.MaxCacheDuration || cfg.MaxProjectStoreDuration || cfg.MaxBuildStoreDuration;
+ if (has_expiration)
+ {
+ const tile = grid.tag().classify("card").classify("info-tile");
+ tile.tag().classify("card-title").text("Expiration");
+ const list = tile.tag().classify("info-props");
+
+ if (cfg.MaxCacheDuration)
+ {
+ this._prop(list, "cache", Friendly.timespan(cfg.MaxCacheDuration));
+ }
+ if (cfg.MaxProjectStoreDuration)
+ {
+ this._prop(list, "project store", Friendly.timespan(cfg.MaxProjectStoreDuration));
+ }
+ if (cfg.MaxBuildStoreDuration)
+ {
+ this._prop(list, "build store", Friendly.timespan(cfg.MaxBuildStoreDuration));
+ }
+ }
+ }
+ }
+ catch (e) { /* gc endpoint unavailable */ }
+ }
+
+ async _render_gc_log()
+ {
+ try
+ {
+ const data = await new Fetcher().resource("/admin/gclog").json();
+ const entries = data.entries || [];
+ if (entries.length === 0)
+ {
+ return;
+ }
+
+ // Parse entries (oldest first in file), reverse to show newest first
+ const parsed = [];
+ for (const entry of entries)
+ {
+ const keys = Object.keys(entry);
+ if (keys.length === 0)
+ {
+ continue;
+ }
+ const id = keys[0];
+ const run = entry[id];
+ if (run)
+ {
+ parsed.push({ id, run });
+ }
+ }
+ parsed.reverse();
+
+ this._gc_entries = parsed;
+ this._gc_page = 0;
+ this._gc_page_size = 20;
+ this._gc_sort_col = -1;
+ this._gc_sort_asc = true;
+
+ const section = this.add_section("Garbage Collection History");
+ this._gc_table_host = section.tag();
+ this._gc_pager = section.tag().classify("sessions-pager");
+ this._gc_detail = section.tag().classify("card").style("marginTop", "16px");
+ this._gc_detail.inner().style.display = "none";
+ this._gc_selected_row = null;
+
+ this._gc_render_page();
+ }
+ catch (e) { /* gc log unavailable */ }
+ }
+
+ _gc_render_page()
+ {
+ const parsed = this._gc_entries;
+ const page = this._gc_page;
+ const pageSize = this._gc_page_size;
+ const totalPages = Math.ceil(parsed.length / pageSize);
+ const start = page * pageSize;
+ const end = Math.min(start + pageSize, parsed.length);
+
+ // Clear previous table and detail
+ this._gc_table_host.inner().innerHTML = "";
+ this._gc_detail.inner().style.display = "none";
+ this._gc_selected_row = null;
+
+ const columns = ["id", "started", "elapsed", "disk freed", "memory freed"];
+
+ // Dynamically import Table (cached by the module loader after first import)
+ import("../util/widgets.js").then(({ Table }) => {
+ const table = new Table(this._gc_table_host, columns, Table.Flag_FitLeft | Table.Flag_PackRight, -1);
+
+ for (let i = start; i < end; i++)
+ {
+ const { id, run } = parsed[i];
+ const result = run.Result || {};
+ const compact = result.Compact || {};
+
+ const diskFreed = compact.RemovedDiskBytes;
+ const memFreed = result.Referencer
+ ? (result.Referencer.RemoveExpiredData || {}).FreedMemoryBytes || 0
+ : 0;
+
+ const row = table.add_row(
+ id,
+ run.StartTime ? Friendly.datetime(run.StartTime) : "-",
+ result.Elapsed ? Friendly.timespan(result.Elapsed) : "-",
+ diskFreed !== undefined ? Friendly.bytes(diskFreed) : "-",
+ memFreed ? Friendly.bytes(memFreed) : "-",
+ );
+ row.get_cell(0).style("fontFamily", "'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace");
+ row.get_cell(0).style("fontSize", "12px");
+ for (let c = 0; c < columns.length; c++)
+ {
+ row.get_cell(c).style("textAlign", "right");
+ }
+
+ const rowElem = row.inner();
+ rowElem.style.cursor = "pointer";
+ rowElem.addEventListener("click", () => this._show_gc_detail(row, id, run));
+ }
+
+ // Sortable column headers
+ const headerCells = table.inner().firstElementChild.children;
+ for (let c = 0; c < headerCells.length; c++)
+ {
+ headerCells[c].style.textAlign = "right";
+ headerCells[c].style.cursor = "pointer";
+ headerCells[c].style.userSelect = "none";
+ headerCells[c].addEventListener("click", () => this._gc_sort_by(c));
+ }
+ this._gc_update_sort_indicator(headerCells);
+
+ // Pager
+ this._gc_pager.inner().innerHTML = "";
+ if (totalPages > 1)
+ {
+ const prev = this._gc_pager.tag("button").text("\u2039 Prev");
+ prev.style("opacity", page === 0 ? "0.4" : "1");
+ if (page > 0)
+ {
+ prev.on_click(() => { this._gc_page--; this._gc_render_page(); });
+ }
+
+ this._gc_pager.tag().classify("sessions-pager-label")
+ .text(`${start + 1}\u2013${end} of ${parsed.length}`);
+
+ const next = this._gc_pager.tag("button").text("Next \u203A");
+ next.style("opacity", page >= totalPages - 1 ? "0.4" : "1");
+ if (page < totalPages - 1)
+ {
+ next.on_click(() => { this._gc_page++; this._gc_render_page(); });
+ }
+ }
+ });
+ }
+
+ _gc_sort_by(col)
+ {
+ if (this._gc_sort_col === col)
+ {
+ this._gc_sort_asc = !this._gc_sort_asc;
+ }
+ else
+ {
+ this._gc_sort_col = col;
+ this._gc_sort_asc = true;
+ }
+
+ const key_fns = [
+ (e) => e.id,
+ (e) => e.run.StartTime || "",
+ (e) => e.run.Result?.Elapsed || "",
+ (e) => e.run.Result?.Compact?.RemovedDiskBytes ?? 0,
+ (e) => {
+ const ref = e.run.Result?.Referencer;
+ return ref ? (ref.RemoveExpiredData?.FreedMemoryBytes || 0) : 0;
+ },
+ ];
+ const key_fn = key_fns[col];
+ const dir = this._gc_sort_asc ? 1 : -1;
+
+ this._gc_entries.sort((a, b) => {
+ const ak = key_fn(a);
+ const bk = key_fn(b);
+ if (typeof ak === "number" && typeof bk === "number")
+ {
+ return (ak - bk) * dir;
+ }
+ return String(ak).localeCompare(String(bk)) * dir;
+ });
+
+ this._gc_page = 0;
+ this._gc_render_page();
+ }
+
+ _gc_update_sort_indicator(headerCells)
+ {
+ for (let c = 0; c < headerCells.length; c++)
+ {
+ const text = headerCells[c].textContent.replace(/ [▲▼]$/, "");
+ headerCells[c].textContent = text;
+ if (c === this._gc_sort_col)
+ {
+ headerCells[c].textContent += this._gc_sort_asc ? " ▲" : " ▼";
+ }
+ }
+ }
+
+ _show_gc_detail(row, id, run)
+ {
+ // Toggle selection
+ if (this._gc_selected_row)
+ {
+ this._gc_selected_row.inner().classList.remove("sessions-selected");
+ }
+
+ if (this._gc_selected_row === row)
+ {
+ this._gc_selected_row = null;
+ this._gc_detail.inner().style.display = "none";
+ return;
+ }
+
+ this._gc_selected_row = row;
+ row.inner().classList.add("sessions-selected");
+ this._gc_detail.inner().style.display = "";
+ this._gc_detail.inner().innerHTML = "";
+
+ this._gc_detail.tag().classify("card-title").text(`GC Run: ${id}`);
+
+ const result = run.Result || {};
+ const settings = run.Settings || {};
+
+ // Timing section
+ {
+ const grid = this._gc_detail.tag().classify("grid").classify("info-tiles");
+
+ // Timing tile
+ {
+ const tile = grid.tag().classify("info-tile");
+ tile.tag().style("fontWeight", "600").style("fontSize", "12px").style("color", "var(--theme_g1)")
+ .style("textTransform", "uppercase").style("letterSpacing", "0.5px").style("marginBottom", "8px")
+ .text("Timing");
+ const list = tile.tag().classify("info-props");
+
+ this._prop(list, "started", run.StartTime ? Friendly.datetime(run.StartTime) : "-");
+ this._prop(list, "total elapsed", result.Elapsed ? Friendly.timespan(result.Elapsed) : "-");
+ this._prop(list, "write block", result.WriteBlock ? Friendly.timespan(result.WriteBlock) : "-");
+
+ const timings = [
+ ["remove expired data", result.RemoveExpiredData],
+ ["create reference checkers", result.CreateReferenceCheckers],
+ ["pre-cache state", result.PreCacheState],
+ ["lock state", result.LockState],
+ ["update locked state", result.UpdateLockedState],
+ ["create reference pruners", result.CreateReferencePruners],
+ ["remove unreferenced data", result.RemoveUnreferencedData],
+ ["compact stores", result.CompactStores],
+ ["validate", result.Validate],
+ ["create reference validators", result.CreateReferenceValidators],
+ ];
+ for (const [label, value] of timings)
+ {
+ if (value)
+ {
+ this._prop(list, label, Friendly.timespan(value));
+ }
+ }
+ }
+
+ // Settings tile
+ {
+ const tile = grid.tag().classify("info-tile");
+ tile.tag().style("fontWeight", "600").style("fontSize", "12px").style("color", "var(--theme_g1)")
+ .style("textTransform", "uppercase").style("letterSpacing", "0.5px").style("marginBottom", "8px")
+ .text("Settings");
+ const list = tile.tag().classify("info-props");
+
+ const fields = [
+ ["cache expire", settings.CacheExpireTime],
+ ["project store expire", settings.ProjectStoreExpireTime],
+ ["build store expire", settings.BuildStoreExpireTime],
+ ["collect small objects", settings.CollectSmallObjects],
+ ["delete mode", settings.IsDeleteMode],
+ ["verbose", settings.Verbose],
+ ["single thread", settings.SingleThread],
+ ["compact threshold", settings.CompactBlockUsageThresholdPercent !== undefined
+ ? settings.CompactBlockUsageThresholdPercent + "%" : undefined],
+ ["validation", settings.EnableValidation],
+ ];
+ for (const [label, value] of fields)
+ {
+ if (value !== undefined)
+ {
+ this._prop(list, label, String(value));
+ }
+ }
+ }
+ }
+
+ // Per-referencer breakdown
+ const referencers = result.Referencers || [];
+ if (referencers.length > 0)
+ {
+ import("../util/widgets.js").then(({ Table }) => {
+ const sub = this._gc_detail.tag().style("marginTop", "16px");
+ sub.tag().style("fontWeight", "600").style("fontSize", "12px").style("color", "var(--theme_g1)")
+ .style("textTransform", "uppercase").style("letterSpacing", "0.5px").style("marginBottom", "8px")
+ .text("Per-Referencer Stats");
+
+ const table = new Table(sub,
+ ["name", "checked", "deleted", "memory freed", "disk freed", "elapsed"],
+ Table.Flag_FitLeft | Table.Flag_PackRight | Table.Flag_AlignNumeric, -1);
+
+ for (const ref of referencers)
+ {
+ const expired = ref.RemoveExpired || {};
+ const compact = ref.Compact || {};
+ table.add_row(
+ ref.Name || "unknown",
+ expired.Checked !== undefined ? Friendly.sep(expired.Checked) : "-",
+ expired.Deleted !== undefined ? Friendly.sep(expired.Deleted) : "-",
+ expired.FreedMemoryBytes !== undefined ? Friendly.bytes(expired.FreedMemoryBytes) : "-",
+ compact.RemovedDiskBytes !== undefined ? Friendly.bytes(compact.RemovedDiskBytes) : "-",
+ ref.Elapsed ? Friendly.timespan(ref.Elapsed) : "-",
+ );
+ }
+ });
+ }
+
+ // Per-reference-store breakdown
+ const refStores = result.ReferenceStores || [];
+ if (refStores.length > 0)
+ {
+ import("../util/widgets.js").then(({ Table }) => {
+ const sub = this._gc_detail.tag().style("marginTop", "16px");
+ sub.tag().style("fontWeight", "600").style("fontSize", "12px").style("color", "var(--theme_g1)")
+ .style("textTransform", "uppercase").style("letterSpacing", "0.5px").style("marginBottom", "8px")
+ .text("Per-Reference Store Stats");
+
+ const table = new Table(sub,
+ ["name", "checked", "deleted", "disk freed", "elapsed"],
+ Table.Flag_FitLeft | Table.Flag_PackRight | Table.Flag_AlignNumeric, -1);
+
+ for (const store of refStores)
+ {
+ const unref = store.RemoveUnreferenced || {};
+ const compact = store.Compact || {};
+ table.add_row(
+ store.Name || "unknown",
+ unref.Checked !== undefined ? Friendly.sep(unref.Checked) : "-",
+ unref.Deleted !== undefined ? Friendly.sep(unref.Deleted) : "-",
+ compact.RemovedDiskBytes !== undefined ? Friendly.bytes(compact.RemovedDiskBytes) : "-",
+ store.Elapsed ? Friendly.timespan(store.Elapsed) : "-",
+ );
+ }
+ });
+ }
+
+ // Validation
+ const validator = result.ReferenceValidator || {};
+ if (validator.Checked !== undefined)
+ {
+ const sub = this._gc_detail.tag().style("marginTop", "16px");
+ sub.tag().style("fontWeight", "600").style("fontSize", "12px").style("color", "var(--theme_g1)")
+ .style("textTransform", "uppercase").style("letterSpacing", "0.5px").style("marginBottom", "8px")
+ .text("Validation");
+ const list = sub.tag().classify("info-props");
+
+ this._prop(list, "checked", Friendly.sep(validator.Checked));
+ if (validator.Missing !== undefined)
+ {
+ this._prop(list, "missing", Friendly.sep(validator.Missing));
+ }
+ }
+ }
+
+ _prop(parent, label, value)
+ {
+ const row = parent.tag().classify("info-prop");
+ row.tag().classify("info-prop-label").text(label);
+ row.tag().classify("info-prop-value").text(String(value));
+ }
+}
diff --git a/src/zenserver/frontend/html/pages/workspaces.js b/src/zenserver/frontend/html/pages/workspaces.js
new file mode 100644
index 000000000..2442fb35b
--- /dev/null
+++ b/src/zenserver/frontend/html/pages/workspaces.js
@@ -0,0 +1,236 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+import { ZenPage } from "./page.js"
+import { Fetcher } from "../util/fetcher.js"
+
+////////////////////////////////////////////////////////////////////////////////
+export class Page extends ZenPage
+{
+ async main()
+ {
+ this.set_title("workspaces");
+
+ // Workspace Service Stats
+ const stats_section = this._collapsible_section("Workspace Service Stats");
+ this._stats_grid = stats_section.tag().classify("grid").classify("stats-tiles");
+
+ const stats = await new Fetcher().resource("stats", "ws").json().catch(() => null);
+ if (stats) { this._render_stats(stats); }
+
+ this.connect_stats_ws((all_stats) => {
+ const s = all_stats["ws"];
+ if (s) { this._render_stats(s); }
+ });
+
+ const section = this.add_section("Workspaces");
+ const host = section.tag();
+
+ // Toolbar: refresh button
+ const toolbar = host.tag().classify("module-bulk-bar");
+ this._btn_refresh = toolbar.tag("button").classify("module-bulk-btn").inner();
+ this._btn_refresh.textContent = "\u21BB Refresh";
+ this._btn_refresh.addEventListener("click", () => this._do_refresh());
+
+ // Workspace table (raw DOM — in-place row updates require stable element refs)
+ const table = document.createElement("table");
+ table.className = "module-table";
+ const thead = document.createElement("thead");
+ const hrow = document.createElement("tr");
+ for (const label of ["WORKSPACE ID", "ROOT PATH"])
+ {
+ const th = document.createElement("th");
+ th.textContent = label;
+ hrow.appendChild(th);
+ }
+ thead.appendChild(hrow);
+ table.appendChild(thead);
+ this._tbody = document.createElement("tbody");
+ table.appendChild(this._tbody);
+ host.inner().appendChild(table);
+
+ // State
+ this._expanded = new Set(); // workspace ids with shares panel open
+ this._row_cache = new Map(); // workspace id -> row refs, for in-place DOM updates
+ this._loading = false;
+
+ await this._load();
+ }
+
+ async _load()
+ {
+ if (this._loading) { return; }
+ this._loading = true;
+ this._btn_refresh.disabled = true;
+ try
+ {
+ const data = await new Fetcher().resource("/ws/").json();
+ const workspaces = data.workspaces || [];
+ this._render(workspaces);
+ }
+ catch (e) { /* service unavailable */ }
+ finally
+ {
+ this._loading = false;
+ this._btn_refresh.disabled = false;
+ }
+ }
+
+ async _do_refresh()
+ {
+ if (this._loading) { return; }
+ this._btn_refresh.disabled = true;
+ try
+ {
+ await new Fetcher().resource("/ws/refresh").text();
+ }
+ catch (e) { /* ignore */ }
+ await this._load();
+ }
+
+ _render(workspaces)
+ {
+ const ws_map = new Map(workspaces.map(w => [w.id, w]));
+
+ // Remove rows for workspaces no longer present
+ for (const [id, row] of this._row_cache)
+ {
+ if (!ws_map.has(id))
+ {
+ row.tr.remove();
+ row.detail_tr.remove();
+ this._row_cache.delete(id);
+ this._expanded.delete(id);
+ }
+ }
+
+ // Create or update rows, then reorder tbody to match response order.
+ // appendChild on an existing node moves it, so iterating in response order
+ // achieves correct ordering without touching rows already in the right position.
+ for (const ws of workspaces)
+ {
+ const id = ws.id || "";
+ const shares = ws.shares || [];
+
+ let row = this._row_cache.get(id);
+ if (row)
+ {
+ // Update in-place — preserves DOM node identity so expanded state is kept
+ row.root_path_node.nodeValue = ws.root_path || "";
+ row.detail_tr.style.display = this._expanded.has(id) ? "" : "none";
+ row.btn_expand.textContent = this._expanded.has(id) ? "\u25BE" : "\u25B8";
+ const shares_json = JSON.stringify(shares);
+ if (shares_json !== row.shares_json)
+ {
+ row.shares_json = shares_json;
+ this._render_shares(row.sh_tbody, shares);
+ }
+ }
+ else
+ {
+ // Create new workspace row
+ const tr = document.createElement("tr");
+ const detail_tr = document.createElement("tr");
+ detail_tr.className = "module-metrics-row";
+ detail_tr.style.display = this._expanded.has(id) ? "" : "none";
+
+ const btn_expand = document.createElement("button");
+ btn_expand.className = "module-expand-btn";
+ btn_expand.textContent = this._expanded.has(id) ? "\u25BE" : "\u25B8";
+ btn_expand.addEventListener("click", () => {
+ if (this._expanded.has(id))
+ {
+ this._expanded.delete(id);
+ detail_tr.style.display = "none";
+ btn_expand.textContent = "\u25B8";
+ }
+ else
+ {
+ this._expanded.add(id);
+ detail_tr.style.display = "";
+ btn_expand.textContent = "\u25BE";
+ }
+ });
+
+ const id_wrap = document.createElement("span");
+ id_wrap.className = "ws-id-wrap";
+ id_wrap.appendChild(btn_expand);
+ id_wrap.appendChild(document.createTextNode("\u00A0" + id));
+ const td_id = document.createElement("td");
+ td_id.appendChild(id_wrap);
+ tr.appendChild(td_id);
+
+ const root_path_node = document.createTextNode(ws.root_path || "");
+ const td_root = document.createElement("td");
+ td_root.appendChild(root_path_node);
+ tr.appendChild(td_root);
+
+ // Detail row: nested shares table
+ const sh_table = document.createElement("table");
+ sh_table.className = "module-table ws-share-table";
+ const sh_thead = document.createElement("thead");
+ const sh_hrow = document.createElement("tr");
+ for (const label of ["SHARE ID", "SHARE PATH", "ALIAS"])
+ {
+ const th = document.createElement("th");
+ th.textContent = label;
+ sh_hrow.appendChild(th);
+ }
+ sh_thead.appendChild(sh_hrow);
+ sh_table.appendChild(sh_thead);
+ const sh_tbody = document.createElement("tbody");
+ sh_table.appendChild(sh_tbody);
+ const detail_td = document.createElement("td");
+ detail_td.colSpan = 2;
+ detail_td.className = "ws-detail-cell";
+ detail_td.appendChild(sh_table);
+ detail_tr.appendChild(detail_td);
+
+ this._render_shares(sh_tbody, shares);
+
+ row = { tr, detail_tr, root_path_node, sh_tbody, btn_expand, shares_json: JSON.stringify(shares) };
+ this._row_cache.set(id, row);
+ }
+
+ this._tbody.appendChild(row.tr);
+ this._tbody.appendChild(row.detail_tr);
+ }
+ }
+
+ _render_stats(stats)
+ {
+ const grid = this._stats_grid;
+ grid.inner().innerHTML = "";
+
+ // HTTP Requests tile
+ this._render_http_requests_tile(grid, stats.requests);
+ }
+
+ _render_shares(sh_tbody, shares)
+ {
+ sh_tbody.innerHTML = "";
+ if (shares.length === 0)
+ {
+ const tr = document.createElement("tr");
+ const td = document.createElement("td");
+ td.colSpan = 3;
+ td.className = "ws-no-shares-cell";
+ td.textContent = "No shares";
+ tr.appendChild(td);
+ sh_tbody.appendChild(tr);
+ return;
+ }
+ for (const share of shares)
+ {
+ const tr = document.createElement("tr");
+ for (const text of [share.id || "", share.share_path || "", share.alias || ""])
+ {
+ const td = document.createElement("td");
+ td.textContent = text;
+ tr.appendChild(td);
+ }
+ sh_tbody.appendChild(tr);
+ }
+ }
+}
diff --git a/src/zenserver/frontend/html/thirdparty/marked.esm.js b/src/zenserver/frontend/html/thirdparty/marked.esm.js
new file mode 100644
index 000000000..d07059ea7
--- /dev/null
+++ b/src/zenserver/frontend/html/thirdparty/marked.esm.js
@@ -0,0 +1,2580 @@
+/**
+ * marked v15.0.7 - a markdown parser
+ * Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/markedjs/marked
+ */
+
+/**
+ * DO NOT EDIT THIS FILE
+ * The code in this file is generated from files in ./src/
+ */
+
+/**
+ * Gets the original marked default options.
+ */
+function _getDefaults() {
+ return {
+ async: false,
+ breaks: false,
+ extensions: null,
+ gfm: true,
+ hooks: null,
+ pedantic: false,
+ renderer: null,
+ silent: false,
+ tokenizer: null,
+ walkTokens: null,
+ };
+}
+let _defaults = _getDefaults();
+function changeDefaults(newDefaults) {
+ _defaults = newDefaults;
+}
+
+const noopTest = { exec: () => null };
+function edit(regex, opt = '') {
+ let source = typeof regex === 'string' ? regex : regex.source;
+ const obj = {
+ replace: (name, val) => {
+ let valSource = typeof val === 'string' ? val : val.source;
+ valSource = valSource.replace(other.caret, '$1');
+ source = source.replace(name, valSource);
+ return obj;
+ },
+ getRegex: () => {
+ return new RegExp(source, opt);
+ },
+ };
+ return obj;
+}
+const other = {
+ codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm,
+ outputLinkReplace: /\\([\[\]])/g,
+ indentCodeCompensation: /^(\s+)(?:```)/,
+ beginningSpace: /^\s+/,
+ endingHash: /#$/,
+ startingSpaceChar: /^ /,
+ endingSpaceChar: / $/,
+ nonSpaceChar: /[^ ]/,
+ newLineCharGlobal: /\n/g,
+ tabCharGlobal: /\t/g,
+ multipleSpaceGlobal: /\s+/g,
+ blankLine: /^[ \t]*$/,
+ doubleBlankLine: /\n[ \t]*\n[ \t]*$/,
+ blockquoteStart: /^ {0,3}>/,
+ blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g,
+ blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm,
+ listReplaceTabs: /^\t+/,
+ listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,
+ listIsTask: /^\[[ xX]\] /,
+ listReplaceTask: /^\[[ xX]\] +/,
+ anyLine: /\n.*\n/,
+ hrefBrackets: /^<(.*)>$/,
+ tableDelimiter: /[:|]/,
+ tableAlignChars: /^\||\| *$/g,
+ tableRowBlankLine: /\n[ \t]*$/,
+ tableAlignRight: /^ *-+: *$/,
+ tableAlignCenter: /^ *:-+: *$/,
+ tableAlignLeft: /^ *:-+ *$/,
+ startATag: /^<a /i,
+ endATag: /^<\/a>/i,
+ startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i,
+ endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i,
+ startAngleBracket: /^</,
+ endAngleBracket: />$/,
+ pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/,
+ unicodeAlphaNumeric: /[\p{L}\p{N}]/u,
+ escapeTest: /[&<>"']/,
+ escapeReplace: /[&<>"']/g,
+ escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,
+ escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,
+ unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,
+ caret: /(^|[^\[])\^/g,
+ percentDecode: /%25/g,
+ findPipe: /\|/g,
+ splitPipe: / \|/,
+ slashPipe: /\\\|/g,
+ carriageReturn: /\r\n|\r/g,
+ spaceLine: /^ +$/gm,
+ notSpaceStart: /^\S*/,
+ endingNewline: /\n$/,
+ listItemRegex: (bull) => new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`),
+ nextBulletRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),
+ hrRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
+ fencesBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
+ headingBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
+ htmlBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i'),
+};
+/**
+ * Block-Level Grammar
+ */
+const newline = /^(?:[ \t]*(?:\n|$))+/;
+const blockCode = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
+const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
+const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
+const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
+const bullet = /(?:[*+-]|\d{1,9}[.)])/;
+const lheadingCore = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
+const lheading = edit(lheadingCore)
+ .replace(/bull/g, bullet) // lists can interrupt
+ .replace(/blockCode/g, /(?: {4}| {0,3}\t)/) // indented code blocks can interrupt
+ .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt
+ .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt
+ .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt
+ .replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt
+ .replace(/\|table/g, '') // table not in commonmark
+ .getRegex();
+const lheadingGfm = edit(lheadingCore)
+ .replace(/bull/g, bullet) // lists can interrupt
+ .replace(/blockCode/g, /(?: {4}| {0,3}\t)/) // indented code blocks can interrupt
+ .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt
+ .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt
+ .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt
+ .replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt
+ .replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/) // table can interrupt
+ .getRegex();
+const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
+const blockText = /^[^\n]+/;
+const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
+const def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/)
+ .replace('label', _blockLabel)
+ .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/)
+ .getRegex();
+const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/)
+ .replace(/bull/g, bullet)
+ .getRegex();
+const _tag = 'address|article|aside|base|basefont|blockquote|body|caption'
+ + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
+ + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
+ + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
+ + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'
+ + '|tr|track|ul';
+const _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
+const html = edit('^ {0,3}(?:' // optional indentation
+ + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
+ + '|comment[^\\n]*(\\n+|$)' // (2)
+ + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
+ + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
+ + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
+ + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (6)
+ + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) open tag
+ + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) closing tag
+ + ')', 'i')
+ .replace('comment', _comment)
+ .replace('tag', _tag)
+ .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
+ .getRegex();
+const paragraph = edit(_paragraph)
+ .replace('hr', hr)
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
+ .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
+ .replace('|table', '')
+ .replace('blockquote', ' {0,3}>')
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+ .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
+ .getRegex();
+const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/)
+ .replace('paragraph', paragraph)
+ .getRegex();
+/**
+ * Normal Block Grammar
+ */
+const blockNormal = {
+ blockquote,
+ code: blockCode,
+ def,
+ fences,
+ heading,
+ hr,
+ html,
+ lheading,
+ list,
+ newline,
+ paragraph,
+ table: noopTest,
+ text: blockText,
+};
+/**
+ * GFM Block Grammar
+ */
+const gfmTable = edit('^ *([^\\n ].*)\\n' // Header
+ + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
+ + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells
+ .replace('hr', hr)
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
+ .replace('blockquote', ' {0,3}>')
+ .replace('code', '(?: {4}| {0,3}\t)[^\\n]')
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+ .replace('tag', _tag) // tables can be interrupted by type (6) html blocks
+ .getRegex();
+const blockGfm = {
+ ...blockNormal,
+ lheading: lheadingGfm,
+ table: gfmTable,
+ paragraph: edit(_paragraph)
+ .replace('hr', hr)
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
+ .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
+ .replace('table', gfmTable) // interrupt paragraphs with table
+ .replace('blockquote', ' {0,3}>')
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+ .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
+ .getRegex(),
+};
+/**
+ * Pedantic grammar (original John Gruber's loose markdown specification)
+ */
+const blockPedantic = {
+ ...blockNormal,
+ html: edit('^ *(?:comment *(?:\\n|\\s*$)'
+ + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
+ + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
+ .replace('comment', _comment)
+ .replace(/tag/g, '(?!(?:'
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
+ + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
+ + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
+ .getRegex(),
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
+ heading: /^(#{1,6})(.*)(?:\n+|$)/,
+ fences: noopTest, // fences not supported
+ lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+ paragraph: edit(_paragraph)
+ .replace('hr', hr)
+ .replace('heading', ' *#{1,6} *[^\n]')
+ .replace('lheading', lheading)
+ .replace('|table', '')
+ .replace('blockquote', ' {0,3}>')
+ .replace('|fences', '')
+ .replace('|list', '')
+ .replace('|html', '')
+ .replace('|tag', '')
+ .getRegex(),
+};
+/**
+ * Inline-Level Grammar
+ */
+const escape$1 = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
+const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
+const br = /^( {2,}|\\)\n(?!\s*$)/;
+const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
+// list of unicode punctuation marks, plus any missing characters from CommonMark spec
+const _punctuation = /[\p{P}\p{S}]/u;
+const _punctuationOrSpace = /[\s\p{P}\p{S}]/u;
+const _notPunctuationOrSpace = /[^\s\p{P}\p{S}]/u;
+const punctuation = edit(/^((?![*_])punctSpace)/, 'u')
+ .replace(/punctSpace/g, _punctuationOrSpace).getRegex();
+// GFM allows ~ inside strong and em for strikethrough
+const _punctuationGfmStrongEm = /(?!~)[\p{P}\p{S}]/u;
+const _punctuationOrSpaceGfmStrongEm = /(?!~)[\s\p{P}\p{S}]/u;
+const _notPunctuationOrSpaceGfmStrongEm = /(?:[^\s\p{P}\p{S}]|~)/u;
+// sequences em should skip over [title](link), `code`, <html>
+const blockSkip = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
+const emStrongLDelimCore = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
+const emStrongLDelim = edit(emStrongLDelimCore, 'u')
+ .replace(/punct/g, _punctuation)
+ .getRegex();
+const emStrongLDelimGfm = edit(emStrongLDelimCore, 'u')
+ .replace(/punct/g, _punctuationGfmStrongEm)
+ .getRegex();
+const emStrongRDelimAstCore = '^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
+ + '|[^*]+(?=[^*])' // Consume to delim
+ + '|(?!\\*)punct(\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
+ + '|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter
+ + '|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter
+ + '|[\\s](\\*+)(?!\\*)(?=punct)' // (4) ***# can only be Left Delimiter
+ + '|(?!\\*)punct(\\*+)(?!\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter
+ + '|notPunctSpace(\\*+)(?=notPunctSpace)'; // (6) a***a can be either Left or Right Delimiter
+const emStrongRDelimAst = edit(emStrongRDelimAstCore, 'gu')
+ .replace(/notPunctSpace/g, _notPunctuationOrSpace)
+ .replace(/punctSpace/g, _punctuationOrSpace)
+ .replace(/punct/g, _punctuation)
+ .getRegex();
+const emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, 'gu')
+ .replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm)
+ .replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm)
+ .replace(/punct/g, _punctuationGfmStrongEm)
+ .getRegex();
+// (6) Not allowed for _
+const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
+ + '|[^_]+(?=[^_])' // Consume to delim
+ + '|(?!_)punct(_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter
+ + '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter
+ + '|(?!_)punctSpace(_+)(?=notPunctSpace)' // (3) #___a, ___a can only be Left Delimiter
+ + '|[\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter
+ + '|(?!_)punct(_+)(?!_)(?=punct)', 'gu') // (5) #___# can be either Left or Right Delimiter
+ .replace(/notPunctSpace/g, _notPunctuationOrSpace)
+ .replace(/punctSpace/g, _punctuationOrSpace)
+ .replace(/punct/g, _punctuation)
+ .getRegex();
+const anyPunctuation = edit(/\\(punct)/, 'gu')
+ .replace(/punct/g, _punctuation)
+ .getRegex();
+const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/)
+ .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)
+ .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)
+ .getRegex();
+const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();
+const tag = edit('^comment'
+ + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
+ + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
+ + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
+ + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
+ + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section
+ .replace('comment', _inlineComment)
+ .replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/)
+ .getRegex();
+const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
+const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/)
+ .replace('label', _inlineLabel)
+ .replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/)
+ .replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/)
+ .getRegex();
+const reflink = edit(/^!?\[(label)\]\[(ref)\]/)
+ .replace('label', _inlineLabel)
+ .replace('ref', _blockLabel)
+ .getRegex();
+const nolink = edit(/^!?\[(ref)\](?:\[\])?/)
+ .replace('ref', _blockLabel)
+ .getRegex();
+const reflinkSearch = edit('reflink|nolink(?!\\()', 'g')
+ .replace('reflink', reflink)
+ .replace('nolink', nolink)
+ .getRegex();
+/**
+ * Normal Inline Grammar
+ */
+const inlineNormal = {
+ _backpedal: noopTest, // only used for GFM url
+ anyPunctuation,
+ autolink,
+ blockSkip,
+ br,
+ code: inlineCode,
+ del: noopTest,
+ emStrongLDelim,
+ emStrongRDelimAst,
+ emStrongRDelimUnd,
+ escape: escape$1,
+ link,
+ nolink,
+ punctuation,
+ reflink,
+ reflinkSearch,
+ tag,
+ text: inlineText,
+ url: noopTest,
+};
+/**
+ * Pedantic Inline Grammar
+ */
+const inlinePedantic = {
+ ...inlineNormal,
+ link: edit(/^!?\[(label)\]\((.*?)\)/)
+ .replace('label', _inlineLabel)
+ .getRegex(),
+ reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
+ .replace('label', _inlineLabel)
+ .getRegex(),
+};
+/**
+ * GFM Inline Grammar
+ */
+const inlineGfm = {
+ ...inlineNormal,
+ emStrongRDelimAst: emStrongRDelimAstGfm,
+ emStrongLDelim: emStrongLDelimGfm,
+ url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i')
+ .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)
+ .getRegex(),
+ _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
+ del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,
+ text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/,
+};
+/**
+ * GFM + Line Breaks Inline Grammar
+ */
+const inlineBreaks = {
+ ...inlineGfm,
+ br: edit(br).replace('{2,}', '*').getRegex(),
+ text: edit(inlineGfm.text)
+ .replace('\\b_', '\\b_| {2,}\\n')
+ .replace(/\{2,\}/g, '*')
+ .getRegex(),
+};
+/**
+ * exports
+ */
+const block = {
+ normal: blockNormal,
+ gfm: blockGfm,
+ pedantic: blockPedantic,
+};
+const inline = {
+ normal: inlineNormal,
+ gfm: inlineGfm,
+ breaks: inlineBreaks,
+ pedantic: inlinePedantic,
+};
+
+/**
+ * Helpers
+ */
+const escapeReplacements = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#39;',
+};
+const getEscapeReplacement = (ch) => escapeReplacements[ch];
+function escape(html, encode) {
+ if (encode) {
+ if (other.escapeTest.test(html)) {
+ return html.replace(other.escapeReplace, getEscapeReplacement);
+ }
+ }
+ else {
+ if (other.escapeTestNoEncode.test(html)) {
+ return html.replace(other.escapeReplaceNoEncode, getEscapeReplacement);
+ }
+ }
+ return html;
+}
+function cleanUrl(href) {
+ try {
+ href = encodeURI(href).replace(other.percentDecode, '%');
+ }
+ catch {
+ return null;
+ }
+ return href;
+}
+function splitCells(tableRow, count) {
+ // ensure that every cell-delimiting pipe has a space
+ // before it to distinguish it from an escaped pipe
+ const row = tableRow.replace(other.findPipe, (match, offset, str) => {
+ let escaped = false;
+ let curr = offset;
+ while (--curr >= 0 && str[curr] === '\\')
+ escaped = !escaped;
+ if (escaped) {
+ // odd number of slashes means | is escaped
+ // so we leave it alone
+ return '|';
+ }
+ else {
+ // add space before unescaped |
+ return ' |';
+ }
+ }), cells = row.split(other.splitPipe);
+ let i = 0;
+ // First/last cell in a row cannot be empty if it has no leading/trailing pipe
+ if (!cells[0].trim()) {
+ cells.shift();
+ }
+ if (cells.length > 0 && !cells.at(-1)?.trim()) {
+ cells.pop();
+ }
+ if (count) {
+ if (cells.length > count) {
+ cells.splice(count);
+ }
+ else {
+ while (cells.length < count)
+ cells.push('');
+ }
+ }
+ for (; i < cells.length; i++) {
+ // leading or trailing whitespace is ignored per the gfm spec
+ cells[i] = cells[i].trim().replace(other.slashPipe, '|');
+ }
+ return cells;
+}
+/**
+ * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
+ * /c*$/ is vulnerable to REDOS.
+ *
+ * @param str
+ * @param c
+ * @param invert Remove suffix of non-c chars instead. Default falsey.
+ */
+function rtrim(str, c, invert) {
+ const l = str.length;
+ if (l === 0) {
+ return '';
+ }
+ // Length of suffix matching the invert condition.
+ let suffLen = 0;
+ // Step left until we fail to match the invert condition.
+ while (suffLen < l) {
+ const currChar = str.charAt(l - suffLen - 1);
+ if (currChar === c && true) {
+ suffLen++;
+ }
+ else {
+ break;
+ }
+ }
+ return str.slice(0, l - suffLen);
+}
+function findClosingBracket(str, b) {
+ if (str.indexOf(b[1]) === -1) {
+ return -1;
+ }
+ let level = 0;
+ for (let i = 0; i < str.length; i++) {
+ if (str[i] === '\\') {
+ i++;
+ }
+ else if (str[i] === b[0]) {
+ level++;
+ }
+ else if (str[i] === b[1]) {
+ level--;
+ if (level < 0) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+function outputLink(cap, link, raw, lexer, rules) {
+ const href = link.href;
+ const title = link.title || null;
+ const text = cap[1].replace(rules.other.outputLinkReplace, '$1');
+ if (cap[0].charAt(0) !== '!') {
+ lexer.state.inLink = true;
+ const token = {
+ type: 'link',
+ raw,
+ href,
+ title,
+ text,
+ tokens: lexer.inlineTokens(text),
+ };
+ lexer.state.inLink = false;
+ return token;
+ }
+ return {
+ type: 'image',
+ raw,
+ href,
+ title,
+ text,
+ };
+}
+function indentCodeCompensation(raw, text, rules) {
+ const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);
+ if (matchIndentToCode === null) {
+ return text;
+ }
+ const indentToCode = matchIndentToCode[1];
+ return text
+ .split('\n')
+ .map(node => {
+ const matchIndentInNode = node.match(rules.other.beginningSpace);
+ if (matchIndentInNode === null) {
+ return node;
+ }
+ const [indentInNode] = matchIndentInNode;
+ if (indentInNode.length >= indentToCode.length) {
+ return node.slice(indentToCode.length);
+ }
+ return node;
+ })
+ .join('\n');
+}
+/**
+ * Tokenizer
+ */
+class _Tokenizer {
+ options;
+ rules; // set by the lexer
+ lexer; // set by the lexer
+ constructor(options) {
+ this.options = options || _defaults;
+ }
+ space(src) {
+ const cap = this.rules.block.newline.exec(src);
+ if (cap && cap[0].length > 0) {
+ return {
+ type: 'space',
+ raw: cap[0],
+ };
+ }
+ }
+ code(src) {
+ const cap = this.rules.block.code.exec(src);
+ if (cap) {
+ const text = cap[0].replace(this.rules.other.codeRemoveIndent, '');
+ return {
+ type: 'code',
+ raw: cap[0],
+ codeBlockStyle: 'indented',
+ text: !this.options.pedantic
+ ? rtrim(text, '\n')
+ : text,
+ };
+ }
+ }
+ fences(src) {
+ const cap = this.rules.block.fences.exec(src);
+ if (cap) {
+ const raw = cap[0];
+ const text = indentCodeCompensation(raw, cap[3] || '', this.rules);
+ return {
+ type: 'code',
+ raw,
+ lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],
+ text,
+ };
+ }
+ }
+ heading(src) {
+ const cap = this.rules.block.heading.exec(src);
+ if (cap) {
+ let text = cap[2].trim();
+ // remove trailing #s
+ if (this.rules.other.endingHash.test(text)) {
+ const trimmed = rtrim(text, '#');
+ if (this.options.pedantic) {
+ text = trimmed.trim();
+ }
+ else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {
+ // CommonMark requires space before trailing #s
+ text = trimmed.trim();
+ }
+ }
+ return {
+ type: 'heading',
+ raw: cap[0],
+ depth: cap[1].length,
+ text,
+ tokens: this.lexer.inline(text),
+ };
+ }
+ }
+ hr(src) {
+ const cap = this.rules.block.hr.exec(src);
+ if (cap) {
+ return {
+ type: 'hr',
+ raw: rtrim(cap[0], '\n'),
+ };
+ }
+ }
+ blockquote(src) {
+ const cap = this.rules.block.blockquote.exec(src);
+ if (cap) {
+ let lines = rtrim(cap[0], '\n').split('\n');
+ let raw = '';
+ let text = '';
+ const tokens = [];
+ while (lines.length > 0) {
+ let inBlockquote = false;
+ const currentLines = [];
+ let i;
+ for (i = 0; i < lines.length; i++) {
+ // get lines up to a continuation
+ if (this.rules.other.blockquoteStart.test(lines[i])) {
+ currentLines.push(lines[i]);
+ inBlockquote = true;
+ }
+ else if (!inBlockquote) {
+ currentLines.push(lines[i]);
+ }
+ else {
+ break;
+ }
+ }
+ lines = lines.slice(i);
+ const currentRaw = currentLines.join('\n');
+ const currentText = currentRaw
+ // precede setext continuation with 4 spaces so it isn't a setext
+ .replace(this.rules.other.blockquoteSetextReplace, '\n $1')
+ .replace(this.rules.other.blockquoteSetextReplace2, '');
+ raw = raw ? `${raw}\n${currentRaw}` : currentRaw;
+ text = text ? `${text}\n${currentText}` : currentText;
+ // parse blockquote lines as top level tokens
+ // merge paragraphs if this is a continuation
+ const top = this.lexer.state.top;
+ this.lexer.state.top = true;
+ this.lexer.blockTokens(currentText, tokens, true);
+ this.lexer.state.top = top;
+ // if there is no continuation then we are done
+ if (lines.length === 0) {
+ break;
+ }
+ const lastToken = tokens.at(-1);
+ if (lastToken?.type === 'code') {
+ // blockquote continuation cannot be preceded by a code block
+ break;
+ }
+ else if (lastToken?.type === 'blockquote') {
+ // include continuation in nested blockquote
+ const oldToken = lastToken;
+ const newText = oldToken.raw + '\n' + lines.join('\n');
+ const newToken = this.blockquote(newText);
+ tokens[tokens.length - 1] = newToken;
+ raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;
+ text = text.substring(0, text.length - oldToken.text.length) + newToken.text;
+ break;
+ }
+ else if (lastToken?.type === 'list') {
+ // include continuation in nested list
+ const oldToken = lastToken;
+ const newText = oldToken.raw + '\n' + lines.join('\n');
+ const newToken = this.list(newText);
+ tokens[tokens.length - 1] = newToken;
+ raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
+ text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
+ lines = newText.substring(tokens.at(-1).raw.length).split('\n');
+ continue;
+ }
+ }
+ return {
+ type: 'blockquote',
+ raw,
+ tokens,
+ text,
+ };
+ }
+ }
+ list(src) {
+ let cap = this.rules.block.list.exec(src);
+ if (cap) {
+ let bull = cap[1].trim();
+ const isordered = bull.length > 1;
+ const list = {
+ type: 'list',
+ raw: '',
+ ordered: isordered,
+ start: isordered ? +bull.slice(0, -1) : '',
+ loose: false,
+ items: [],
+ };
+ bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
+ if (this.options.pedantic) {
+ bull = isordered ? bull : '[*+-]';
+ }
+ // Get next list item
+ const itemRegex = this.rules.other.listItemRegex(bull);
+ let endsWithBlankLine = false;
+ // Check if current bullet point can start a new List Item
+ while (src) {
+ let endEarly = false;
+ let raw = '';
+ let itemContents = '';
+ if (!(cap = itemRegex.exec(src))) {
+ break;
+ }
+ if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
+ break;
+ }
+ raw = cap[0];
+ src = src.substring(raw.length);
+ let line = cap[2].split('\n', 1)[0].replace(this.rules.other.listReplaceTabs, (t) => ' '.repeat(3 * t.length));
+ let nextLine = src.split('\n', 1)[0];
+ let blankLine = !line.trim();
+ let indent = 0;
+ if (this.options.pedantic) {
+ indent = 2;
+ itemContents = line.trimStart();
+ }
+ else if (blankLine) {
+ indent = cap[1].length + 1;
+ }
+ else {
+ indent = cap[2].search(this.rules.other.nonSpaceChar); // Find first non-space char
+ indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
+ itemContents = line.slice(indent);
+ indent += cap[1].length;
+ }
+ if (blankLine && this.rules.other.blankLine.test(nextLine)) { // Items begin with at most one blank line
+ raw += nextLine + '\n';
+ src = src.substring(nextLine.length + 1);
+ endEarly = true;
+ }
+ if (!endEarly) {
+ const nextBulletRegex = this.rules.other.nextBulletRegex(indent);
+ const hrRegex = this.rules.other.hrRegex(indent);
+ const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);
+ const headingBeginRegex = this.rules.other.headingBeginRegex(indent);
+ const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);
+ // Check if following lines should be included in List Item
+ while (src) {
+ const rawLine = src.split('\n', 1)[0];
+ let nextLineWithoutTabs;
+ nextLine = rawLine;
+ // Re-align to follow commonmark nesting rules
+ if (this.options.pedantic) {
+ nextLine = nextLine.replace(this.rules.other.listReplaceNesting, ' ');
+ nextLineWithoutTabs = nextLine;
+ }
+ else {
+ nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, ' ');
+ }
+ // End list item if found code fences
+ if (fencesBeginRegex.test(nextLine)) {
+ break;
+ }
+ // End list item if found start of new heading
+ if (headingBeginRegex.test(nextLine)) {
+ break;
+ }
+ // End list item if found start of html block
+ if (htmlBeginRegex.test(nextLine)) {
+ break;
+ }
+ // End list item if found start of new bullet
+ if (nextBulletRegex.test(nextLine)) {
+ break;
+ }
+ // Horizontal rule found
+ if (hrRegex.test(nextLine)) {
+ break;
+ }
+ if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) { // Dedent if possible
+ itemContents += '\n' + nextLineWithoutTabs.slice(indent);
+ }
+ else {
+ // not enough indentation
+ if (blankLine) {
+ break;
+ }
+ // paragraph continuation unless last line was a different block level element
+ if (line.replace(this.rules.other.tabCharGlobal, ' ').search(this.rules.other.nonSpaceChar) >= 4) { // indented code block
+ break;
+ }
+ if (fencesBeginRegex.test(line)) {
+ break;
+ }
+ if (headingBeginRegex.test(line)) {
+ break;
+ }
+ if (hrRegex.test(line)) {
+ break;
+ }
+ itemContents += '\n' + nextLine;
+ }
+ if (!blankLine && !nextLine.trim()) { // Check if current line is blank
+ blankLine = true;
+ }
+ raw += rawLine + '\n';
+ src = src.substring(rawLine.length + 1);
+ line = nextLineWithoutTabs.slice(indent);
+ }
+ }
+ if (!list.loose) {
+ // If the previous item ended with a blank line, the list is loose
+ if (endsWithBlankLine) {
+ list.loose = true;
+ }
+ else if (this.rules.other.doubleBlankLine.test(raw)) {
+ endsWithBlankLine = true;
+ }
+ }
+ let istask = null;
+ let ischecked;
+ // Check for task list items
+ if (this.options.gfm) {
+ istask = this.rules.other.listIsTask.exec(itemContents);
+ if (istask) {
+ ischecked = istask[0] !== '[ ] ';
+ itemContents = itemContents.replace(this.rules.other.listReplaceTask, '');
+ }
+ }
+ list.items.push({
+ type: 'list_item',
+ raw,
+ task: !!istask,
+ checked: ischecked,
+ loose: false,
+ text: itemContents,
+ tokens: [],
+ });
+ list.raw += raw;
+ }
+ // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
+ const lastItem = list.items.at(-1);
+ if (lastItem) {
+ lastItem.raw = lastItem.raw.trimEnd();
+ lastItem.text = lastItem.text.trimEnd();
+ }
+ else {
+ // not a list since there were no items
+ return;
+ }
+ list.raw = list.raw.trimEnd();
+ // Item child tokens handled here at end because we needed to have the final item to trim it first
+ for (let i = 0; i < list.items.length; i++) {
+ this.lexer.state.top = false;
+ list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
+ if (!list.loose) {
+ // Check if list should be loose
+ const spacers = list.items[i].tokens.filter(t => t.type === 'space');
+ const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => this.rules.other.anyLine.test(t.raw));
+ list.loose = hasMultipleLineBreaks;
+ }
+ }
+ // Set all items to loose if list is loose
+ if (list.loose) {
+ for (let i = 0; i < list.items.length; i++) {
+ list.items[i].loose = true;
+ }
+ }
+ return list;
+ }
+ }
+ html(src) {
+ const cap = this.rules.block.html.exec(src);
+ if (cap) {
+ const token = {
+ type: 'html',
+ block: true,
+ raw: cap[0],
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
+ text: cap[0],
+ };
+ return token;
+ }
+ }
+ def(src) {
+ const cap = this.rules.block.def.exec(src);
+ if (cap) {
+ const tag = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, ' ');
+ const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';
+ const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];
+ return {
+ type: 'def',
+ tag,
+ raw: cap[0],
+ href,
+ title,
+ };
+ }
+ }
+ table(src) {
+ const cap = this.rules.block.table.exec(src);
+ if (!cap) {
+ return;
+ }
+ if (!this.rules.other.tableDelimiter.test(cap[2])) {
+ // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
+ return;
+ }
+ const headers = splitCells(cap[1]);
+ const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');
+ const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
+ const item = {
+ type: 'table',
+ raw: cap[0],
+ header: [],
+ align: [],
+ rows: [],
+ };
+ if (headers.length !== aligns.length) {
+ // header and align columns must be equal, rows can be different.
+ return;
+ }
+ for (const align of aligns) {
+ if (this.rules.other.tableAlignRight.test(align)) {
+ item.align.push('right');
+ }
+ else if (this.rules.other.tableAlignCenter.test(align)) {
+ item.align.push('center');
+ }
+ else if (this.rules.other.tableAlignLeft.test(align)) {
+ item.align.push('left');
+ }
+ else {
+ item.align.push(null);
+ }
+ }
+ for (let i = 0; i < headers.length; i++) {
+ item.header.push({
+ text: headers[i],
+ tokens: this.lexer.inline(headers[i]),
+ header: true,
+ align: item.align[i],
+ });
+ }
+ for (const row of rows) {
+ item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
+ return {
+ text: cell,
+ tokens: this.lexer.inline(cell),
+ header: false,
+ align: item.align[i],
+ };
+ }));
+ }
+ return item;
+ }
+ lheading(src) {
+ const cap = this.rules.block.lheading.exec(src);
+ if (cap) {
+ return {
+ type: 'heading',
+ raw: cap[0],
+ depth: cap[2].charAt(0) === '=' ? 1 : 2,
+ text: cap[1],
+ tokens: this.lexer.inline(cap[1]),
+ };
+ }
+ }
+ paragraph(src) {
+ const cap = this.rules.block.paragraph.exec(src);
+ if (cap) {
+ const text = cap[1].charAt(cap[1].length - 1) === '\n'
+ ? cap[1].slice(0, -1)
+ : cap[1];
+ return {
+ type: 'paragraph',
+ raw: cap[0],
+ text,
+ tokens: this.lexer.inline(text),
+ };
+ }
+ }
+ text(src) {
+ const cap = this.rules.block.text.exec(src);
+ if (cap) {
+ return {
+ type: 'text',
+ raw: cap[0],
+ text: cap[0],
+ tokens: this.lexer.inline(cap[0]),
+ };
+ }
+ }
+ escape(src) {
+ const cap = this.rules.inline.escape.exec(src);
+ if (cap) {
+ return {
+ type: 'escape',
+ raw: cap[0],
+ text: cap[1],
+ };
+ }
+ }
+ tag(src) {
+ const cap = this.rules.inline.tag.exec(src);
+ if (cap) {
+ if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {
+ this.lexer.state.inLink = true;
+ }
+ else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {
+ this.lexer.state.inLink = false;
+ }
+ if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {
+ this.lexer.state.inRawBlock = true;
+ }
+ else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {
+ this.lexer.state.inRawBlock = false;
+ }
+ return {
+ type: 'html',
+ raw: cap[0],
+ inLink: this.lexer.state.inLink,
+ inRawBlock: this.lexer.state.inRawBlock,
+ block: false,
+ text: cap[0],
+ };
+ }
+ }
+ link(src) {
+ const cap = this.rules.inline.link.exec(src);
+ if (cap) {
+ const trimmedUrl = cap[2].trim();
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {
+ // commonmark requires matching angle brackets
+ if (!(this.rules.other.endAngleBracket.test(trimmedUrl))) {
+ return;
+ }
+ // ending angle bracket cannot be escaped
+ const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
+ if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
+ return;
+ }
+ }
+ else {
+ // find closing parenthesis
+ const lastParenIndex = findClosingBracket(cap[2], '()');
+ if (lastParenIndex > -1) {
+ const start = cap[0].indexOf('!') === 0 ? 5 : 4;
+ const linkLen = start + cap[1].length + lastParenIndex;
+ cap[2] = cap[2].substring(0, lastParenIndex);
+ cap[0] = cap[0].substring(0, linkLen).trim();
+ cap[3] = '';
+ }
+ }
+ let href = cap[2];
+ let title = '';
+ if (this.options.pedantic) {
+ // split pedantic href and title
+ const link = this.rules.other.pedanticHrefTitle.exec(href);
+ if (link) {
+ href = link[1];
+ title = link[3];
+ }
+ }
+ else {
+ title = cap[3] ? cap[3].slice(1, -1) : '';
+ }
+ href = href.trim();
+ if (this.rules.other.startAngleBracket.test(href)) {
+ if (this.options.pedantic && !(this.rules.other.endAngleBracket.test(trimmedUrl))) {
+ // pedantic allows starting angle bracket without ending angle bracket
+ href = href.slice(1);
+ }
+ else {
+ href = href.slice(1, -1);
+ }
+ }
+ return outputLink(cap, {
+ href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,
+ title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,
+ }, cap[0], this.lexer, this.rules);
+ }
+ }
+ reflink(src, links) {
+ let cap;
+ if ((cap = this.rules.inline.reflink.exec(src))
+ || (cap = this.rules.inline.nolink.exec(src))) {
+ const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, ' ');
+ const link = links[linkString.toLowerCase()];
+ if (!link) {
+ const text = cap[0].charAt(0);
+ return {
+ type: 'text',
+ raw: text,
+ text,
+ };
+ }
+ return outputLink(cap, link, cap[0], this.lexer, this.rules);
+ }
+ }
+ emStrong(src, maskedSrc, prevChar = '') {
+ let match = this.rules.inline.emStrongLDelim.exec(src);
+ if (!match)
+ return;
+ // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
+ if (match[3] && prevChar.match(this.rules.other.unicodeAlphaNumeric))
+ return;
+ const nextChar = match[1] || match[2] || '';
+ if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
+ // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
+ const lLength = [...match[0]].length - 1;
+ let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
+ const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
+ endReg.lastIndex = 0;
+ // Clip maskedSrc to same section of string as src (move to lexer?)
+ maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
+ while ((match = endReg.exec(maskedSrc)) != null) {
+ rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
+ if (!rDelim)
+ continue; // skip single * in __abc*abc__
+ rLength = [...rDelim].length;
+ if (match[3] || match[4]) { // found another Left Delim
+ delimTotal += rLength;
+ continue;
+ }
+ else if (match[5] || match[6]) { // either Left or Right Delim
+ if (lLength % 3 && !((lLength + rLength) % 3)) {
+ midDelimTotal += rLength;
+ continue; // CommonMark Emphasis Rules 9-10
+ }
+ }
+ delimTotal -= rLength;
+ if (delimTotal > 0)
+ continue; // Haven't found enough closing delimiters
+ // Remove extra characters. *a*** -> *a*
+ rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
+ // char length can be >1 for unicode characters;
+ const lastCharLength = [...match[0]][0].length;
+ const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);
+ // Create `em` if smallest delimiter has odd char count. *a***
+ if (Math.min(lLength, rLength) % 2) {
+ const text = raw.slice(1, -1);
+ return {
+ type: 'em',
+ raw,
+ text,
+ tokens: this.lexer.inlineTokens(text),
+ };
+ }
+ // Create 'strong' if smallest delimiter has even char count. **a***
+ const text = raw.slice(2, -2);
+ return {
+ type: 'strong',
+ raw,
+ text,
+ tokens: this.lexer.inlineTokens(text),
+ };
+ }
+ }
+ }
+ codespan(src) {
+ const cap = this.rules.inline.code.exec(src);
+ if (cap) {
+ let text = cap[2].replace(this.rules.other.newLineCharGlobal, ' ');
+ const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);
+ const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);
+ if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
+ text = text.substring(1, text.length - 1);
+ }
+ return {
+ type: 'codespan',
+ raw: cap[0],
+ text,
+ };
+ }
+ }
+ br(src) {
+ const cap = this.rules.inline.br.exec(src);
+ if (cap) {
+ return {
+ type: 'br',
+ raw: cap[0],
+ };
+ }
+ }
+ del(src) {
+ const cap = this.rules.inline.del.exec(src);
+ if (cap) {
+ return {
+ type: 'del',
+ raw: cap[0],
+ text: cap[2],
+ tokens: this.lexer.inlineTokens(cap[2]),
+ };
+ }
+ }
+ autolink(src) {
+ const cap = this.rules.inline.autolink.exec(src);
+ if (cap) {
+ let text, href;
+ if (cap[2] === '@') {
+ text = cap[1];
+ href = 'mailto:' + text;
+ }
+ else {
+ text = cap[1];
+ href = text;
+ }
+ return {
+ type: 'link',
+ raw: cap[0],
+ text,
+ href,
+ tokens: [
+ {
+ type: 'text',
+ raw: text,
+ text,
+ },
+ ],
+ };
+ }
+ }
+ url(src) {
+ let cap;
+ if (cap = this.rules.inline.url.exec(src)) {
+ let text, href;
+ if (cap[2] === '@') {
+ text = cap[0];
+ href = 'mailto:' + text;
+ }
+ else {
+ // do extended autolink path validation
+ let prevCapZero;
+ do {
+ prevCapZero = cap[0];
+ cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';
+ } while (prevCapZero !== cap[0]);
+ text = cap[0];
+ if (cap[1] === 'www.') {
+ href = 'http://' + cap[0];
+ }
+ else {
+ href = cap[0];
+ }
+ }
+ return {
+ type: 'link',
+ raw: cap[0],
+ text,
+ href,
+ tokens: [
+ {
+ type: 'text',
+ raw: text,
+ text,
+ },
+ ],
+ };
+ }
+ }
+ inlineText(src) {
+ const cap = this.rules.inline.text.exec(src);
+ if (cap) {
+ const escaped = this.lexer.state.inRawBlock;
+ return {
+ type: 'text',
+ raw: cap[0],
+ text: cap[0],
+ escaped,
+ };
+ }
+ }
+}
+
+/**
+ * Block Lexer
+ */
+class _Lexer {
+ tokens;
+ options;
+ state;
+ tokenizer;
+ inlineQueue;
+ constructor(options) {
+ // TokenList cannot be created in one go
+ this.tokens = [];
+ this.tokens.links = Object.create(null);
+ this.options = options || _defaults;
+ this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
+ this.tokenizer = this.options.tokenizer;
+ this.tokenizer.options = this.options;
+ this.tokenizer.lexer = this;
+ this.inlineQueue = [];
+ this.state = {
+ inLink: false,
+ inRawBlock: false,
+ top: true,
+ };
+ const rules = {
+ other,
+ block: block.normal,
+ inline: inline.normal,
+ };
+ if (this.options.pedantic) {
+ rules.block = block.pedantic;
+ rules.inline = inline.pedantic;
+ }
+ else if (this.options.gfm) {
+ rules.block = block.gfm;
+ if (this.options.breaks) {
+ rules.inline = inline.breaks;
+ }
+ else {
+ rules.inline = inline.gfm;
+ }
+ }
+ this.tokenizer.rules = rules;
+ }
+ /**
+ * Expose Rules
+ */
+ static get rules() {
+ return {
+ block,
+ inline,
+ };
+ }
+ /**
+ * Static Lex Method
+ */
+ static lex(src, options) {
+ const lexer = new _Lexer(options);
+ return lexer.lex(src);
+ }
+ /**
+ * Static Lex Inline Method
+ */
+ static lexInline(src, options) {
+ const lexer = new _Lexer(options);
+ return lexer.inlineTokens(src);
+ }
+ /**
+ * Preprocessing
+ */
+ lex(src) {
+ src = src.replace(other.carriageReturn, '\n');
+ this.blockTokens(src, this.tokens);
+ for (let i = 0; i < this.inlineQueue.length; i++) {
+ const next = this.inlineQueue[i];
+ this.inlineTokens(next.src, next.tokens);
+ }
+ this.inlineQueue = [];
+ return this.tokens;
+ }
+ blockTokens(src, tokens = [], lastParagraphClipped = false) {
+ if (this.options.pedantic) {
+ src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');
+ }
+ while (src) {
+ let token;
+ if (this.options.extensions?.block?.some((extTokenizer) => {
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ return true;
+ }
+ return false;
+ })) {
+ continue;
+ }
+ // newline
+ if (token = this.tokenizer.space(src)) {
+ src = src.substring(token.raw.length);
+ const lastToken = tokens.at(-1);
+ if (token.raw.length === 1 && lastToken !== undefined) {
+ // if there's a single \n as a spacer, it's terminating the last line,
+ // so move it there so that we don't get unnecessary paragraph tags
+ lastToken.raw += '\n';
+ }
+ else {
+ tokens.push(token);
+ }
+ continue;
+ }
+ // code
+ if (token = this.tokenizer.code(src)) {
+ src = src.substring(token.raw.length);
+ const lastToken = tokens.at(-1);
+ // An indented code block cannot interrupt a paragraph.
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
+ lastToken.raw += '\n' + token.raw;
+ lastToken.text += '\n' + token.text;
+ this.inlineQueue.at(-1).src = lastToken.text;
+ }
+ else {
+ tokens.push(token);
+ }
+ continue;
+ }
+ // fences
+ if (token = this.tokenizer.fences(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // heading
+ if (token = this.tokenizer.heading(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // hr
+ if (token = this.tokenizer.hr(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // blockquote
+ if (token = this.tokenizer.blockquote(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // list
+ if (token = this.tokenizer.list(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // html
+ if (token = this.tokenizer.html(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // def
+ if (token = this.tokenizer.def(src)) {
+ src = src.substring(token.raw.length);
+ const lastToken = tokens.at(-1);
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
+ lastToken.raw += '\n' + token.raw;
+ lastToken.text += '\n' + token.raw;
+ this.inlineQueue.at(-1).src = lastToken.text;
+ }
+ else if (!this.tokens.links[token.tag]) {
+ this.tokens.links[token.tag] = {
+ href: token.href,
+ title: token.title,
+ };
+ }
+ continue;
+ }
+ // table (gfm)
+ if (token = this.tokenizer.table(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // lheading
+ if (token = this.tokenizer.lheading(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // top-level paragraph
+ // prevent paragraph consuming extensions by clipping 'src' to extension start
+ let cutSrc = src;
+ if (this.options.extensions?.startBlock) {
+ let startIndex = Infinity;
+ const tempSrc = src.slice(1);
+ let tempStart;
+ this.options.extensions.startBlock.forEach((getStartIndex) => {
+ tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+ if (typeof tempStart === 'number' && tempStart >= 0) {
+ startIndex = Math.min(startIndex, tempStart);
+ }
+ });
+ if (startIndex < Infinity && startIndex >= 0) {
+ cutSrc = src.substring(0, startIndex + 1);
+ }
+ }
+ if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
+ const lastToken = tokens.at(-1);
+ if (lastParagraphClipped && lastToken?.type === 'paragraph') {
+ lastToken.raw += '\n' + token.raw;
+ lastToken.text += '\n' + token.text;
+ this.inlineQueue.pop();
+ this.inlineQueue.at(-1).src = lastToken.text;
+ }
+ else {
+ tokens.push(token);
+ }
+ lastParagraphClipped = cutSrc.length !== src.length;
+ src = src.substring(token.raw.length);
+ continue;
+ }
+ // text
+ if (token = this.tokenizer.text(src)) {
+ src = src.substring(token.raw.length);
+ const lastToken = tokens.at(-1);
+ if (lastToken?.type === 'text') {
+ lastToken.raw += '\n' + token.raw;
+ lastToken.text += '\n' + token.text;
+ this.inlineQueue.pop();
+ this.inlineQueue.at(-1).src = lastToken.text;
+ }
+ else {
+ tokens.push(token);
+ }
+ continue;
+ }
+ if (src) {
+ const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+ if (this.options.silent) {
+ console.error(errMsg);
+ break;
+ }
+ else {
+ throw new Error(errMsg);
+ }
+ }
+ }
+ this.state.top = true;
+ return tokens;
+ }
+ inline(src, tokens = []) {
+ this.inlineQueue.push({ src, tokens });
+ return tokens;
+ }
+ /**
+ * Lexing/Compiling
+ */
+ inlineTokens(src, tokens = []) {
+ // String with links masked to avoid interference with em and strong
+ let maskedSrc = src;
+ let match = null;
+ // Mask out reflinks
+ if (this.tokens.links) {
+ const links = Object.keys(this.tokens.links);
+ if (links.length > 0) {
+ while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
+ if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
+ maskedSrc = maskedSrc.slice(0, match.index)
+ + '[' + 'a'.repeat(match[0].length - 2) + ']'
+ + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
+ }
+ }
+ }
+ }
+ // Mask out other blocks
+ while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
+ maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
+ }
+ // Mask out escaped characters
+ while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
+ maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
+ }
+ let keepPrevChar = false;
+ let prevChar = '';
+ while (src) {
+ if (!keepPrevChar) {
+ prevChar = '';
+ }
+ keepPrevChar = false;
+ let token;
+ // extensions
+ if (this.options.extensions?.inline?.some((extTokenizer) => {
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ return true;
+ }
+ return false;
+ })) {
+ continue;
+ }
+ // escape
+ if (token = this.tokenizer.escape(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // tag
+ if (token = this.tokenizer.tag(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // link
+ if (token = this.tokenizer.link(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // reflink, nolink
+ if (token = this.tokenizer.reflink(src, this.tokens.links)) {
+ src = src.substring(token.raw.length);
+ const lastToken = tokens.at(-1);
+ if (token.type === 'text' && lastToken?.type === 'text') {
+ lastToken.raw += token.raw;
+ lastToken.text += token.text;
+ }
+ else {
+ tokens.push(token);
+ }
+ continue;
+ }
+ // em & strong
+ if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // code
+ if (token = this.tokenizer.codespan(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // br
+ if (token = this.tokenizer.br(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // del (gfm)
+ if (token = this.tokenizer.del(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // autolink
+ if (token = this.tokenizer.autolink(src)) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // url (gfm)
+ if (!this.state.inLink && (token = this.tokenizer.url(src))) {
+ src = src.substring(token.raw.length);
+ tokens.push(token);
+ continue;
+ }
+ // text
+ // prevent inlineText consuming extensions by clipping 'src' to extension start
+ let cutSrc = src;
+ if (this.options.extensions?.startInline) {
+ let startIndex = Infinity;
+ const tempSrc = src.slice(1);
+ let tempStart;
+ this.options.extensions.startInline.forEach((getStartIndex) => {
+ tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+ if (typeof tempStart === 'number' && tempStart >= 0) {
+ startIndex = Math.min(startIndex, tempStart);
+ }
+ });
+ if (startIndex < Infinity && startIndex >= 0) {
+ cutSrc = src.substring(0, startIndex + 1);
+ }
+ }
+ if (token = this.tokenizer.inlineText(cutSrc)) {
+ src = src.substring(token.raw.length);
+ if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
+ prevChar = token.raw.slice(-1);
+ }
+ keepPrevChar = true;
+ const lastToken = tokens.at(-1);
+ if (lastToken?.type === 'text') {
+ lastToken.raw += token.raw;
+ lastToken.text += token.text;
+ }
+ else {
+ tokens.push(token);
+ }
+ continue;
+ }
+ if (src) {
+ const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+ if (this.options.silent) {
+ console.error(errMsg);
+ break;
+ }
+ else {
+ throw new Error(errMsg);
+ }
+ }
+ }
+ return tokens;
+ }
+}
+
+/**
+ * Renderer
+ */
+class _Renderer {
+ options;
+ parser; // set by the parser
+ constructor(options) {
+ this.options = options || _defaults;
+ }
+ space(token) {
+ return '';
+ }
+ code({ text, lang, escaped }) {
+ const langString = (lang || '').match(other.notSpaceStart)?.[0];
+ const code = text.replace(other.endingNewline, '') + '\n';
+ if (!langString) {
+ return '<pre><code>'
+ + (escaped ? code : escape(code, true))
+ + '</code></pre>\n';
+ }
+ return '<pre><code class="language-'
+ + escape(langString)
+ + '">'
+ + (escaped ? code : escape(code, true))
+ + '</code></pre>\n';
+ }
+ blockquote({ tokens }) {
+ const body = this.parser.parse(tokens);
+ return `<blockquote>\n${body}</blockquote>\n`;
+ }
+ html({ text }) {
+ return text;
+ }
+ heading({ tokens, depth }) {
+ return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\n`;
+ }
+ hr(token) {
+ return '<hr>\n';
+ }
+ list(token) {
+ const ordered = token.ordered;
+ const start = token.start;
+ let body = '';
+ for (let j = 0; j < token.items.length; j++) {
+ const item = token.items[j];
+ body += this.listitem(item);
+ }
+ const type = ordered ? 'ol' : 'ul';
+ const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : '';
+ return '<' + type + startAttr + '>\n' + body + '</' + type + '>\n';
+ }
+ listitem(item) {
+ let itemBody = '';
+ if (item.task) {
+ const checkbox = this.checkbox({ checked: !!item.checked });
+ if (item.loose) {
+ if (item.tokens[0]?.type === 'paragraph') {
+ item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
+ if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
+ item.tokens[0].tokens[0].text = checkbox + ' ' + escape(item.tokens[0].tokens[0].text);
+ item.tokens[0].tokens[0].escaped = true;
+ }
+ }
+ else {
+ item.tokens.unshift({
+ type: 'text',
+ raw: checkbox + ' ',
+ text: checkbox + ' ',
+ escaped: true,
+ });
+ }
+ }
+ else {
+ itemBody += checkbox + ' ';
+ }
+ }
+ itemBody += this.parser.parse(item.tokens, !!item.loose);
+ return `<li>${itemBody}</li>\n`;
+ }
+ checkbox({ checked }) {
+ return '<input '
+ + (checked ? 'checked="" ' : '')
+ + 'disabled="" type="checkbox">';
+ }
+ paragraph({ tokens }) {
+ return `<p>${this.parser.parseInline(tokens)}</p>\n`;
+ }
+ table(token) {
+ let header = '';
+ // header
+ let cell = '';
+ for (let j = 0; j < token.header.length; j++) {
+ cell += this.tablecell(token.header[j]);
+ }
+ header += this.tablerow({ text: cell });
+ let body = '';
+ for (let j = 0; j < token.rows.length; j++) {
+ const row = token.rows[j];
+ cell = '';
+ for (let k = 0; k < row.length; k++) {
+ cell += this.tablecell(row[k]);
+ }
+ body += this.tablerow({ text: cell });
+ }
+ if (body)
+ body = `<tbody>${body}</tbody>`;
+ return '<table>\n'
+ + '<thead>\n'
+ + header
+ + '</thead>\n'
+ + body
+ + '</table>\n';
+ }
+ tablerow({ text }) {
+ return `<tr>\n${text}</tr>\n`;
+ }
+ tablecell(token) {
+ const content = this.parser.parseInline(token.tokens);
+ const type = token.header ? 'th' : 'td';
+ const tag = token.align
+ ? `<${type} align="${token.align}">`
+ : `<${type}>`;
+ return tag + content + `</${type}>\n`;
+ }
+ /**
+ * span level renderer
+ */
+ strong({ tokens }) {
+ return `<strong>${this.parser.parseInline(tokens)}</strong>`;
+ }
+ em({ tokens }) {
+ return `<em>${this.parser.parseInline(tokens)}</em>`;
+ }
+ codespan({ text }) {
+ return `<code>${escape(text, true)}</code>`;
+ }
+ br(token) {
+ return '<br>';
+ }
+ del({ tokens }) {
+ return `<del>${this.parser.parseInline(tokens)}</del>`;
+ }
+ link({ href, title, tokens }) {
+ const text = this.parser.parseInline(tokens);
+ const cleanHref = cleanUrl(href);
+ if (cleanHref === null) {
+ return text;
+ }
+ href = cleanHref;
+ let out = '<a href="' + href + '"';
+ if (title) {
+ out += ' title="' + (escape(title)) + '"';
+ }
+ out += '>' + text + '</a>';
+ return out;
+ }
+ image({ href, title, text }) {
+ const cleanHref = cleanUrl(href);
+ if (cleanHref === null) {
+ return escape(text);
+ }
+ href = cleanHref;
+ let out = `<img src="${href}" alt="${text}"`;
+ if (title) {
+ out += ` title="${escape(title)}"`;
+ }
+ out += '>';
+ return out;
+ }
+ text(token) {
+ return 'tokens' in token && token.tokens
+ ? this.parser.parseInline(token.tokens)
+ : ('escaped' in token && token.escaped ? token.text : escape(token.text));
+ }
+}
+
+/**
+ * TextRenderer
+ * returns only the textual part of the token
+ */
+class _TextRenderer {
+ // no need for block level renderers
+ strong({ text }) {
+ return text;
+ }
+ em({ text }) {
+ return text;
+ }
+ codespan({ text }) {
+ return text;
+ }
+ del({ text }) {
+ return text;
+ }
+ html({ text }) {
+ return text;
+ }
+ text({ text }) {
+ return text;
+ }
+ link({ text }) {
+ return '' + text;
+ }
+ image({ text }) {
+ return '' + text;
+ }
+ br() {
+ return '';
+ }
+}
+
+/**
+ * Parsing & Compiling
+ */
+class _Parser {
+ options;
+ renderer;
+ textRenderer;
+ constructor(options) {
+ this.options = options || _defaults;
+ this.options.renderer = this.options.renderer || new _Renderer();
+ this.renderer = this.options.renderer;
+ this.renderer.options = this.options;
+ this.renderer.parser = this;
+ this.textRenderer = new _TextRenderer();
+ }
+ /**
+ * Static Parse Method
+ */
+ static parse(tokens, options) {
+ const parser = new _Parser(options);
+ return parser.parse(tokens);
+ }
+ /**
+ * Static Parse Inline Method
+ */
+ static parseInline(tokens, options) {
+ const parser = new _Parser(options);
+ return parser.parseInline(tokens);
+ }
+ /**
+ * Parse Loop
+ */
+ parse(tokens, top = true) {
+ let out = '';
+ for (let i = 0; i < tokens.length; i++) {
+ const anyToken = tokens[i];
+ // Run any renderer extensions
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
+ const genericToken = anyToken;
+ const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
+ if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
+ out += ret || '';
+ continue;
+ }
+ }
+ const token = anyToken;
+ switch (token.type) {
+ case 'space': {
+ out += this.renderer.space(token);
+ continue;
+ }
+ case 'hr': {
+ out += this.renderer.hr(token);
+ continue;
+ }
+ case 'heading': {
+ out += this.renderer.heading(token);
+ continue;
+ }
+ case 'code': {
+ out += this.renderer.code(token);
+ continue;
+ }
+ case 'table': {
+ out += this.renderer.table(token);
+ continue;
+ }
+ case 'blockquote': {
+ out += this.renderer.blockquote(token);
+ continue;
+ }
+ case 'list': {
+ out += this.renderer.list(token);
+ continue;
+ }
+ case 'html': {
+ out += this.renderer.html(token);
+ continue;
+ }
+ case 'paragraph': {
+ out += this.renderer.paragraph(token);
+ continue;
+ }
+ case 'text': {
+ let textToken = token;
+ let body = this.renderer.text(textToken);
+ while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
+ textToken = tokens[++i];
+ body += '\n' + this.renderer.text(textToken);
+ }
+ if (top) {
+ out += this.renderer.paragraph({
+ type: 'paragraph',
+ raw: body,
+ text: body,
+ tokens: [{ type: 'text', raw: body, text: body, escaped: true }],
+ });
+ }
+ else {
+ out += body;
+ }
+ continue;
+ }
+ default: {
+ const errMsg = 'Token with "' + token.type + '" type was not found.';
+ if (this.options.silent) {
+ console.error(errMsg);
+ return '';
+ }
+ else {
+ throw new Error(errMsg);
+ }
+ }
+ }
+ }
+ return out;
+ }
+ /**
+ * Parse Inline Tokens
+ */
+ parseInline(tokens, renderer = this.renderer) {
+ let out = '';
+ for (let i = 0; i < tokens.length; i++) {
+ const anyToken = tokens[i];
+ // Run any renderer extensions
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
+ const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
+ if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
+ out += ret || '';
+ continue;
+ }
+ }
+ const token = anyToken;
+ switch (token.type) {
+ case 'escape': {
+ out += renderer.text(token);
+ break;
+ }
+ case 'html': {
+ out += renderer.html(token);
+ break;
+ }
+ case 'link': {
+ out += renderer.link(token);
+ break;
+ }
+ case 'image': {
+ out += renderer.image(token);
+ break;
+ }
+ case 'strong': {
+ out += renderer.strong(token);
+ break;
+ }
+ case 'em': {
+ out += renderer.em(token);
+ break;
+ }
+ case 'codespan': {
+ out += renderer.codespan(token);
+ break;
+ }
+ case 'br': {
+ out += renderer.br(token);
+ break;
+ }
+ case 'del': {
+ out += renderer.del(token);
+ break;
+ }
+ case 'text': {
+ out += renderer.text(token);
+ break;
+ }
+ default: {
+ const errMsg = 'Token with "' + token.type + '" type was not found.';
+ if (this.options.silent) {
+ console.error(errMsg);
+ return '';
+ }
+ else {
+ throw new Error(errMsg);
+ }
+ }
+ }
+ }
+ return out;
+ }
+}
+
+class _Hooks {
+ options;
+ block;
+ constructor(options) {
+ this.options = options || _defaults;
+ }
+ static passThroughHooks = new Set([
+ 'preprocess',
+ 'postprocess',
+ 'processAllTokens',
+ ]);
+ /**
+ * Process markdown before marked
+ */
+ preprocess(markdown) {
+ return markdown;
+ }
+ /**
+ * Process HTML after marked is finished
+ */
+ postprocess(html) {
+ return html;
+ }
+ /**
+ * Process all tokens before walk tokens
+ */
+ processAllTokens(tokens) {
+ return tokens;
+ }
+ /**
+ * Provide function to tokenize markdown
+ */
+ provideLexer() {
+ return this.block ? _Lexer.lex : _Lexer.lexInline;
+ }
+ /**
+ * Provide function to parse tokens
+ */
+ provideParser() {
+ return this.block ? _Parser.parse : _Parser.parseInline;
+ }
+}
+
+class Marked {
+ defaults = _getDefaults();
+ options = this.setOptions;
+ parse = this.parseMarkdown(true);
+ parseInline = this.parseMarkdown(false);
+ Parser = _Parser;
+ Renderer = _Renderer;
+ TextRenderer = _TextRenderer;
+ Lexer = _Lexer;
+ Tokenizer = _Tokenizer;
+ Hooks = _Hooks;
+ constructor(...args) {
+ this.use(...args);
+ }
+ /**
+ * Run callback for every token
+ */
+ walkTokens(tokens, callback) {
+ let values = [];
+ for (const token of tokens) {
+ values = values.concat(callback.call(this, token));
+ switch (token.type) {
+ case 'table': {
+ const tableToken = token;
+ for (const cell of tableToken.header) {
+ values = values.concat(this.walkTokens(cell.tokens, callback));
+ }
+ for (const row of tableToken.rows) {
+ for (const cell of row) {
+ values = values.concat(this.walkTokens(cell.tokens, callback));
+ }
+ }
+ break;
+ }
+ case 'list': {
+ const listToken = token;
+ values = values.concat(this.walkTokens(listToken.items, callback));
+ break;
+ }
+ default: {
+ const genericToken = token;
+ if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
+ this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
+ const tokens = genericToken[childTokens].flat(Infinity);
+ values = values.concat(this.walkTokens(tokens, callback));
+ });
+ }
+ else if (genericToken.tokens) {
+ values = values.concat(this.walkTokens(genericToken.tokens, callback));
+ }
+ }
+ }
+ }
+ return values;
+ }
+ use(...args) {
+ const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
+ args.forEach((pack) => {
+ // copy options to new object
+ const opts = { ...pack };
+ // set async to true if it was set to true before
+ opts.async = this.defaults.async || opts.async || false;
+ // ==-- Parse "addon" extensions --== //
+ if (pack.extensions) {
+ pack.extensions.forEach((ext) => {
+ if (!ext.name) {
+ throw new Error('extension name required');
+ }
+ if ('renderer' in ext) { // Renderer extensions
+ const prevRenderer = extensions.renderers[ext.name];
+ if (prevRenderer) {
+ // Replace extension with func to run new extension but fall back if false
+ extensions.renderers[ext.name] = function (...args) {
+ let ret = ext.renderer.apply(this, args);
+ if (ret === false) {
+ ret = prevRenderer.apply(this, args);
+ }
+ return ret;
+ };
+ }
+ else {
+ extensions.renderers[ext.name] = ext.renderer;
+ }
+ }
+ if ('tokenizer' in ext) { // Tokenizer Extensions
+ if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
+ throw new Error("extension level must be 'block' or 'inline'");
+ }
+ const extLevel = extensions[ext.level];
+ if (extLevel) {
+ extLevel.unshift(ext.tokenizer);
+ }
+ else {
+ extensions[ext.level] = [ext.tokenizer];
+ }
+ if (ext.start) { // Function to check for start of token
+ if (ext.level === 'block') {
+ if (extensions.startBlock) {
+ extensions.startBlock.push(ext.start);
+ }
+ else {
+ extensions.startBlock = [ext.start];
+ }
+ }
+ else if (ext.level === 'inline') {
+ if (extensions.startInline) {
+ extensions.startInline.push(ext.start);
+ }
+ else {
+ extensions.startInline = [ext.start];
+ }
+ }
+ }
+ }
+ if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
+ extensions.childTokens[ext.name] = ext.childTokens;
+ }
+ });
+ opts.extensions = extensions;
+ }
+ // ==-- Parse "overwrite" extensions --== //
+ if (pack.renderer) {
+ const renderer = this.defaults.renderer || new _Renderer(this.defaults);
+ for (const prop in pack.renderer) {
+ if (!(prop in renderer)) {
+ throw new Error(`renderer '${prop}' does not exist`);
+ }
+ if (['options', 'parser'].includes(prop)) {
+ // ignore options property
+ continue;
+ }
+ const rendererProp = prop;
+ const rendererFunc = pack.renderer[rendererProp];
+ const prevRenderer = renderer[rendererProp];
+ // Replace renderer with func to run extension, but fall back if false
+ renderer[rendererProp] = (...args) => {
+ let ret = rendererFunc.apply(renderer, args);
+ if (ret === false) {
+ ret = prevRenderer.apply(renderer, args);
+ }
+ return ret || '';
+ };
+ }
+ opts.renderer = renderer;
+ }
+ if (pack.tokenizer) {
+ const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
+ for (const prop in pack.tokenizer) {
+ if (!(prop in tokenizer)) {
+ throw new Error(`tokenizer '${prop}' does not exist`);
+ }
+ if (['options', 'rules', 'lexer'].includes(prop)) {
+ // ignore options, rules, and lexer properties
+ continue;
+ }
+ const tokenizerProp = prop;
+ const tokenizerFunc = pack.tokenizer[tokenizerProp];
+ const prevTokenizer = tokenizer[tokenizerProp];
+ // Replace tokenizer with func to run extension, but fall back if false
+ // @ts-expect-error cannot type tokenizer function dynamically
+ tokenizer[tokenizerProp] = (...args) => {
+ let ret = tokenizerFunc.apply(tokenizer, args);
+ if (ret === false) {
+ ret = prevTokenizer.apply(tokenizer, args);
+ }
+ return ret;
+ };
+ }
+ opts.tokenizer = tokenizer;
+ }
+ // ==-- Parse Hooks extensions --== //
+ if (pack.hooks) {
+ const hooks = this.defaults.hooks || new _Hooks();
+ for (const prop in pack.hooks) {
+ if (!(prop in hooks)) {
+ throw new Error(`hook '${prop}' does not exist`);
+ }
+ if (['options', 'block'].includes(prop)) {
+ // ignore options and block properties
+ continue;
+ }
+ const hooksProp = prop;
+ const hooksFunc = pack.hooks[hooksProp];
+ const prevHook = hooks[hooksProp];
+ if (_Hooks.passThroughHooks.has(prop)) {
+ // @ts-expect-error cannot type hook function dynamically
+ hooks[hooksProp] = (arg) => {
+ if (this.defaults.async) {
+ return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
+ return prevHook.call(hooks, ret);
+ });
+ }
+ const ret = hooksFunc.call(hooks, arg);
+ return prevHook.call(hooks, ret);
+ };
+ }
+ else {
+ // @ts-expect-error cannot type hook function dynamically
+ hooks[hooksProp] = (...args) => {
+ let ret = hooksFunc.apply(hooks, args);
+ if (ret === false) {
+ ret = prevHook.apply(hooks, args);
+ }
+ return ret;
+ };
+ }
+ }
+ opts.hooks = hooks;
+ }
+ // ==-- Parse WalkTokens extensions --== //
+ if (pack.walkTokens) {
+ const walkTokens = this.defaults.walkTokens;
+ const packWalktokens = pack.walkTokens;
+ opts.walkTokens = function (token) {
+ let values = [];
+ values.push(packWalktokens.call(this, token));
+ if (walkTokens) {
+ values = values.concat(walkTokens.call(this, token));
+ }
+ return values;
+ };
+ }
+ this.defaults = { ...this.defaults, ...opts };
+ });
+ return this;
+ }
+ setOptions(opt) {
+ this.defaults = { ...this.defaults, ...opt };
+ return this;
+ }
+ lexer(src, options) {
+ return _Lexer.lex(src, options ?? this.defaults);
+ }
+ parser(tokens, options) {
+ return _Parser.parse(tokens, options ?? this.defaults);
+ }
+ parseMarkdown(blockType) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const parse = (src, options) => {
+ const origOpt = { ...options };
+ const opt = { ...this.defaults, ...origOpt };
+ const throwError = this.onError(!!opt.silent, !!opt.async);
+ // throw error if an extension set async to true but parse was called with async: false
+ if (this.defaults.async === true && origOpt.async === false) {
+ return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));
+ }
+ // throw error in case of non string input
+ if (typeof src === 'undefined' || src === null) {
+ return throwError(new Error('marked(): input parameter is undefined or null'));
+ }
+ if (typeof src !== 'string') {
+ return throwError(new Error('marked(): input parameter is of type '
+ + Object.prototype.toString.call(src) + ', string expected'));
+ }
+ if (opt.hooks) {
+ opt.hooks.options = opt;
+ opt.hooks.block = blockType;
+ }
+ const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);
+ const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);
+ if (opt.async) {
+ return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
+ .then(src => lexer(src, opt))
+ .then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens)
+ .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
+ .then(tokens => parser(tokens, opt))
+ .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
+ .catch(throwError);
+ }
+ try {
+ if (opt.hooks) {
+ src = opt.hooks.preprocess(src);
+ }
+ let tokens = lexer(src, opt);
+ if (opt.hooks) {
+ tokens = opt.hooks.processAllTokens(tokens);
+ }
+ if (opt.walkTokens) {
+ this.walkTokens(tokens, opt.walkTokens);
+ }
+ let html = parser(tokens, opt);
+ if (opt.hooks) {
+ html = opt.hooks.postprocess(html);
+ }
+ return html;
+ }
+ catch (e) {
+ return throwError(e);
+ }
+ };
+ return parse;
+ }
+ onError(silent, async) {
+ return (e) => {
+ e.message += '\nPlease report this to https://github.com/markedjs/marked.';
+ if (silent) {
+ const msg = '<p>An error occurred:</p><pre>'
+ + escape(e.message + '', true)
+ + '</pre>';
+ if (async) {
+ return Promise.resolve(msg);
+ }
+ return msg;
+ }
+ if (async) {
+ return Promise.reject(e);
+ }
+ throw e;
+ };
+ }
+}
+
+const markedInstance = new Marked();
+function marked(src, opt) {
+ return markedInstance.parse(src, opt);
+}
+/**
+ * Sets the default options.
+ *
+ * @param options Hash of options
+ */
+marked.options =
+ marked.setOptions = function (options) {
+ markedInstance.setOptions(options);
+ marked.defaults = markedInstance.defaults;
+ changeDefaults(marked.defaults);
+ return marked;
+ };
+/**
+ * Gets the original marked default options.
+ */
+marked.getDefaults = _getDefaults;
+marked.defaults = _defaults;
+/**
+ * Use Extension
+ */
+marked.use = function (...args) {
+ markedInstance.use(...args);
+ marked.defaults = markedInstance.defaults;
+ changeDefaults(marked.defaults);
+ return marked;
+};
+/**
+ * Run callback for every token
+ */
+marked.walkTokens = function (tokens, callback) {
+ return markedInstance.walkTokens(tokens, callback);
+};
+/**
+ * Compiles markdown to HTML without enclosing `p` tag.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options
+ * @return String of compiled HTML
+ */
+marked.parseInline = markedInstance.parseInline;
+/**
+ * Expose
+ */
+marked.Parser = _Parser;
+marked.parser = _Parser.parse;
+marked.Renderer = _Renderer;
+marked.TextRenderer = _TextRenderer;
+marked.Lexer = _Lexer;
+marked.lexer = _Lexer.lex;
+marked.Tokenizer = _Tokenizer;
+marked.Hooks = _Hooks;
+marked.parse = marked;
+const options = marked.options;
+const setOptions = marked.setOptions;
+const use = marked.use;
+const walkTokens = marked.walkTokens;
+const parseInline = marked.parseInline;
+const parse = marked;
+const parser = _Parser.parse;
+const lexer = _Lexer.lex;
+
+export { _Hooks as Hooks, _Lexer as Lexer, Marked, _Parser as Parser, _Renderer as Renderer, _TextRenderer as TextRenderer, _Tokenizer as Tokenizer, _defaults as defaults, _getDefaults as getDefaults, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens };
+//# sourceMappingURL=marked.esm.js.map
diff --git a/src/zenserver/frontend/html/thirdparty/mermaid.min.js b/src/zenserver/frontend/html/thirdparty/mermaid.min.js
new file mode 100644
index 000000000..6e12566eb
--- /dev/null
+++ b/src/zenserver/frontend/html/thirdparty/mermaid.min.js
@@ -0,0 +1,2607 @@
+"use strict";var __esbuild_esm_mermaid=(()=>{var B2e=Object.create;var by=Object.defineProperty;var F2e=Object.getOwnPropertyDescriptor;var $2e=Object.getOwnPropertyNames;var z2e=Object.getPrototypeOf,G2e=Object.prototype.hasOwnProperty;var o=(t,e)=>by(t,"name",{value:e,configurable:!0});var N=(t,e)=>()=>(t&&(e=t(t=0)),e);var Mi=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),hr=(t,e)=>{for(var r in e)by(t,r,{get:e[r],enumerable:!0})},L4=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of $2e(e))!G2e.call(t,i)&&i!==r&&by(t,i,{get:()=>e[i],enumerable:!(n=F2e(e,i))||n.enumerable});return t},Sr=(t,e,r)=>(L4(t,e,"default"),r&&L4(r,e,"default")),Sa=(t,e,r)=>(r=t!=null?B2e(z2e(t)):{},L4(e||!t||!t.__esModule?by(r,"default",{value:t,enumerable:!0}):r,t)),V2e=t=>L4(by({},"__esModule",{value:!0}),t);var R4=Mi((EC,SC)=>{"use strict";(function(t,e){typeof EC=="object"&&typeof SC<"u"?SC.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs=e()})(EC,function(){"use strict";var t=1e3,e=6e4,r=36e5,n="millisecond",i="second",a="minute",s="hour",l="day",u="week",h="month",f="quarter",d="year",p="date",m="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,v={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:o(function(k){var L=["th","st","nd","rd"],R=k%100;return"["+k+(L[(R-20)%10]||L[R]||L[0])+"]"},"ordinal")},x=o(function(k,L,R){var O=String(k);return!O||O.length>=L?k:""+Array(L+1-O.length).join(R)+k},"m"),b={s:x,z:o(function(k){var L=-k.utcOffset(),R=Math.abs(L),O=Math.floor(R/60),M=R%60;return(L<=0?"+":"-")+x(O,2,"0")+":"+x(M,2,"0")},"z"),m:o(function k(L,R){if(L.date()<R.date())return-k(R,L);var O=12*(R.year()-L.year())+(R.month()-L.month()),M=L.clone().add(O,h),B=R-M<0,F=L.clone().add(O+(B?-1:1),h);return+(-(O+(R-M)/(B?M-F:F-M))||0)},"t"),a:o(function(k){return k<0?Math.ceil(k)||0:Math.floor(k)},"a"),p:o(function(k){return{M:h,y:d,w:u,d:l,D:p,h:s,m:a,s:i,ms:n,Q:f}[k]||String(k||"").toLowerCase().replace(/s$/,"")},"p"),u:o(function(k){return k===void 0},"u")},w="en",C={};C[w]=v;var T="$isDayjsObject",E=o(function(k){return k instanceof I||!(!k||!k[T])},"S"),A=o(function k(L,R,O){var M;if(!L)return w;if(typeof L=="string"){var B=L.toLowerCase();C[B]&&(M=B),R&&(C[B]=R,M=B);var F=L.split("-");if(!M&&F.length>1)return k(F[0])}else{var P=L.name;C[P]=L,M=P}return!O&&M&&(w=M),M||!O&&w},"t"),S=o(function(k,L){if(E(k))return k.clone();var R=typeof L=="object"?L:{};return R.date=k,R.args=arguments,new I(R)},"O"),_=b;_.l=A,_.i=E,_.w=function(k,L){return S(k,{locale:L.$L,utc:L.$u,x:L.$x,$offset:L.$offset})};var I=function(){function k(R){this.$L=A(R.locale,null,!0),this.parse(R),this.$x=this.$x||R.x||{},this[T]=!0}o(k,"M");var L=k.prototype;return L.parse=function(R){this.$d=function(O){var M=O.date,B=O.utc;if(M===null)return new Date(NaN);if(_.u(M))return new Date;if(M instanceof Date)return new Date(M);if(typeof M=="string"&&!/Z$/i.test(M)){var F=M.match(g);if(F){var P=F[2]-1||0,z=(F[7]||"0").substring(0,3);return B?new Date(Date.UTC(F[1],P,F[3]||1,F[4]||0,F[5]||0,F[6]||0,z)):new Date(F[1],P,F[3]||1,F[4]||0,F[5]||0,F[6]||0,z)}}return new Date(M)}(R),this.init()},L.init=function(){var R=this.$d;this.$y=R.getFullYear(),this.$M=R.getMonth(),this.$D=R.getDate(),this.$W=R.getDay(),this.$H=R.getHours(),this.$m=R.getMinutes(),this.$s=R.getSeconds(),this.$ms=R.getMilliseconds()},L.$utils=function(){return _},L.isValid=function(){return this.$d.toString()!==m},L.isSame=function(R,O){var M=S(R);return this.startOf(O)<=M&&M<=this.endOf(O)},L.isAfter=function(R,O){return S(R)<this.startOf(O)},L.isBefore=function(R,O){return this.endOf(O)<S(R)},L.$g=function(R,O,M){return _.u(R)?this[O]:this.set(M,R)},L.unix=function(){return Math.floor(this.valueOf()/1e3)},L.valueOf=function(){return this.$d.getTime()},L.startOf=function(R,O){var M=this,B=!!_.u(O)||O,F=_.p(R),P=o(function(le,he){var K=_.w(M.$u?Date.UTC(M.$y,he,le):new Date(M.$y,he,le),M);return B?K:K.endOf(l)},"l"),z=o(function(le,he){return _.w(M.toDate()[le].apply(M.toDate("s"),(B?[0,0,0,0]:[23,59,59,999]).slice(he)),M)},"$"),$=this.$W,H=this.$M,Q=this.$D,j="set"+(this.$u?"UTC":"");switch(F){case d:return B?P(1,0):P(31,11);case h:return B?P(1,H):P(0,H+1);case u:var ie=this.$locale().weekStart||0,ne=($<ie?$+7:$)-ie;return P(B?Q-ne:Q+(6-ne),H);case l:case p:return z(j+"Hours",0);case s:return z(j+"Minutes",1);case a:return z(j+"Seconds",2);case i:return z(j+"Milliseconds",3);default:return this.clone()}},L.endOf=function(R){return this.startOf(R,!1)},L.$set=function(R,O){var M,B=_.p(R),F="set"+(this.$u?"UTC":""),P=(M={},M[l]=F+"Date",M[p]=F+"Date",M[h]=F+"Month",M[d]=F+"FullYear",M[s]=F+"Hours",M[a]=F+"Minutes",M[i]=F+"Seconds",M[n]=F+"Milliseconds",M)[B],z=B===l?this.$D+(O-this.$W):O;if(B===h||B===d){var $=this.clone().set(p,1);$.$d[P](z),$.init(),this.$d=$.set(p,Math.min(this.$D,$.daysInMonth())).$d}else P&&this.$d[P](z);return this.init(),this},L.set=function(R,O){return this.clone().$set(R,O)},L.get=function(R){return this[_.p(R)]()},L.add=function(R,O){var M,B=this;R=Number(R);var F=_.p(O),P=o(function(H){var Q=S(B);return _.w(Q.date(Q.date()+Math.round(H*R)),B)},"y");if(F===h)return this.set(h,this.$M+R);if(F===d)return this.set(d,this.$y+R);if(F===l)return P(1);if(F===u)return P(7);var z=(M={},M[a]=e,M[s]=r,M[i]=t,M)[F]||1,$=this.$d.getTime()+R*z;return _.w($,this)},L.subtract=function(R,O){return this.add(-1*R,O)},L.format=function(R){var O=this,M=this.$locale();if(!this.isValid())return M.invalidDate||m;var B=R||"YYYY-MM-DDTHH:mm:ssZ",F=_.z(this),P=this.$H,z=this.$m,$=this.$M,H=M.weekdays,Q=M.months,j=M.meridiem,ie=o(function(he,K,X,te){return he&&(he[K]||he(O,B))||X[K].slice(0,te)},"h"),ne=o(function(he){return _.s(P%12||12,he,"0")},"d"),le=j||function(he,K,X){var te=he<12?"AM":"PM";return X?te.toLowerCase():te};return B.replace(y,function(he,K){return K||function(X){switch(X){case"YY":return String(O.$y).slice(-2);case"YYYY":return _.s(O.$y,4,"0");case"M":return $+1;case"MM":return _.s($+1,2,"0");case"MMM":return ie(M.monthsShort,$,Q,3);case"MMMM":return ie(Q,$);case"D":return O.$D;case"DD":return _.s(O.$D,2,"0");case"d":return String(O.$W);case"dd":return ie(M.weekdaysMin,O.$W,H,2);case"ddd":return ie(M.weekdaysShort,O.$W,H,3);case"dddd":return H[O.$W];case"H":return String(P);case"HH":return _.s(P,2,"0");case"h":return ne(1);case"hh":return ne(2);case"a":return le(P,z,!0);case"A":return le(P,z,!1);case"m":return String(z);case"mm":return _.s(z,2,"0");case"s":return String(O.$s);case"ss":return _.s(O.$s,2,"0");case"SSS":return _.s(O.$ms,3,"0");case"Z":return F}return null}(he)||F.replace(":","")})},L.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},L.diff=function(R,O,M){var B,F=this,P=_.p(O),z=S(R),$=(z.utcOffset()-this.utcOffset())*e,H=this-z,Q=o(function(){return _.m(F,z)},"D");switch(P){case d:B=Q()/12;break;case h:B=Q();break;case f:B=Q()/3;break;case u:B=(H-$)/6048e5;break;case l:B=(H-$)/864e5;break;case s:B=H/r;break;case a:B=H/e;break;case i:B=H/t;break;default:B=H}return M?B:_.a(B)},L.daysInMonth=function(){return this.endOf(h).$D},L.$locale=function(){return C[this.$L]},L.locale=function(R,O){if(!R)return this.$L;var M=this.clone(),B=A(R,O,!0);return B&&(M.$L=B),M},L.clone=function(){return _.w(this.$d,this)},L.toDate=function(){return new Date(this.valueOf())},L.toJSON=function(){return this.isValid()?this.toISOString():null},L.toISOString=function(){return this.$d.toISOString()},L.toString=function(){return this.$d.toUTCString()},k}(),D=I.prototype;return S.prototype=D,[["$ms",n],["$s",i],["$m",a],["$H",s],["$W",l],["$M",h],["$y",d],["$D",p]].forEach(function(k){D[k[1]]=function(L){return this.$g(L,k[0],k[1])}}),S.extend=function(k,L){return k.$i||(k(L,I,S),k.$i=!0),S},S.locale=A,S.isDayjs=E,S.unix=function(k){return S(1e3*k)},S.en=C[w],S.Ls=C,S.p={},S})});var CF,eu,Y,wy,bo,vt=N(()=>{"use strict";CF=Sa(R4(),1),eu={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},Y={trace:o((...t)=>{},"trace"),debug:o((...t)=>{},"debug"),info:o((...t)=>{},"info"),warn:o((...t)=>{},"warn"),error:o((...t)=>{},"error"),fatal:o((...t)=>{},"fatal")},wy=o(function(t="fatal"){let e=eu.fatal;typeof t=="string"?t.toLowerCase()in eu&&(e=eu[t]):typeof t=="number"&&(e=t),Y.trace=()=>{},Y.debug=()=>{},Y.info=()=>{},Y.warn=()=>{},Y.error=()=>{},Y.fatal=()=>{},e<=eu.fatal&&(Y.fatal=console.error?console.error.bind(console,bo("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",bo("FATAL"))),e<=eu.error&&(Y.error=console.error?console.error.bind(console,bo("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",bo("ERROR"))),e<=eu.warn&&(Y.warn=console.warn?console.warn.bind(console,bo("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",bo("WARN"))),e<=eu.info&&(Y.info=console.info?console.info.bind(console,bo("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",bo("INFO"))),e<=eu.debug&&(Y.debug=console.debug?console.debug.bind(console,bo("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",bo("DEBUG"))),e<=eu.trace&&(Y.trace=console.debug?console.debug.bind(console,bo("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",bo("TRACE")))},"setLogLevel"),bo=o(t=>`%c${(0,CF.default)().format("ss.SSS")} : ${t} : `,"format")});var U2e,e0,CC,AF,N4=N(()=>{"use strict";U2e=Object.freeze({left:0,top:0,width:16,height:16}),e0=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),CC=Object.freeze({...U2e,...e0}),AF=Object.freeze({...CC,body:"",hidden:!1})});var H2e,_F,DF=N(()=>{"use strict";N4();H2e=Object.freeze({width:null,height:null}),_F=Object.freeze({...H2e,...e0})});var AC,M4,LF=N(()=>{"use strict";AC=o((t,e,r,n="")=>{let i=t.split(":");if(t.slice(0,1)==="@"){if(i.length<2||i.length>3)return null;n=i.shift().slice(1)}if(i.length>3||!i.length)return null;if(i.length>1){let l=i.pop(),u=i.pop(),h={provider:i.length>0?i[0]:n,prefix:u,name:l};return e&&!M4(h)?null:h}let a=i[0],s=a.split("-");if(s.length>1){let l={provider:n,prefix:s.shift(),name:s.join("-")};return e&&!M4(l)?null:l}if(r&&n===""){let l={provider:n,prefix:"",name:a};return e&&!M4(l,r)?null:l}return null},"stringToIcon"),M4=o((t,e)=>t?!!((e&&t.prefix===""||t.prefix)&&t.name):!1,"validateIconName")});function RF(t,e){let r={};!t.hFlip!=!e.hFlip&&(r.hFlip=!0),!t.vFlip!=!e.vFlip&&(r.vFlip=!0);let n=((t.rotate||0)+(e.rotate||0))%4;return n&&(r.rotate=n),r}var NF=N(()=>{"use strict";o(RF,"mergeIconTransformations")});function _C(t,e){let r=RF(t,e);for(let n in AF)n in e0?n in t&&!(n in r)&&(r[n]=e0[n]):n in e?r[n]=e[n]:n in t&&(r[n]=t[n]);return r}var MF=N(()=>{"use strict";N4();NF();o(_C,"mergeIconData")});function IF(t,e){let r=t.icons,n=t.aliases||Object.create(null),i=Object.create(null);function a(s){if(r[s])return i[s]=[];if(!(s in i)){i[s]=null;let l=n[s]&&n[s].parent,u=l&&a(l);u&&(i[s]=[l].concat(u))}return i[s]}return o(a,"resolve"),(e||Object.keys(r).concat(Object.keys(n))).forEach(a),i}var OF=N(()=>{"use strict";o(IF,"getIconsTree")});function PF(t,e,r){let n=t.icons,i=t.aliases||Object.create(null),a={};function s(l){a=_C(n[l]||i[l],a)}return o(s,"parse"),s(e),r.forEach(s),_C(t,a)}function DC(t,e){if(t.icons[e])return PF(t,e,[]);let r=IF(t,[e])[e];return r?PF(t,e,r):null}var BF=N(()=>{"use strict";MF();OF();o(PF,"internalGetIconData");o(DC,"getIconData")});function LC(t,e,r){if(e===1)return t;if(r=r||100,typeof t=="number")return Math.ceil(t*e*r)/r;if(typeof t!="string")return t;let n=t.split(W2e);if(n===null||!n.length)return t;let i=[],a=n.shift(),s=q2e.test(a);for(;;){if(s){let l=parseFloat(a);isNaN(l)?i.push(a):i.push(Math.ceil(l*e*r)/r)}else i.push(a);if(a=n.shift(),a===void 0)return i.join("");s=!s}}var W2e,q2e,FF=N(()=>{"use strict";W2e=/(-?[0-9.]*[0-9]+[0-9.]*)/g,q2e=/^-?[0-9.]*[0-9]+[0-9.]*$/g;o(LC,"calculateSize")});function Y2e(t,e="defs"){let r="",n=t.indexOf("<"+e);for(;n>=0;){let i=t.indexOf(">",n),a=t.indexOf("</"+e);if(i===-1||a===-1)break;let s=t.indexOf(">",a);if(s===-1)break;r+=t.slice(i+1,a).trim(),t=t.slice(0,n).trim()+t.slice(s+1)}return{defs:r,content:t}}function X2e(t,e){return t?"<defs>"+t+"</defs>"+e:e}function $F(t,e,r){let n=Y2e(t);return X2e(n.defs,e+n.content+r)}var zF=N(()=>{"use strict";o(Y2e,"splitSVGDefs");o(X2e,"mergeDefsAndContent");o($F,"wrapSVGContent")});function RC(t,e){let r={...CC,...t},n={..._F,...e},i={left:r.left,top:r.top,width:r.width,height:r.height},a=r.body;[r,n].forEach(y=>{let v=[],x=y.hFlip,b=y.vFlip,w=y.rotate;x?b?w+=2:(v.push("translate("+(i.width+i.left).toString()+" "+(0-i.top).toString()+")"),v.push("scale(-1 1)"),i.top=i.left=0):b&&(v.push("translate("+(0-i.left).toString()+" "+(i.height+i.top).toString()+")"),v.push("scale(1 -1)"),i.top=i.left=0);let C;switch(w<0&&(w-=Math.floor(w/4)*4),w=w%4,w){case 1:C=i.height/2+i.top,v.unshift("rotate(90 "+C.toString()+" "+C.toString()+")");break;case 2:v.unshift("rotate(180 "+(i.width/2+i.left).toString()+" "+(i.height/2+i.top).toString()+")");break;case 3:C=i.width/2+i.left,v.unshift("rotate(-90 "+C.toString()+" "+C.toString()+")");break}w%2===1&&(i.left!==i.top&&(C=i.left,i.left=i.top,i.top=C),i.width!==i.height&&(C=i.width,i.width=i.height,i.height=C)),v.length&&(a=$F(a,'<g transform="'+v.join(" ")+'">',"</g>"))});let s=n.width,l=n.height,u=i.width,h=i.height,f,d;s===null?(d=l===null?"1em":l==="auto"?h:l,f=LC(d,u/h)):(f=s==="auto"?u:s,d=l===null?LC(f,h/u):l==="auto"?h:l);let p={},m=o((y,v)=>{j2e(v)||(p[y]=v.toString())},"setAttr");m("width",f),m("height",d);let g=[i.left,i.top,u,h];return p.viewBox=g.join(" "),{attributes:p,viewBox:g,body:a}}var j2e,GF=N(()=>{"use strict";N4();DF();FF();zF();j2e=o(t=>t==="unset"||t==="undefined"||t==="none","isUnsetKeyword");o(RC,"iconToSVG")});function NC(t,e=Q2e){let r=[],n;for(;n=K2e.exec(t);)r.push(n[1]);if(!r.length)return t;let i="suffix"+(Math.random()*16777216|Date.now()).toString(16);return r.forEach(a=>{let s=typeof e=="function"?e(a):e+(Z2e++).toString(),l=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");t=t.replace(new RegExp('([#;"])('+l+')([")]|\\.[a-z])',"g"),"$1"+s+i+"$3")}),t=t.replace(new RegExp(i,"g"),""),t}var K2e,Q2e,Z2e,VF=N(()=>{"use strict";K2e=/\sid="(\S+)"/g,Q2e="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16),Z2e=0;o(NC,"replaceIDs")});function MC(t,e){let r=t.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(let n in e)r+=" "+n+'="'+e[n]+'"';return'<svg xmlns="http://www.w3.org/2000/svg"'+r+">"+t+"</svg>"}var UF=N(()=>{"use strict";o(MC,"iconToHTML")});var WF=Mi((iit,HF)=>{"use strict";var t0=1e3,r0=t0*60,n0=r0*60,Wf=n0*24,J2e=Wf*7,exe=Wf*365.25;HF.exports=function(t,e){e=e||{};var r=typeof t;if(r==="string"&&t.length>0)return txe(t);if(r==="number"&&isFinite(t))return e.long?nxe(t):rxe(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))};function txe(t){if(t=String(t),!(t.length>100)){var e=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(t);if(e){var r=parseFloat(e[1]),n=(e[2]||"ms").toLowerCase();switch(n){case"years":case"year":case"yrs":case"yr":case"y":return r*exe;case"weeks":case"week":case"w":return r*J2e;case"days":case"day":case"d":return r*Wf;case"hours":case"hour":case"hrs":case"hr":case"h":return r*n0;case"minutes":case"minute":case"mins":case"min":case"m":return r*r0;case"seconds":case"second":case"secs":case"sec":case"s":return r*t0;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}}}o(txe,"parse");function rxe(t){var e=Math.abs(t);return e>=Wf?Math.round(t/Wf)+"d":e>=n0?Math.round(t/n0)+"h":e>=r0?Math.round(t/r0)+"m":e>=t0?Math.round(t/t0)+"s":t+"ms"}o(rxe,"fmtShort");function nxe(t){var e=Math.abs(t);return e>=Wf?I4(t,e,Wf,"day"):e>=n0?I4(t,e,n0,"hour"):e>=r0?I4(t,e,r0,"minute"):e>=t0?I4(t,e,t0,"second"):t+" ms"}o(nxe,"fmtLong");function I4(t,e,r,n){var i=e>=r*1.5;return Math.round(t/r)+" "+n+(i?"s":"")}o(I4,"plural")});var YF=Mi((sit,qF)=>{"use strict";function ixe(t){r.debug=r,r.default=r,r.coerce=u,r.disable=s,r.enable=i,r.enabled=l,r.humanize=WF(),r.destroy=h,Object.keys(t).forEach(f=>{r[f]=t[f]}),r.names=[],r.skips=[],r.formatters={};function e(f){let d=0;for(let p=0;p<f.length;p++)d=(d<<5)-d+f.charCodeAt(p),d|=0;return r.colors[Math.abs(d)%r.colors.length]}o(e,"selectColor"),r.selectColor=e;function r(f){let d,p=null,m,g;function y(...v){if(!y.enabled)return;let x=y,b=Number(new Date),w=b-(d||b);x.diff=w,x.prev=d,x.curr=b,d=b,v[0]=r.coerce(v[0]),typeof v[0]!="string"&&v.unshift("%O");let C=0;v[0]=v[0].replace(/%([a-zA-Z%])/g,(E,A)=>{if(E==="%%")return"%";C++;let S=r.formatters[A];if(typeof S=="function"){let _=v[C];E=S.call(x,_),v.splice(C,1),C--}return E}),r.formatArgs.call(x,v),(x.log||r.log).apply(x,v)}return o(y,"debug"),y.namespace=f,y.useColors=r.useColors(),y.color=r.selectColor(f),y.extend=n,y.destroy=r.destroy,Object.defineProperty(y,"enabled",{enumerable:!0,configurable:!1,get:o(()=>p!==null?p:(m!==r.namespaces&&(m=r.namespaces,g=r.enabled(f)),g),"get"),set:o(v=>{p=v},"set")}),typeof r.init=="function"&&r.init(y),y}o(r,"createDebug");function n(f,d){let p=r(this.namespace+(typeof d>"u"?":":d)+f);return p.log=this.log,p}o(n,"extend");function i(f){r.save(f),r.namespaces=f,r.names=[],r.skips=[];let d=(typeof f=="string"?f:"").trim().replace(" ",",").split(",").filter(Boolean);for(let p of d)p[0]==="-"?r.skips.push(p.slice(1)):r.names.push(p)}o(i,"enable");function a(f,d){let p=0,m=0,g=-1,y=0;for(;p<f.length;)if(m<d.length&&(d[m]===f[p]||d[m]==="*"))d[m]==="*"?(g=m,y=p,m++):(p++,m++);else if(g!==-1)m=g+1,y++,p=y;else return!1;for(;m<d.length&&d[m]==="*";)m++;return m===d.length}o(a,"matchesTemplate");function s(){let f=[...r.names,...r.skips.map(d=>"-"+d)].join(",");return r.enable(""),f}o(s,"disable");function l(f){for(let d of r.skips)if(a(f,d))return!1;for(let d of r.names)if(a(f,d))return!0;return!1}o(l,"enabled");function u(f){return f instanceof Error?f.stack||f.message:f}o(u,"coerce");function h(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return o(h,"destroy"),r.enable(r.load()),r}o(ixe,"setup");qF.exports=ixe});var XF=Mi((qs,O4)=>{"use strict";qs.formatArgs=sxe;qs.save=oxe;qs.load=lxe;qs.useColors=axe;qs.storage=cxe();qs.destroy=(()=>{let t=!1;return()=>{t||(t=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})();qs.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function axe(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let t;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(t=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(t[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}o(axe,"useColors");function sxe(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+O4.exports.humanize(this.diff),!this.useColors)return;let e="color: "+this.color;t.splice(1,0,e,"color: inherit");let r=0,n=0;t[0].replace(/%[a-zA-Z%]/g,i=>{i!=="%%"&&(r++,i==="%c"&&(n=r))}),t.splice(n,0,e)}o(sxe,"formatArgs");qs.log=console.debug||console.log||(()=>{});function oxe(t){try{t?qs.storage.setItem("debug",t):qs.storage.removeItem("debug")}catch{}}o(oxe,"save");function lxe(){let t;try{t=qs.storage.getItem("debug")}catch{}return!t&&typeof process<"u"&&"env"in process&&(t=process.env.DEBUG),t}o(lxe,"load");function cxe(){try{return localStorage}catch{}}o(cxe,"localstorage");O4.exports=YF()(qs);var{formatters:uxe}=O4.exports;uxe.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}});var uit,jF=N(()=>{"use strict";LF();BF();GF();VF();UF();uit=Sa(XF(),1)});var OC,IC,KF,P4,hxe,wo,tu=N(()=>{"use strict";vt();jF();OC={body:'<g><rect width="80" height="80" style="fill: #087ebf; stroke-width: 0px;"/><text transform="translate(21.16 64.67)" style="fill: #fff; font-family: ArialMT, Arial; font-size: 67.75px;"><tspan x="0" y="0">?</tspan></text></g>',height:80,width:80},IC=new Map,KF=new Map,P4=o(t=>{for(let e of t){if(!e.name)throw new Error('Invalid icon loader. Must have a "name" property with non-empty string value.');if(Y.debug("Registering icon pack:",e.name),"loader"in e)KF.set(e.name,e.loader);else if("icons"in e)IC.set(e.name,e.icons);else throw Y.error("Invalid icon loader:",e),new Error('Invalid icon loader. Must have either "icons" or "loader" property.')}},"registerIconPacks"),hxe=o(async(t,e)=>{let r=AC(t,!0,e!==void 0);if(!r)throw new Error(`Invalid icon name: ${t}`);let n=r.prefix||e;if(!n)throw new Error(`Icon name must contain a prefix: ${t}`);let i=IC.get(n);if(!i){let s=KF.get(n);if(!s)throw new Error(`Icon set not found: ${r.prefix}`);try{i={...await s(),prefix:n},IC.set(n,i)}catch(l){throw Y.error(l),new Error(`Failed to load icon set: ${r.prefix}`)}}let a=DC(i,r.name);if(!a)throw new Error(`Icon not found: ${t}`);return a},"getRegisteredIconData"),wo=o(async(t,e)=>{let r;try{r=await hxe(t,e?.fallbackPrefix)}catch(a){Y.error(a),r=OC}let n=RC(r,e);return MC(NC(n.body),n.attributes)},"getIconSVG")});function B4(t){for(var e=[],r=1;r<arguments.length;r++)e[r-1]=arguments[r];var n=Array.from(typeof t=="string"?[t]:t);n[n.length-1]=n[n.length-1].replace(/\r?\n([\t ]*)$/,"");var i=n.reduce(function(l,u){var h=u.match(/\n([\t ]+|(?!\s).)/g);return h?l.concat(h.map(function(f){var d,p;return(p=(d=f.match(/[\t ]/g))===null||d===void 0?void 0:d.length)!==null&&p!==void 0?p:0})):l},[]);if(i.length){var a=new RegExp(`
+[ ]{`+Math.min.apply(Math,i)+"}","g");n=n.map(function(l){return l.replace(a,`
+`)})}n[0]=n[0].replace(/^\r?\n/,"");var s=n[0];return e.forEach(function(l,u){var h=s.match(/(?:^|\n)( *)$/),f=h?h[1]:"",d=l;typeof l=="string"&&l.includes(`
+`)&&(d=String(l).split(`
+`).map(function(p,m){return m===0?p:""+f+p}).join(`
+`)),s+=d+n[u+1]}),s}var PC=N(()=>{"use strict";o(B4,"dedent")});var F4,qf,QF,$4=N(()=>{"use strict";F4=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,qf=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,QF=/\s*%%.*\n/gm});var i0,BC=N(()=>{"use strict";i0=class extends Error{static{o(this,"UnknownDiagramError")}constructor(e){super(e),this.name="UnknownDiagramError"}}});var Yf,a0,z4,FC,ZF,Xf=N(()=>{"use strict";vt();$4();BC();Yf={},a0=o(function(t,e){t=t.replace(F4,"").replace(qf,"").replace(QF,`
+`);for(let[r,{detector:n}]of Object.entries(Yf))if(n(t,e))return r;throw new i0(`No diagram type detected matching given configuration for text: ${t}`)},"detectType"),z4=o((...t)=>{for(let{id:e,detector:r,loader:n}of t)FC(e,r,n)},"registerLazyLoadedDiagrams"),FC=o((t,e,r)=>{Yf[t]&&Y.warn(`Detector with key ${t} already exists. Overwriting.`),Yf[t]={detector:e,loader:r},Y.debug(`Detector with key ${t} added${r?" with loader":""}`)},"addDetector"),ZF=o(t=>Yf[t].loader,"getDiagramLoader")});var Ty,JF,$C=N(()=>{"use strict";Ty=function(){var t=o(function($e,Re,Ie,be){for(Ie=Ie||{},be=$e.length;be--;Ie[$e[be]]=Re);return Ie},"o"),e=[1,24],r=[1,25],n=[1,26],i=[1,27],a=[1,28],s=[1,63],l=[1,64],u=[1,65],h=[1,66],f=[1,67],d=[1,68],p=[1,69],m=[1,29],g=[1,30],y=[1,31],v=[1,32],x=[1,33],b=[1,34],w=[1,35],C=[1,36],T=[1,37],E=[1,38],A=[1,39],S=[1,40],_=[1,41],I=[1,42],D=[1,43],k=[1,44],L=[1,45],R=[1,46],O=[1,47],M=[1,48],B=[1,50],F=[1,51],P=[1,52],z=[1,53],$=[1,54],H=[1,55],Q=[1,56],j=[1,57],ie=[1,58],ne=[1,59],le=[1,60],he=[14,42],K=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],X=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],te=[1,82],J=[1,83],se=[1,84],ue=[1,85],Z=[12,14,42],Se=[12,14,33,42],ce=[12,14,33,42,76,77,79,80],ae=[12,33],Oe=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],ge={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:o(function(Re,Ie,be,W,de,re,oe){var V=re.length-1;switch(de){case 3:W.setDirection("TB");break;case 4:W.setDirection("BT");break;case 5:W.setDirection("RL");break;case 6:W.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:W.setC4Type(re[V-3]);break;case 19:W.setTitle(re[V].substring(6)),this.$=re[V].substring(6);break;case 20:W.setAccDescription(re[V].substring(15)),this.$=re[V].substring(15);break;case 21:this.$=re[V].trim(),W.setTitle(this.$);break;case 22:case 23:this.$=re[V].trim(),W.setAccDescription(this.$);break;case 28:re[V].splice(2,0,"ENTERPRISE"),W.addPersonOrSystemBoundary(...re[V]),this.$=re[V];break;case 29:re[V].splice(2,0,"SYSTEM"),W.addPersonOrSystemBoundary(...re[V]),this.$=re[V];break;case 30:W.addPersonOrSystemBoundary(...re[V]),this.$=re[V];break;case 31:re[V].splice(2,0,"CONTAINER"),W.addContainerBoundary(...re[V]),this.$=re[V];break;case 32:W.addDeploymentNode("node",...re[V]),this.$=re[V];break;case 33:W.addDeploymentNode("nodeL",...re[V]),this.$=re[V];break;case 34:W.addDeploymentNode("nodeR",...re[V]),this.$=re[V];break;case 35:W.popBoundaryParseStack();break;case 39:W.addPersonOrSystem("person",...re[V]),this.$=re[V];break;case 40:W.addPersonOrSystem("external_person",...re[V]),this.$=re[V];break;case 41:W.addPersonOrSystem("system",...re[V]),this.$=re[V];break;case 42:W.addPersonOrSystem("system_db",...re[V]),this.$=re[V];break;case 43:W.addPersonOrSystem("system_queue",...re[V]),this.$=re[V];break;case 44:W.addPersonOrSystem("external_system",...re[V]),this.$=re[V];break;case 45:W.addPersonOrSystem("external_system_db",...re[V]),this.$=re[V];break;case 46:W.addPersonOrSystem("external_system_queue",...re[V]),this.$=re[V];break;case 47:W.addContainer("container",...re[V]),this.$=re[V];break;case 48:W.addContainer("container_db",...re[V]),this.$=re[V];break;case 49:W.addContainer("container_queue",...re[V]),this.$=re[V];break;case 50:W.addContainer("external_container",...re[V]),this.$=re[V];break;case 51:W.addContainer("external_container_db",...re[V]),this.$=re[V];break;case 52:W.addContainer("external_container_queue",...re[V]),this.$=re[V];break;case 53:W.addComponent("component",...re[V]),this.$=re[V];break;case 54:W.addComponent("component_db",...re[V]),this.$=re[V];break;case 55:W.addComponent("component_queue",...re[V]),this.$=re[V];break;case 56:W.addComponent("external_component",...re[V]),this.$=re[V];break;case 57:W.addComponent("external_component_db",...re[V]),this.$=re[V];break;case 58:W.addComponent("external_component_queue",...re[V]),this.$=re[V];break;case 60:W.addRel("rel",...re[V]),this.$=re[V];break;case 61:W.addRel("birel",...re[V]),this.$=re[V];break;case 62:W.addRel("rel_u",...re[V]),this.$=re[V];break;case 63:W.addRel("rel_d",...re[V]),this.$=re[V];break;case 64:W.addRel("rel_l",...re[V]),this.$=re[V];break;case 65:W.addRel("rel_r",...re[V]),this.$=re[V];break;case 66:W.addRel("rel_b",...re[V]),this.$=re[V];break;case 67:re[V].splice(0,1),W.addRel("rel",...re[V]),this.$=re[V];break;case 68:W.updateElStyle("update_el_style",...re[V]),this.$=re[V];break;case 69:W.updateRelStyle("update_rel_style",...re[V]),this.$=re[V];break;case 70:W.updateLayoutConfig("update_layout_config",...re[V]),this.$=re[V];break;case 71:this.$=[re[V]];break;case 72:re[V].unshift(re[V-1]),this.$=re[V];break;case 73:case 75:this.$=re[V].trim();break;case 74:let xe={};xe[re[V-1].trim()]=re[V].trim(),this.$=xe;break;case 76:this.$="";break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le},{13:70,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le},{13:71,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le},{13:72,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le},{13:73,19:20,20:21,21:22,22:e,23:r,24:n,26:i,28:a,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le},{14:[1,74]},t(he,[2,13],{43:23,29:49,30:61,32:62,20:75,34:s,36:l,37:u,38:h,39:f,40:d,41:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le}),t(he,[2,14]),t(K,[2,16],{12:[1,76]}),t(he,[2,36],{12:[1,77]}),t(X,[2,19]),t(X,[2,20]),{25:[1,78]},{27:[1,79]},t(X,[2,23]),{35:80,75:81,76:te,77:J,79:se,80:ue},{35:86,75:81,76:te,77:J,79:se,80:ue},{35:87,75:81,76:te,77:J,79:se,80:ue},{35:88,75:81,76:te,77:J,79:se,80:ue},{35:89,75:81,76:te,77:J,79:se,80:ue},{35:90,75:81,76:te,77:J,79:se,80:ue},{35:91,75:81,76:te,77:J,79:se,80:ue},{35:92,75:81,76:te,77:J,79:se,80:ue},{35:93,75:81,76:te,77:J,79:se,80:ue},{35:94,75:81,76:te,77:J,79:se,80:ue},{35:95,75:81,76:te,77:J,79:se,80:ue},{35:96,75:81,76:te,77:J,79:se,80:ue},{35:97,75:81,76:te,77:J,79:se,80:ue},{35:98,75:81,76:te,77:J,79:se,80:ue},{35:99,75:81,76:te,77:J,79:se,80:ue},{35:100,75:81,76:te,77:J,79:se,80:ue},{35:101,75:81,76:te,77:J,79:se,80:ue},{35:102,75:81,76:te,77:J,79:se,80:ue},{35:103,75:81,76:te,77:J,79:se,80:ue},{35:104,75:81,76:te,77:J,79:se,80:ue},t(Z,[2,59]),{35:105,75:81,76:te,77:J,79:se,80:ue},{35:106,75:81,76:te,77:J,79:se,80:ue},{35:107,75:81,76:te,77:J,79:se,80:ue},{35:108,75:81,76:te,77:J,79:se,80:ue},{35:109,75:81,76:te,77:J,79:se,80:ue},{35:110,75:81,76:te,77:J,79:se,80:ue},{35:111,75:81,76:te,77:J,79:se,80:ue},{35:112,75:81,76:te,77:J,79:se,80:ue},{35:113,75:81,76:te,77:J,79:se,80:ue},{35:114,75:81,76:te,77:J,79:se,80:ue},{35:115,75:81,76:te,77:J,79:se,80:ue},{20:116,29:49,30:61,32:62,34:s,36:l,37:u,38:h,39:f,40:d,41:p,43:23,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le},{12:[1,118],33:[1,117]},{35:119,75:81,76:te,77:J,79:se,80:ue},{35:120,75:81,76:te,77:J,79:se,80:ue},{35:121,75:81,76:te,77:J,79:se,80:ue},{35:122,75:81,76:te,77:J,79:se,80:ue},{35:123,75:81,76:te,77:J,79:se,80:ue},{35:124,75:81,76:te,77:J,79:se,80:ue},{35:125,75:81,76:te,77:J,79:se,80:ue},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(he,[2,15]),t(K,[2,17],{21:22,19:130,22:e,23:r,24:n,26:i,28:a}),t(he,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:r,24:n,26:i,28:a,34:s,36:l,37:u,38:h,39:f,40:d,41:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w,51:C,52:T,53:E,54:A,55:S,56:_,57:I,58:D,59:k,60:L,61:R,62:O,63:M,64:B,65:F,66:P,67:z,68:$,69:H,70:Q,71:j,72:ie,73:ne,74:le}),t(X,[2,21]),t(X,[2,22]),t(Z,[2,39]),t(Se,[2,71],{75:81,35:132,76:te,77:J,79:se,80:ue}),t(ce,[2,73]),{78:[1,133]},t(ce,[2,75]),t(ce,[2,76]),t(Z,[2,40]),t(Z,[2,41]),t(Z,[2,42]),t(Z,[2,43]),t(Z,[2,44]),t(Z,[2,45]),t(Z,[2,46]),t(Z,[2,47]),t(Z,[2,48]),t(Z,[2,49]),t(Z,[2,50]),t(Z,[2,51]),t(Z,[2,52]),t(Z,[2,53]),t(Z,[2,54]),t(Z,[2,55]),t(Z,[2,56]),t(Z,[2,57]),t(Z,[2,58]),t(Z,[2,60]),t(Z,[2,61]),t(Z,[2,62]),t(Z,[2,63]),t(Z,[2,64]),t(Z,[2,65]),t(Z,[2,66]),t(Z,[2,67]),t(Z,[2,68]),t(Z,[2,69]),t(Z,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(ae,[2,28]),t(ae,[2,29]),t(ae,[2,30]),t(ae,[2,31]),t(ae,[2,32]),t(ae,[2,33]),t(ae,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t(K,[2,18]),t(he,[2,38]),t(Se,[2,72]),t(ce,[2,74]),t(Z,[2,24]),t(Z,[2,35]),t(Oe,[2,25]),t(Oe,[2,26],{12:[1,138]}),t(Oe,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:o(function(Re,Ie){if(Ie.recoverable)this.trace(Re);else{var be=new Error(Re);throw be.hash=Ie,be}},"parseError"),parse:o(function(Re){var Ie=this,be=[0],W=[],de=[null],re=[],oe=this.table,V="",xe=0,q=0,pe=0,ve=2,Pe=1,_e=re.slice.call(arguments,1),we=Object.create(this.lexer),Ve={yy:{}};for(var De in this.yy)Object.prototype.hasOwnProperty.call(this.yy,De)&&(Ve.yy[De]=this.yy[De]);we.setInput(Re,Ve.yy),Ve.yy.lexer=we,Ve.yy.parser=this,typeof we.yylloc>"u"&&(we.yylloc={});var qe=we.yylloc;re.push(qe);var at=we.options&&we.options.ranges;typeof Ve.yy.parseError=="function"?this.parseError=Ve.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Rt(nt){be.length=be.length-2*nt,de.length=de.length-nt,re.length=re.length-nt}o(Rt,"popStack");function st(){var nt;return nt=W.pop()||we.lex()||Pe,typeof nt!="number"&&(nt instanceof Array&&(W=nt,nt=W.pop()),nt=Ie.symbols_[nt]||nt),nt}o(st,"lex");for(var Ue,ct,We,ot,Yt,bt,Mt={},xt,ut,Et,ft;;){if(We=be[be.length-1],this.defaultActions[We]?ot=this.defaultActions[We]:((Ue===null||typeof Ue>"u")&&(Ue=st()),ot=oe[We]&&oe[We][Ue]),typeof ot>"u"||!ot.length||!ot[0]){var yt="";ft=[];for(xt in oe[We])this.terminals_[xt]&&xt>ve&&ft.push("'"+this.terminals_[xt]+"'");we.showPosition?yt="Parse error on line "+(xe+1)+`:
+`+we.showPosition()+`
+Expecting `+ft.join(", ")+", got '"+(this.terminals_[Ue]||Ue)+"'":yt="Parse error on line "+(xe+1)+": Unexpected "+(Ue==Pe?"end of input":"'"+(this.terminals_[Ue]||Ue)+"'"),this.parseError(yt,{text:we.match,token:this.terminals_[Ue]||Ue,line:we.yylineno,loc:qe,expected:ft})}if(ot[0]instanceof Array&&ot.length>1)throw new Error("Parse Error: multiple actions possible at state: "+We+", token: "+Ue);switch(ot[0]){case 1:be.push(Ue),de.push(we.yytext),re.push(we.yylloc),be.push(ot[1]),Ue=null,ct?(Ue=ct,ct=null):(q=we.yyleng,V=we.yytext,xe=we.yylineno,qe=we.yylloc,pe>0&&pe--);break;case 2:if(ut=this.productions_[ot[1]][1],Mt.$=de[de.length-ut],Mt._$={first_line:re[re.length-(ut||1)].first_line,last_line:re[re.length-1].last_line,first_column:re[re.length-(ut||1)].first_column,last_column:re[re.length-1].last_column},at&&(Mt._$.range=[re[re.length-(ut||1)].range[0],re[re.length-1].range[1]]),bt=this.performAction.apply(Mt,[V,q,xe,Ve.yy,ot[1],de,re].concat(_e)),typeof bt<"u")return bt;ut&&(be=be.slice(0,-1*ut*2),de=de.slice(0,-1*ut),re=re.slice(0,-1*ut)),be.push(this.productions_[ot[1]][0]),de.push(Mt.$),re.push(Mt._$),Et=oe[be[be.length-2]][be[be.length-1]],be.push(Et);break;case 3:return!0}}return!0},"parse")},ze=function(){var $e={EOF:1,parseError:o(function(Ie,be){if(this.yy.parser)this.yy.parser.parseError(Ie,be);else throw new Error(Ie)},"parseError"),setInput:o(function(Re,Ie){return this.yy=Ie||this.yy||{},this._input=Re,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var Re=this._input[0];this.yytext+=Re,this.yyleng++,this.offset++,this.match+=Re,this.matched+=Re;var Ie=Re.match(/(?:\r\n?|\n).*/g);return Ie?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),Re},"input"),unput:o(function(Re){var Ie=Re.length,be=Re.split(/(?:\r\n?|\n)/g);this._input=Re+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-Ie),this.offset-=Ie;var W=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),be.length-1&&(this.yylineno-=be.length-1);var de=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:be?(be.length===W.length?this.yylloc.first_column:0)+W[W.length-be.length].length-be[0].length:this.yylloc.first_column-Ie},this.options.ranges&&(this.yylloc.range=[de[0],de[0]+this.yyleng-Ie]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(Re){this.unput(this.match.slice(Re))},"less"),pastInput:o(function(){var Re=this.matched.substr(0,this.matched.length-this.match.length);return(Re.length>20?"...":"")+Re.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var Re=this.match;return Re.length<20&&(Re+=this._input.substr(0,20-Re.length)),(Re.substr(0,20)+(Re.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var Re=this.pastInput(),Ie=new Array(Re.length+1).join("-");return Re+this.upcomingInput()+`
+`+Ie+"^"},"showPosition"),test_match:o(function(Re,Ie){var be,W,de;if(this.options.backtrack_lexer&&(de={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(de.yylloc.range=this.yylloc.range.slice(0))),W=Re[0].match(/(?:\r\n?|\n).*/g),W&&(this.yylineno+=W.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:W?W[W.length-1].length-W[W.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+Re[0].length},this.yytext+=Re[0],this.match+=Re[0],this.matches=Re,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(Re[0].length),this.matched+=Re[0],be=this.performAction.call(this,this.yy,this,Ie,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),be)return be;if(this._backtrack){for(var re in de)this[re]=de[re];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var Re,Ie,be,W;this._more||(this.yytext="",this.match="");for(var de=this._currentRules(),re=0;re<de.length;re++)if(be=this._input.match(this.rules[de[re]]),be&&(!Ie||be[0].length>Ie[0].length)){if(Ie=be,W=re,this.options.backtrack_lexer){if(Re=this.test_match(be,de[re]),Re!==!1)return Re;if(this._backtrack){Ie=!1;continue}else return!1}else if(!this.options.flex)break}return Ie?(Re=this.test_match(Ie,de[W]),Re!==!1?Re:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var Ie=this.next();return Ie||this.lex()},"lex"),begin:o(function(Ie){this.conditionStack.push(Ie)},"begin"),popState:o(function(){var Ie=this.conditionStack.length-1;return Ie>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(Ie){return Ie=this.conditionStack.length-1-Math.abs(Ie||0),Ie>=0?this.conditionStack[Ie]:"INITIAL"},"topState"),pushState:o(function(Ie){this.begin(Ie)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(Ie,be,W,de){var re=de;switch(W){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),26;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:break;case 14:c;break;case 15:return 12;case 16:break;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;break;case 23:return this.begin("person"),44;break;case 24:return this.begin("system_ext_queue"),51;break;case 25:return this.begin("system_ext_db"),50;break;case 26:return this.begin("system_ext"),49;break;case 27:return this.begin("system_queue"),48;break;case 28:return this.begin("system_db"),47;break;case 29:return this.begin("system"),46;break;case 30:return this.begin("boundary"),37;break;case 31:return this.begin("enterprise_boundary"),34;break;case 32:return this.begin("system_boundary"),36;break;case 33:return this.begin("container_ext_queue"),57;break;case 34:return this.begin("container_ext_db"),56;break;case 35:return this.begin("container_ext"),55;break;case 36:return this.begin("container_queue"),54;break;case 37:return this.begin("container_db"),53;break;case 38:return this.begin("container"),52;break;case 39:return this.begin("container_boundary"),38;break;case 40:return this.begin("component_ext_queue"),63;break;case 41:return this.begin("component_ext_db"),62;break;case 42:return this.begin("component_ext"),61;break;case 43:return this.begin("component_queue"),60;break;case 44:return this.begin("component_db"),59;break;case 45:return this.begin("component"),58;break;case 46:return this.begin("node"),39;break;case 47:return this.begin("node"),39;break;case 48:return this.begin("node_l"),40;break;case 49:return this.begin("node_r"),41;break;case 50:return this.begin("rel"),64;break;case 51:return this.begin("birel"),65;break;case 52:return this.begin("rel_u"),66;break;case 53:return this.begin("rel_u"),66;break;case 54:return this.begin("rel_d"),67;break;case 55:return this.begin("rel_d"),67;break;case 56:return this.begin("rel_l"),68;break;case 57:return this.begin("rel_l"),68;break;case 58:return this.begin("rel_r"),69;break;case 59:return this.begin("rel_r"),69;break;case 60:return this.begin("rel_b"),70;break;case 61:return this.begin("rel_index"),71;break;case 62:return this.begin("update_el_style"),72;break;case 63:return this.begin("update_rel_style"),73;break;case 64:return this.begin("update_layout_config"),74;break;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";break;case 67:this.begin("attribute");break;case 68:this.popState(),this.popState();break;case 69:return 80;case 70:break;case 71:return 80;case 72:this.begin("string");break;case 73:this.popState();break;case 74:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";break;case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 79:this.popState(),this.popState();break;case 80:return"STR";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}};return $e}();ge.lexer=ze;function He(){this.yy={}}return o(He,"Parser"),He.prototype=ge,ge.Parser=He,new He}();Ty.parser=Ty;JF=Ty});var zC,Gn,s0=N(()=>{"use strict";zC=o((t,e,{depth:r=2,clobber:n=!1}={})=>{let i={depth:r,clobber:n};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach(a=>zC(t,a,i)),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach(a=>{t.includes(a)||t.push(a)}),t):t===void 0||r<=0?t!=null&&typeof t=="object"&&typeof e=="object"?Object.assign(t,e):e:(e!==void 0&&typeof t=="object"&&typeof e=="object"&&Object.keys(e).forEach(a=>{typeof e[a]=="object"&&(t[a]===void 0||typeof t[a]=="object")?(t[a]===void 0&&(t[a]=Array.isArray(e[a])?[]:{}),t[a]=zC(t[a],e[a],{depth:r-1,clobber:n})):(n||typeof t[a]!="object"&&typeof e[a]!="object")&&(t[a]=e[a])}),t)},"assignWithDepth"),Gn=zC});var G4,e$,t$=N(()=>{"use strict";G4={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:o(t=>t>=255?255:t<0?0:t,"r"),g:o(t=>t>=255?255:t<0?0:t,"g"),b:o(t=>t>=255?255:t<0?0:t,"b"),h:o(t=>t%360,"h"),s:o(t=>t>=100?100:t<0?0:t,"s"),l:o(t=>t>=100?100:t<0?0:t,"l"),a:o(t=>t>=1?1:t<0?0:t,"a")},toLinear:o(t=>{let e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},"toLinear"),hue2rgb:o((t,e,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<.16666666666666666?t+(e-t)*6*r:r<.5?e:r<.6666666666666666?t+(e-t)*(.6666666666666666-r)*6:t),"hue2rgb"),hsl2rgb:o(({h:t,s:e,l:r},n)=>{if(!e)return r*2.55;t/=360,e/=100,r/=100;let i=r<.5?r*(1+e):r+e-r*e,a=2*r-i;switch(n){case"r":return G4.hue2rgb(a,i,t+.3333333333333333)*255;case"g":return G4.hue2rgb(a,i,t)*255;case"b":return G4.hue2rgb(a,i,t-.3333333333333333)*255}},"hsl2rgb"),rgb2hsl:o(({r:t,g:e,b:r},n)=>{t/=255,e/=255,r/=255;let i=Math.max(t,e,r),a=Math.min(t,e,r),s=(i+a)/2;if(n==="l")return s*100;if(i===a)return 0;let l=i-a,u=s>.5?l/(2-i-a):l/(i+a);if(n==="s")return u*100;switch(i){case t:return((e-r)/l+(e<r?6:0))*60;case e:return((r-t)/l+2)*60;case r:return((t-e)/l+4)*60;default:return-1}},"rgb2hsl")},e$=G4});var fxe,r$,n$=N(()=>{"use strict";fxe={clamp:o((t,e,r)=>e>r?Math.min(e,Math.max(r,t)):Math.min(r,Math.max(e,t)),"clamp"),round:o(t=>Math.round(t*1e10)/1e10,"round")},r$=fxe});var dxe,i$,a$=N(()=>{"use strict";dxe={dec2hex:o(t=>{let e=Math.round(t).toString(16);return e.length>1?e:`0${e}`},"dec2hex")},i$=dxe});var pxe,jt,Wl=N(()=>{"use strict";t$();n$();a$();pxe={channel:e$,lang:r$,unit:i$},jt=pxe});var ru,Ii,ky=N(()=>{"use strict";Wl();ru={};for(let t=0;t<=255;t++)ru[t]=jt.unit.dec2hex(t);Ii={ALL:0,RGB:1,HSL:2}});var GC,s$,o$=N(()=>{"use strict";ky();GC=class{static{o(this,"Type")}constructor(){this.type=Ii.ALL}get(){return this.type}set(e){if(this.type&&this.type!==e)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=e}reset(){this.type=Ii.ALL}is(e){return this.type===e}},s$=GC});var VC,l$,c$=N(()=>{"use strict";Wl();o$();ky();VC=class{static{o(this,"Channels")}constructor(e,r){this.color=r,this.changed=!1,this.data=e,this.type=new s$}set(e,r){return this.color=r,this.changed=!1,this.data=e,this.type.type=Ii.ALL,this}_ensureHSL(){let e=this.data,{h:r,s:n,l:i}=e;r===void 0&&(e.h=jt.channel.rgb2hsl(e,"h")),n===void 0&&(e.s=jt.channel.rgb2hsl(e,"s")),i===void 0&&(e.l=jt.channel.rgb2hsl(e,"l"))}_ensureRGB(){let e=this.data,{r,g:n,b:i}=e;r===void 0&&(e.r=jt.channel.hsl2rgb(e,"r")),n===void 0&&(e.g=jt.channel.hsl2rgb(e,"g")),i===void 0&&(e.b=jt.channel.hsl2rgb(e,"b"))}get r(){let e=this.data,r=e.r;return!this.type.is(Ii.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"r"))}get g(){let e=this.data,r=e.g;return!this.type.is(Ii.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"g"))}get b(){let e=this.data,r=e.b;return!this.type.is(Ii.HSL)&&r!==void 0?r:(this._ensureHSL(),jt.channel.hsl2rgb(e,"b"))}get h(){let e=this.data,r=e.h;return!this.type.is(Ii.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"h"))}get s(){let e=this.data,r=e.s;return!this.type.is(Ii.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"s"))}get l(){let e=this.data,r=e.l;return!this.type.is(Ii.RGB)&&r!==void 0?r:(this._ensureRGB(),jt.channel.rgb2hsl(e,"l"))}get a(){return this.data.a}set r(e){this.type.set(Ii.RGB),this.changed=!0,this.data.r=e}set g(e){this.type.set(Ii.RGB),this.changed=!0,this.data.g=e}set b(e){this.type.set(Ii.RGB),this.changed=!0,this.data.b=e}set h(e){this.type.set(Ii.HSL),this.changed=!0,this.data.h=e}set s(e){this.type.set(Ii.HSL),this.changed=!0,this.data.s=e}set l(e){this.type.set(Ii.HSL),this.changed=!0,this.data.l=e}set a(e){this.changed=!0,this.data.a=e}},l$=VC});var mxe,ih,Ey=N(()=>{"use strict";c$();mxe=new l$({r:0,g:0,b:0,a:0},"transparent"),ih=mxe});var u$,jf,UC=N(()=>{"use strict";Ey();ky();u$={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:o(t=>{if(t.charCodeAt(0)!==35)return;let e=t.match(u$.re);if(!e)return;let r=e[1],n=parseInt(r,16),i=r.length,a=i%4===0,s=i>4,l=s?1:17,u=s?8:4,h=a?0:-1,f=s?255:15;return ih.set({r:(n>>u*(h+3)&f)*l,g:(n>>u*(h+2)&f)*l,b:(n>>u*(h+1)&f)*l,a:a?(n&f)*l/255:1},t)},"parse"),stringify:o(t=>{let{r:e,g:r,b:n,a:i}=t;return i<1?`#${ru[Math.round(e)]}${ru[Math.round(r)]}${ru[Math.round(n)]}${ru[Math.round(i*255)]}`:`#${ru[Math.round(e)]}${ru[Math.round(r)]}${ru[Math.round(n)]}`},"stringify")},jf=u$});var V4,Sy,h$=N(()=>{"use strict";Wl();Ey();V4={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:o(t=>{let e=t.match(V4.hueRe);if(e){let[,r,n]=e;switch(n){case"grad":return jt.channel.clamp.h(parseFloat(r)*.9);case"rad":return jt.channel.clamp.h(parseFloat(r)*180/Math.PI);case"turn":return jt.channel.clamp.h(parseFloat(r)*360)}}return jt.channel.clamp.h(parseFloat(t))},"_hue2deg"),parse:o(t=>{let e=t.charCodeAt(0);if(e!==104&&e!==72)return;let r=t.match(V4.re);if(!r)return;let[,n,i,a,s,l]=r;return ih.set({h:V4._hue2deg(n),s:jt.channel.clamp.s(parseFloat(i)),l:jt.channel.clamp.l(parseFloat(a)),a:s?jt.channel.clamp.a(l?parseFloat(s)/100:parseFloat(s)):1},t)},"parse"),stringify:o(t=>{let{h:e,s:r,l:n,a:i}=t;return i<1?`hsla(${jt.lang.round(e)}, ${jt.lang.round(r)}%, ${jt.lang.round(n)}%, ${i})`:`hsl(${jt.lang.round(e)}, ${jt.lang.round(r)}%, ${jt.lang.round(n)}%)`},"stringify")},Sy=V4});var U4,HC,f$=N(()=>{"use strict";UC();U4={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:o(t=>{t=t.toLowerCase();let e=U4.colors[t];if(e)return jf.parse(e)},"parse"),stringify:o(t=>{let e=jf.stringify(t);for(let r in U4.colors)if(U4.colors[r]===e)return r},"stringify")},HC=U4});var d$,Cy,p$=N(()=>{"use strict";Wl();Ey();d$={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:o(t=>{let e=t.charCodeAt(0);if(e!==114&&e!==82)return;let r=t.match(d$.re);if(!r)return;let[,n,i,a,s,l,u,h,f]=r;return ih.set({r:jt.channel.clamp.r(i?parseFloat(n)*2.55:parseFloat(n)),g:jt.channel.clamp.g(s?parseFloat(a)*2.55:parseFloat(a)),b:jt.channel.clamp.b(u?parseFloat(l)*2.55:parseFloat(l)),a:h?jt.channel.clamp.a(f?parseFloat(h)/100:parseFloat(h)):1},t)},"parse"),stringify:o(t=>{let{r:e,g:r,b:n,a:i}=t;return i<1?`rgba(${jt.lang.round(e)}, ${jt.lang.round(r)}, ${jt.lang.round(n)}, ${jt.lang.round(i)})`:`rgb(${jt.lang.round(e)}, ${jt.lang.round(r)}, ${jt.lang.round(n)})`},"stringify")},Cy=d$});var gxe,Oi,nu=N(()=>{"use strict";UC();h$();f$();p$();ky();gxe={format:{keyword:HC,hex:jf,rgb:Cy,rgba:Cy,hsl:Sy,hsla:Sy},parse:o(t=>{if(typeof t!="string")return t;let e=jf.parse(t)||Cy.parse(t)||Sy.parse(t)||HC.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},"parse"),stringify:o(t=>!t.changed&&t.color?t.color:t.type.is(Ii.HSL)||t.data.r===void 0?Sy.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?Cy.stringify(t):jf.stringify(t),"stringify")},Oi=gxe});var yxe,H4,WC=N(()=>{"use strict";Wl();nu();yxe=o((t,e)=>{let r=Oi.parse(t);for(let n in e)r[n]=jt.channel.clamp[n](e[n]);return Oi.stringify(r)},"change"),H4=yxe});var vxe,qa,qC=N(()=>{"use strict";Wl();Ey();nu();WC();vxe=o((t,e,r=0,n=1)=>{if(typeof t!="number")return H4(t,{a:e});let i=ih.set({r:jt.channel.clamp.r(t),g:jt.channel.clamp.g(e),b:jt.channel.clamp.b(r),a:jt.channel.clamp.a(n)});return Oi.stringify(i)},"rgba"),qa=vxe});var xxe,Kf,m$=N(()=>{"use strict";Wl();nu();xxe=o((t,e)=>jt.lang.round(Oi.parse(t)[e]),"channel"),Kf=xxe});var bxe,g$,y$=N(()=>{"use strict";Wl();nu();bxe=o(t=>{let{r:e,g:r,b:n}=Oi.parse(t),i=.2126*jt.channel.toLinear(e)+.7152*jt.channel.toLinear(r)+.0722*jt.channel.toLinear(n);return jt.lang.round(i)},"luminance"),g$=bxe});var wxe,v$,x$=N(()=>{"use strict";y$();wxe=o(t=>g$(t)>=.5,"isLight"),v$=wxe});var Txe,ca,b$=N(()=>{"use strict";x$();Txe=o(t=>!v$(t),"isDark"),ca=Txe});var kxe,W4,YC=N(()=>{"use strict";Wl();nu();kxe=o((t,e,r)=>{let n=Oi.parse(t),i=n[e],a=jt.channel.clamp[e](i+r);return i!==a&&(n[e]=a),Oi.stringify(n)},"adjustChannel"),W4=kxe});var Exe,Dt,w$=N(()=>{"use strict";YC();Exe=o((t,e)=>W4(t,"l",e),"lighten"),Dt=Exe});var Sxe,Ot,T$=N(()=>{"use strict";YC();Sxe=o((t,e)=>W4(t,"l",-e),"darken"),Ot=Sxe});var Cxe,Me,k$=N(()=>{"use strict";nu();WC();Cxe=o((t,e)=>{let r=Oi.parse(t),n={};for(let i in e)e[i]&&(n[i]=r[i]+e[i]);return H4(t,n)},"adjust"),Me=Cxe});var Axe,E$,S$=N(()=>{"use strict";nu();qC();Axe=o((t,e,r=50)=>{let{r:n,g:i,b:a,a:s}=Oi.parse(t),{r:l,g:u,b:h,a:f}=Oi.parse(e),d=r/100,p=d*2-1,m=s-f,y=((p*m===-1?p:(p+m)/(1+p*m))+1)/2,v=1-y,x=n*y+l*v,b=i*y+u*v,w=a*y+h*v,C=s*d+f*(1-d);return qa(x,b,w,C)},"mix"),E$=Axe});var _xe,wt,C$=N(()=>{"use strict";nu();S$();_xe=o((t,e=100)=>{let r=Oi.parse(t);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,E$(r,t,e)},"invert"),wt=_xe});var A$=N(()=>{"use strict";qC();m$();b$();w$();T$();k$();C$()});var Ys=N(()=>{"use strict";A$()});var ah,sh,Ay=N(()=>{"use strict";ah="#ffffff",sh="#f2f2f2"});var Ti,o0=N(()=>{"use strict";Ys();Ti=o((t,e)=>e?Me(t,{s:-40,l:10}):Me(t,{s:-40,l:-10}),"mkBorder")});var jC,_$,D$=N(()=>{"use strict";Ys();Ay();o0();jC=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||Me(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||Me(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Ti(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Ti(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Ti(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Ti(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||wt(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||wt(this.tertiaryColor),this.lineColor=this.lineColor||wt(this.background),this.arrowheadColor=this.arrowheadColor||wt(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?Ot(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||Ot(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||wt(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||Dt(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.darkMode?(this.rowOdd=this.rowOdd||Ot(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||Ot(this.mainBkg,10)):(this.rowOdd=this.rowOdd||Dt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||Dt(this.mainBkg,5)),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.darkMode)for(let r=0;r<this.THEME_COLOR_LIMIT;r++)this["cScale"+r]=Ot(this["cScale"+r],75);else for(let r=0;r<this.THEME_COLOR_LIMIT;r++)this["cScale"+r]=Ot(this["cScale"+r],25);for(let r=0;r<this.THEME_COLOR_LIMIT;r++)this["cScaleInv"+r]=this["cScaleInv"+r]||wt(this["cScale"+r]);for(let r=0;r<this.THEME_COLOR_LIMIT;r++)this.darkMode?this["cScalePeer"+r]=this["cScalePeer"+r]||Dt(this["cScale"+r],10):this["cScalePeer"+r]=this["cScalePeer"+r]||Ot(this["cScale"+r],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let r=0;r<this.THEME_COLOR_LIMIT;r++)this["cScaleLabel"+r]=this["cScaleLabel"+r]||this.scaleLabelColor;let e=this.darkMode?-4:-1;for(let r=0;r<5;r++)this["surface"+r]=this["surface"+r]||Me(this.mainBkg,{h:180,s:-15,l:e*(5+r*3)}),this["surfacePeer"+r]=this["surfacePeer"+r]||Me(this.mainBkg,{h:180,s:-15,l:e*(8+r*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||Me(this.primaryColor,{h:64}),this.fillType3=this.fillType3||Me(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||Me(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||Me(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||Me(this.primaryColor,{h:128}),this.fillType7=this.fillType7||Me(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||Me(this.primaryColor,{l:-10}),this.pie5=this.pie5||Me(this.secondaryColor,{l:-10}),this.pie6=this.pie6||Me(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||Me(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||Me(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||Me(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||Me(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||Me(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||Me(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.archEdgeColor=this.archEdgeColor||"#777",this.archEdgeArrowColor=this.archEdgeArrowColor||"#777",this.archEdgeWidth=this.archEdgeWidth||"3",this.archGroupBorderColor=this.archGroupBorderColor||"#000",this.archGroupBorderWidth=this.archGroupBorderWidth||"2px",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||Me(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||Me(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||Me(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||Me(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||Me(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||Me(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ca(this.quadrant1Fill)?Dt(this.quadrant1Fill):Ot(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?Ot(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||Me(this.primaryColor,{h:-30}),this.git4=this.git4||Me(this.primaryColor,{h:-60}),this.git5=this.git5||Me(this.primaryColor,{h:-90}),this.git6=this.git6||Me(this.primaryColor,{h:60}),this.git7=this.git7||Me(this.primaryColor,{h:120}),this.darkMode?(this.git0=Dt(this.git0,25),this.git1=Dt(this.git1,25),this.git2=Dt(this.git2,25),this.git3=Dt(this.git3,25),this.git4=Dt(this.git4,25),this.git5=Dt(this.git5,25),this.git6=Dt(this.git6,25),this.git7=Dt(this.git7,25)):(this.git0=Ot(this.git0,25),this.git1=Ot(this.git1,25),this.git2=Ot(this.git2,25),this.git3=Ot(this.git3,25),this.git4=Ot(this.git4,25),this.git5=Ot(this.git5,25),this.git6=Ot(this.git6,25),this.git7=Ot(this.git7,25)),this.gitInv0=this.gitInv0||wt(this.git0),this.gitInv1=this.gitInv1||wt(this.git1),this.gitInv2=this.gitInv2||wt(this.git2),this.gitInv3=this.gitInv3||wt(this.git3),this.gitInv4=this.gitInv4||wt(this.git4),this.gitInv5=this.gitInv5||wt(this.git5),this.gitInv6=this.gitInv6||wt(this.git6),this.gitInv7=this.gitInv7||wt(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||ah,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||sh}calculate(e){if(typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},_$=o(t=>{let e=new jC;return e.calculate(t),e},"getThemeVariables")});var KC,L$,R$=N(()=>{"use strict";Ys();o0();KC=class{static{o(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=Dt(this.primaryColor,16),this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=wt(this.background),this.secondaryBorderColor=Ti(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Ti(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=Dt(wt("#323D47"),10),this.lineColor="calculated",this.border1="#ccc",this.border2=qa(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=Ot("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=Ot(this.sectionBkgColor,10),this.taskBorderColor=qa(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=qa(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||Dt(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||Ot(this.mainBkg,10),this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=Dt(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=Dt(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.actorBorder,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=Dt(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=Me(this.primaryColor,{h:64}),this.fillType3=Me(this.secondaryColor,{h:64}),this.fillType4=Me(this.primaryColor,{h:-64}),this.fillType5=Me(this.secondaryColor,{h:-64}),this.fillType6=Me(this.primaryColor,{h:128}),this.fillType7=Me(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330});for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||wt(this["cScale"+e]);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScalePeer"+e]=this["cScalePeer"+e]||Dt(this["cScale"+e],10);for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||Me(this.mainBkg,{h:30,s:-30,l:-(-10+e*4)}),this["surfacePeer"+e]=this["surfacePeer"+e]||Me(this.mainBkg,{h:30,s:-30,l:-(-7+e*4)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["pie"+e]=this["cScale"+e];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||Me(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||Me(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||Me(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||Me(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||Me(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||Me(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ca(this.quadrant1Fill)?Dt(this.quadrant1Fill):Ot(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.background},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?Ot(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=Dt(this.secondaryColor,20),this.git1=Dt(this.pie2||this.secondaryColor,20),this.git2=Dt(this.pie3||this.tertiaryColor,20),this.git3=Dt(this.pie4||Me(this.primaryColor,{h:-30}),20),this.git4=Dt(this.pie5||Me(this.primaryColor,{h:-60}),20),this.git5=Dt(this.pie6||Me(this.primaryColor,{h:-90}),10),this.git6=Dt(this.pie7||Me(this.primaryColor,{h:60}),10),this.git7=Dt(this.pie8||Me(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||wt(this.git0),this.gitInv1=this.gitInv1||wt(this.git1),this.gitInv2=this.gitInv2||wt(this.git2),this.gitInv3=this.gitInv3||wt(this.git3),this.gitInv4=this.gitInv4||wt(this.git4),this.gitInv5=this.gitInv5||wt(this.git5),this.gitInv6=this.gitInv6||wt(this.git6),this.gitInv7=this.gitInv7||wt(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||wt(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||wt(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Dt(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Dt(this.background,2),this.nodeBorder=this.nodeBorder||"#999"}calculate(e){if(typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},L$=o(t=>{let e=new KC;return e.calculate(t),e},"getThemeVariables")});var QC,oh,_y=N(()=>{"use strict";Ys();o0();Ay();QC=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=Me(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=Ti(this.primaryColor,this.darkMode),this.secondaryBorderColor=Ti(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Ti(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="rgba(232,232,232, 0.8)",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=qa(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd="calculated",this.rowEven="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||Ot(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||Ot(this.tertiaryColor,40);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=Ot(this["cScale"+e],10),this["cScalePeer"+e]=this["cScalePeer"+e]||Ot(this["cScale"+e],25);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||Me(this["cScale"+e],{h:180});for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||Me(this.mainBkg,{h:30,l:-(5+e*5)}),this["surfacePeer"+e]=this["surfacePeer"+e]||Me(this.mainBkg,{h:30,l:-(7+e*5)});if(this.scaleLabelColor=this.scaleLabelColor!=="calculated"&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,this.labelTextColor!=="calculated"){this.cScaleLabel0=this.cScaleLabel0||wt(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||wt(this.labelTextColor);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=Dt(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.rowOdd=this.rowOdd||Dt(this.primaryColor,75)||"#ffffff",this.rowEven=this.rowEven||Dt(this.primaryColor,1),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=Me(this.primaryColor,{h:64}),this.fillType3=Me(this.secondaryColor,{h:64}),this.fillType4=Me(this.primaryColor,{h:-64}),this.fillType5=Me(this.secondaryColor,{h:-64}),this.fillType6=Me(this.primaryColor,{h:128}),this.fillType7=Me(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||Me(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||Me(this.primaryColor,{l:-10}),this.pie5=this.pie5||Me(this.secondaryColor,{l:-30}),this.pie6=this.pie6||Me(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||Me(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||Me(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||Me(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||Me(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||Me(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||Me(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||Me(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||Me(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||Me(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||Me(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||Me(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||Me(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ca(this.quadrant1Fill)?Dt(this.quadrant1Fill):Ot(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||Me(this.primaryColor,{h:-30}),this.git4=this.git4||Me(this.primaryColor,{h:-60}),this.git5=this.git5||Me(this.primaryColor,{h:-90}),this.git6=this.git6||Me(this.primaryColor,{h:60}),this.git7=this.git7||Me(this.primaryColor,{h:120}),this.darkMode?(this.git0=Dt(this.git0,25),this.git1=Dt(this.git1,25),this.git2=Dt(this.git2,25),this.git3=Dt(this.git3,25),this.git4=Dt(this.git4,25),this.git5=Dt(this.git5,25),this.git6=Dt(this.git6,25),this.git7=Dt(this.git7,25)):(this.git0=Ot(this.git0,25),this.git1=Ot(this.git1,25),this.git2=Ot(this.git2,25),this.git3=Ot(this.git3,25),this.git4=Ot(this.git4,25),this.git5=Ot(this.git5,25),this.git6=Ot(this.git6,25),this.git7=Ot(this.git7,25)),this.gitInv0=this.gitInv0||Ot(wt(this.git0),25),this.gitInv1=this.gitInv1||wt(this.git1),this.gitInv2=this.gitInv2||wt(this.git2),this.gitInv3=this.gitInv3||wt(this.git3),this.gitInv4=this.gitInv4||wt(this.git4),this.gitInv5=this.gitInv5||wt(this.git5),this.gitInv6=this.gitInv6||wt(this.git6),this.gitInv7=this.gitInv7||wt(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||wt(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||wt(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||ah,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||sh}calculate(e){if(Object.keys(this).forEach(n=>{this[n]==="calculated"&&(this[n]=void 0)}),typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},oh=o(t=>{let e=new QC;return e.calculate(t),e},"getThemeVariables")});var ZC,N$,M$=N(()=>{"use strict";Ys();Ay();o0();ZC=class{static{o(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=Dt("#cde498",10),this.primaryBorderColor=Ti(this.primaryColor,this.darkMode),this.secondaryBorderColor=Ti(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Ti(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.primaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.actorBorder=Ot(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||Me(this.primaryColor,{h:30}),this.cScale4=this.cScale4||Me(this.primaryColor,{h:60}),this.cScale5=this.cScale5||Me(this.primaryColor,{h:90}),this.cScale6=this.cScale6||Me(this.primaryColor,{h:120}),this.cScale7=this.cScale7||Me(this.primaryColor,{h:150}),this.cScale8=this.cScale8||Me(this.primaryColor,{h:210}),this.cScale9=this.cScale9||Me(this.primaryColor,{h:270}),this.cScale10=this.cScale10||Me(this.primaryColor,{h:300}),this.cScale11=this.cScale11||Me(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||Ot(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||Ot(this.tertiaryColor,40);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=Ot(this["cScale"+e],10),this["cScalePeer"+e]=this["cScalePeer"+e]||Ot(this["cScale"+e],25);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||Me(this["cScale"+e],{h:180});this.scaleLabelColor=this.scaleLabelColor!=="calculated"&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||Me(this.mainBkg,{h:30,s:-30,l:-(5+e*5)}),this["surfacePeer"+e]=this["surfacePeer"+e]||Me(this.mainBkg,{h:30,s:-30,l:-(8+e*5)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.rowOdd=this.rowOdd||Dt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||Dt(this.mainBkg,20),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=Me(this.primaryColor,{h:64}),this.fillType3=Me(this.secondaryColor,{h:64}),this.fillType4=Me(this.primaryColor,{h:-64}),this.fillType5=Me(this.secondaryColor,{h:-64}),this.fillType6=Me(this.primaryColor,{h:128}),this.fillType7=Me(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||Me(this.primaryColor,{l:-30}),this.pie5=this.pie5||Me(this.secondaryColor,{l:-30}),this.pie6=this.pie6||Me(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||Me(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||Me(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||Me(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||Me(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||Me(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||Me(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||Me(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||Me(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||Me(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||Me(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||Me(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||Me(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ca(this.quadrant1Fill)?Dt(this.quadrant1Fill):Ot(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.mainBkg},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||Me(this.primaryColor,{h:-30}),this.git4=this.git4||Me(this.primaryColor,{h:-60}),this.git5=this.git5||Me(this.primaryColor,{h:-90}),this.git6=this.git6||Me(this.primaryColor,{h:60}),this.git7=this.git7||Me(this.primaryColor,{h:120}),this.darkMode?(this.git0=Dt(this.git0,25),this.git1=Dt(this.git1,25),this.git2=Dt(this.git2,25),this.git3=Dt(this.git3,25),this.git4=Dt(this.git4,25),this.git5=Dt(this.git5,25),this.git6=Dt(this.git6,25),this.git7=Dt(this.git7,25)):(this.git0=Ot(this.git0,25),this.git1=Ot(this.git1,25),this.git2=Ot(this.git2,25),this.git3=Ot(this.git3,25),this.git4=Ot(this.git4,25),this.git5=Ot(this.git5,25),this.git6=Ot(this.git6,25),this.git7=Ot(this.git7,25)),this.gitInv0=this.gitInv0||wt(this.git0),this.gitInv1=this.gitInv1||wt(this.git1),this.gitInv2=this.gitInv2||wt(this.git2),this.gitInv3=this.gitInv3||wt(this.git3),this.gitInv4=this.gitInv4||wt(this.git4),this.gitInv5=this.gitInv5||wt(this.git5),this.gitInv6=this.gitInv6||wt(this.git6),this.gitInv7=this.gitInv7||wt(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||wt(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||wt(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||ah,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||sh}calculate(e){if(typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},N$=o(t=>{let e=new ZC;return e.calculate(t),e},"getThemeVariables")});var JC,I$,O$=N(()=>{"use strict";Ys();o0();Ay();JC=class{static{o(this,"Theme")}constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=Dt(this.contrast,55),this.background="#ffffff",this.tertiaryColor=Me(this.primaryColor,{h:-160}),this.primaryBorderColor=Ti(this.primaryColor,this.darkMode),this.secondaryBorderColor=Ti(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Ti(this.tertiaryColor,this.darkMode),this.primaryTextColor=wt(this.primaryColor),this.secondaryTextColor=wt(this.secondaryColor),this.tertiaryTextColor=wt(this.tertiaryColor),this.lineColor=wt(this.background),this.textColor=wt(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor=this.actorBorder,this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||Dt(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||"#f4f4f4",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=Dt(this.contrast,55),this.border2=this.contrast,this.actorBorder=Dt(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.actorBorder,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||wt(this["cScale"+e]);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this.darkMode?this["cScalePeer"+e]=this["cScalePeer"+e]||Dt(this["cScale"+e],10):this["cScalePeer"+e]=this["cScalePeer"+e]||Ot(this["cScale"+e],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||Me(this.mainBkg,{l:-(5+e*5)}),this["surfacePeer"+e]=this["surfacePeer"+e]||Me(this.mainBkg,{l:-(8+e*5)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=Dt(this.contrast,30),this.sectionBkgColor2=Dt(this.contrast,30),this.taskBorderColor=Ot(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=Dt(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=Ot(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=Me(this.primaryColor,{h:64}),this.fillType3=Me(this.secondaryColor,{h:64}),this.fillType4=Me(this.primaryColor,{h:-64}),this.fillType5=Me(this.secondaryColor,{h:-64}),this.fillType6=Me(this.primaryColor,{h:128}),this.fillType7=Me(this.secondaryColor,{h:128});for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["pie"+e]=this["cScale"+e];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||Me(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||Me(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||Me(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||Me(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||Me(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||Me(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ca(this.quadrant1Fill)?Dt(this.quadrant1Fill):Ot(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=Ot(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||Me(this.primaryColor,{h:-30}),this.git4=this.pie5||Me(this.primaryColor,{h:-60}),this.git5=this.pie6||Me(this.primaryColor,{h:-90}),this.git6=this.pie7||Me(this.primaryColor,{h:60}),this.git7=this.pie8||Me(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||wt(this.git0),this.gitInv1=this.gitInv1||wt(this.git1),this.gitInv2=this.gitInv2||wt(this.git2),this.gitInv3=this.gitInv3||wt(this.git3),this.gitInv4=this.gitInv4||wt(this.git4),this.gitInv5=this.gitInv5||wt(this.git5),this.gitInv6=this.gitInv6||wt(this.git6),this.gitInv7=this.gitInv7||wt(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||ah,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||sh}calculate(e){if(typeof e!="object"){this.updateColors();return}let r=Object.keys(e);r.forEach(n=>{this[n]=e[n]}),this.updateColors(),r.forEach(n=>{this[n]=e[n]})}},I$=o(t=>{let e=new JC;return e.calculate(t),e},"getThemeVariables")});var To,q4=N(()=>{"use strict";D$();R$();_y();M$();O$();To={base:{getThemeVariables:_$},dark:{getThemeVariables:L$},default:{getThemeVariables:oh},forest:{getThemeVariables:N$},neutral:{getThemeVariables:I$}}});var ql,P$=N(()=>{"use strict";ql={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1,hideEmptyMembersBox:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,nodeSpacing:140,rankSpacing:80,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},kanban:{useMaxWidth:!0,padding:8,sectionWidth:200,ticketBaseUrl:""},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},packet:{useMaxWidth:!0,rowHeight:32,bitWidth:32,bitsPerRow:32,showBits:!0,paddingX:5,paddingY:5},architecture:{useMaxWidth:!0,padding:40,iconSize:80,fontSize:16},radar:{useMaxWidth:!0,width:600,height:600,marginTop:50,marginRight:50,marginBottom:50,marginLeft:50,axisScaleFactor:1,axisLabelFactor:1.05,curveTension:.17},theme:"default",look:"classic",handDrawnSeed:0,layout:"dagre",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","suppressErrorRendering","maxEdges"],legacyMathML:!1,forceLegacyMathML:!1,deterministicIds:!1,fontSize:16,markdownAutoWrap:!0,suppressErrorRendering:!1}});var B$,F$,$$,or,Ya=N(()=>{"use strict";q4();P$();B$={...ql,deterministicIDSeed:void 0,elk:{mergeEdges:!1,nodePlacementStrategy:"BRANDES_KOEPF"},themeCSS:void 0,themeVariables:To.default.getThemeVariables(),sequence:{...ql.sequence,messageFont:o(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont"),noteFont:o(function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},"noteFont"),actorFont:o(function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}},"actorFont")},class:{hideEmptyMembersBox:!1},gantt:{...ql.gantt,tickInterval:void 0,useWidth:void 0},c4:{...ql.c4,useWidth:void 0,personFont:o(function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},"personFont"),external_personFont:o(function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},"external_personFont"),systemFont:o(function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},"systemFont"),external_systemFont:o(function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},"external_systemFont"),system_dbFont:o(function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},"system_dbFont"),external_system_dbFont:o(function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},"external_system_dbFont"),system_queueFont:o(function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},"system_queueFont"),external_system_queueFont:o(function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},"external_system_queueFont"),containerFont:o(function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},"containerFont"),external_containerFont:o(function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},"external_containerFont"),container_dbFont:o(function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},"container_dbFont"),external_container_dbFont:o(function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},"external_container_dbFont"),container_queueFont:o(function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},"container_queueFont"),external_container_queueFont:o(function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},"external_container_queueFont"),componentFont:o(function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},"componentFont"),external_componentFont:o(function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},"external_componentFont"),component_dbFont:o(function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},"component_dbFont"),external_component_dbFont:o(function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},"external_component_dbFont"),component_queueFont:o(function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},"component_queueFont"),external_component_queueFont:o(function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},"external_component_queueFont"),boundaryFont:o(function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},"boundaryFont"),messageFont:o(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont")},pie:{...ql.pie,useWidth:984},xyChart:{...ql.xyChart,useWidth:void 0},requirement:{...ql.requirement,useWidth:void 0},packet:{...ql.packet},radar:{...ql.radar}},F$=o((t,e="")=>Object.keys(t).reduce((r,n)=>Array.isArray(t[n])?r:typeof t[n]=="object"&&t[n]!==null?[...r,e+n,...F$(t[n],"")]:[...r,e+n],[]),"keyify"),$$=new Set(F$(B$,"")),or=B$});var l0,Dxe,e7=N(()=>{"use strict";Ya();vt();l0=o(t=>{if(Y.debug("sanitizeDirective called with",t),!(typeof t!="object"||t==null)){if(Array.isArray(t)){t.forEach(e=>l0(e));return}for(let e of Object.keys(t)){if(Y.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!$$.has(e)||t[e]==null){Y.debug("sanitize deleting key: ",e),delete t[e];continue}if(typeof t[e]=="object"){Y.debug("sanitizing object",e),l0(t[e]);continue}let r=["themeCSS","fontFamily","altFontFamily"];for(let n of r)e.includes(n)&&(Y.debug("sanitizing css option",e),t[e]=Dxe(t[e]))}if(t.themeVariables)for(let e of Object.keys(t.themeVariables)){let r=t.themeVariables[e];r?.match&&!r.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}Y.debug("After sanitization",t)}},"sanitizeDirective"),Dxe=o(t=>{let e=0,r=0;for(let n of t){if(e<r)return"{ /* ERROR: Unbalanced CSS */ }";n==="{"?e++:n==="}"&&r++}return e!==r?"{ /* ERROR: Unbalanced CSS */ }":t},"sanitizeCss")});var lh,xs,G$,c0,Dy,Y4,t7,V$,U$,r7,X4,cr,H$,W$,Ly,Lxe,z$,Rxe,q$,ji=N(()=>{"use strict";s0();vt();q4();Ya();e7();lh=Object.freeze(or),xs=Gn({},lh),c0=[],Dy=Gn({},lh),Y4=o((t,e)=>{let r=Gn({},t),n={};for(let i of e)H$(i),n=Gn(n,i);if(r=Gn(r,n),n.theme&&n.theme in To){let i=Gn({},G$),a=Gn(i.themeVariables||{},n.themeVariables);r.theme&&r.theme in To&&(r.themeVariables=To[r.theme].getThemeVariables(a))}return Dy=r,q$(Dy),Dy},"updateCurrentConfig"),t7=o(t=>(xs=Gn({},lh),xs=Gn(xs,t),t.theme&&To[t.theme]&&(xs.themeVariables=To[t.theme].getThemeVariables(t.themeVariables)),Y4(xs,c0),xs),"setSiteConfig"),V$=o(t=>{G$=Gn({},t)},"saveConfigFromInitialize"),U$=o(t=>(xs=Gn(xs,t),Y4(xs,c0),xs),"updateSiteConfig"),r7=o(()=>Gn({},xs),"getSiteConfig"),X4=o(t=>(q$(t),Gn(Dy,t),cr()),"setConfig"),cr=o(()=>Gn({},Dy),"getConfig"),H$=o(t=>{t&&(["secure",...xs.secure??[]].forEach(e=>{Object.hasOwn(t,e)&&(Y.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])}),Object.keys(t).forEach(e=>{e.startsWith("__")&&delete t[e]}),Object.keys(t).forEach(e=>{typeof t[e]=="string"&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],typeof t[e]=="object"&&H$(t[e])}))},"sanitize"),W$=o(t=>{l0(t),t.fontFamily&&!t.themeVariables?.fontFamily&&(t.themeVariables={...t.themeVariables,fontFamily:t.fontFamily}),c0.push(t),Y4(xs,c0)},"addDirective"),Ly=o((t=xs)=>{c0=[],Y4(t,c0)},"reset"),Lxe={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},z$={},Rxe=o(t=>{z$[t]||(Y.warn(Lxe[t]),z$[t]=!0)},"issueWarning"),q$=o(t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&Rxe("LAZY_LOAD_DEPRECATED")},"checkConfig")});function Ka(t){return function(e){for(var r=arguments.length,n=new Array(r>1?r-1:0),i=1;i<r;i++)n[i-1]=arguments[i];return l7(t,e,n)}}function $xe(t){return function(){for(var e=arguments.length,r=new Array(e),n=0;n<e;n++)r[n]=arguments[n];return c7(t,r)}}function Cr(t,e){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Q4;Y$&&Y$(t,null);let n=e.length;for(;n--;){let i=e[n];if(typeof i=="string"){let a=r(i);a!==i&&(Nxe(e)||(e[n]=a),i=a)}t[i]=!0}return t}function zxe(t){for(let e=0;e<t.length;e++)sl(t,e)||(t[e]=null);return t}function Qf(t){let e=nz(null);for(let[r,n]of rz(t))sl(t,r)&&(Array.isArray(n)?e[r]=zxe(n):n&&typeof n=="object"&&n.constructor===Object?e[r]=Qf(n):e[r]=n);return e}function Iy(t,e){for(;t!==null;){let n=Ixe(t,e);if(n){if(n.get)return Ka(n.get);if(typeof n.value=="function")return Ka(n.value)}t=Mxe(t)}function r(){return null}return o(r,"fallbackValue"),r}function sz(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Qxe(),e=o(At=>sz(At),"DOMPurify");if(e.version="3.2.4",e.removed=[],!t||!t.document||t.document.nodeType!==Oy.document||!t.Element)return e.isSupported=!1,e;let{document:r}=t,n=r,i=n.currentScript,{DocumentFragment:a,HTMLTemplateElement:s,Node:l,Element:u,NodeFilter:h,NamedNodeMap:f=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:d,DOMParser:p,trustedTypes:m}=t,g=u.prototype,y=Iy(g,"cloneNode"),v=Iy(g,"remove"),x=Iy(g,"nextSibling"),b=Iy(g,"childNodes"),w=Iy(g,"parentNode");if(typeof s=="function"){let At=r.createElement("template");At.content&&At.content.ownerDocument&&(r=At.content.ownerDocument)}let C,T="",{implementation:E,createNodeIterator:A,createDocumentFragment:S,getElementsByTagName:_}=r,{importNode:I}=n,D=tz();e.isSupported=typeof rz=="function"&&typeof w=="function"&&E&&E.createHTMLDocument!==void 0;let{MUSTACHE_EXPR:k,ERB_EXPR:L,TMPLIT_EXPR:R,DATA_ATTR:O,ARIA_ATTR:M,IS_SCRIPT_OR_DATA:B,ATTR_WHITESPACE:F,CUSTOM_ELEMENT:P}=ez,{IS_ALLOWED_URI:z}=ez,$=null,H=Cr({},[...K$,...i7,...a7,...s7,...Q$]),Q=null,j=Cr({},[...Z$,...o7,...J$,...K4]),ie=Object.seal(nz(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ne=null,le=null,he=!0,K=!0,X=!1,te=!0,J=!1,se=!0,ue=!1,Z=!1,Se=!1,ce=!1,ae=!1,Oe=!1,ge=!0,ze=!1,He="user-content-",$e=!0,Re=!1,Ie={},be=null,W=Cr({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),de=null,re=Cr({},["audio","video","img","source","image","track"]),oe=null,V=Cr({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),xe="http://www.w3.org/1998/Math/MathML",q="http://www.w3.org/2000/svg",pe="http://www.w3.org/1999/xhtml",ve=pe,Pe=!1,_e=null,we=Cr({},[xe,q,pe],n7),Ve=Cr({},["mi","mo","mn","ms","mtext"]),De=Cr({},["annotation-xml"]),qe=Cr({},["title","style","font","a","script"]),at=null,Rt=["application/xhtml+xml","text/html"],st="text/html",Ue=null,ct=null,We=r.createElement("form"),ot=o(function(Ce){return Ce instanceof RegExp||Ce instanceof Function},"isRegexOrFunction"),Yt=o(function(){let Ce=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(ct&&ct===Ce)){if((!Ce||typeof Ce!="object")&&(Ce={}),Ce=Qf(Ce),at=Rt.indexOf(Ce.PARSER_MEDIA_TYPE)===-1?st:Ce.PARSER_MEDIA_TYPE,Ue=at==="application/xhtml+xml"?n7:Q4,$=sl(Ce,"ALLOWED_TAGS")?Cr({},Ce.ALLOWED_TAGS,Ue):H,Q=sl(Ce,"ALLOWED_ATTR")?Cr({},Ce.ALLOWED_ATTR,Ue):j,_e=sl(Ce,"ALLOWED_NAMESPACES")?Cr({},Ce.ALLOWED_NAMESPACES,n7):we,oe=sl(Ce,"ADD_URI_SAFE_ATTR")?Cr(Qf(V),Ce.ADD_URI_SAFE_ATTR,Ue):V,de=sl(Ce,"ADD_DATA_URI_TAGS")?Cr(Qf(re),Ce.ADD_DATA_URI_TAGS,Ue):re,be=sl(Ce,"FORBID_CONTENTS")?Cr({},Ce.FORBID_CONTENTS,Ue):W,ne=sl(Ce,"FORBID_TAGS")?Cr({},Ce.FORBID_TAGS,Ue):{},le=sl(Ce,"FORBID_ATTR")?Cr({},Ce.FORBID_ATTR,Ue):{},Ie=sl(Ce,"USE_PROFILES")?Ce.USE_PROFILES:!1,he=Ce.ALLOW_ARIA_ATTR!==!1,K=Ce.ALLOW_DATA_ATTR!==!1,X=Ce.ALLOW_UNKNOWN_PROTOCOLS||!1,te=Ce.ALLOW_SELF_CLOSE_IN_ATTR!==!1,J=Ce.SAFE_FOR_TEMPLATES||!1,se=Ce.SAFE_FOR_XML!==!1,ue=Ce.WHOLE_DOCUMENT||!1,ce=Ce.RETURN_DOM||!1,ae=Ce.RETURN_DOM_FRAGMENT||!1,Oe=Ce.RETURN_TRUSTED_TYPE||!1,Se=Ce.FORCE_BODY||!1,ge=Ce.SANITIZE_DOM!==!1,ze=Ce.SANITIZE_NAMED_PROPS||!1,$e=Ce.KEEP_CONTENT!==!1,Re=Ce.IN_PLACE||!1,z=Ce.ALLOWED_URI_REGEXP||iz,ve=Ce.NAMESPACE||pe,Ve=Ce.MATHML_TEXT_INTEGRATION_POINTS||Ve,De=Ce.HTML_INTEGRATION_POINTS||De,ie=Ce.CUSTOM_ELEMENT_HANDLING||{},Ce.CUSTOM_ELEMENT_HANDLING&&ot(Ce.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(ie.tagNameCheck=Ce.CUSTOM_ELEMENT_HANDLING.tagNameCheck),Ce.CUSTOM_ELEMENT_HANDLING&&ot(Ce.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(ie.attributeNameCheck=Ce.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),Ce.CUSTOM_ELEMENT_HANDLING&&typeof Ce.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(ie.allowCustomizedBuiltInElements=Ce.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),J&&(K=!1),ae&&(ce=!0),Ie&&($=Cr({},Q$),Q=[],Ie.html===!0&&(Cr($,K$),Cr(Q,Z$)),Ie.svg===!0&&(Cr($,i7),Cr(Q,o7),Cr(Q,K4)),Ie.svgFilters===!0&&(Cr($,a7),Cr(Q,o7),Cr(Q,K4)),Ie.mathMl===!0&&(Cr($,s7),Cr(Q,J$),Cr(Q,K4))),Ce.ADD_TAGS&&($===H&&($=Qf($)),Cr($,Ce.ADD_TAGS,Ue)),Ce.ADD_ATTR&&(Q===j&&(Q=Qf(Q)),Cr(Q,Ce.ADD_ATTR,Ue)),Ce.ADD_URI_SAFE_ATTR&&Cr(oe,Ce.ADD_URI_SAFE_ATTR,Ue),Ce.FORBID_CONTENTS&&(be===W&&(be=Qf(be)),Cr(be,Ce.FORBID_CONTENTS,Ue)),$e&&($["#text"]=!0),ue&&Cr($,["html","head","body"]),$.table&&(Cr($,["tbody"]),delete ne.tbody),Ce.TRUSTED_TYPES_POLICY){if(typeof Ce.TRUSTED_TYPES_POLICY.createHTML!="function")throw My('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof Ce.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw My('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');C=Ce.TRUSTED_TYPES_POLICY,T=C.createHTML("")}else C===void 0&&(C=Zxe(m,i)),C!==null&&typeof T=="string"&&(T=C.createHTML(""));ja&&ja(Ce),ct=Ce}},"_parseConfig"),bt=Cr({},[...i7,...a7,...Gxe]),Mt=Cr({},[...s7,...Vxe]),xt=o(function(Ce){let tt=w(Ce);(!tt||!tt.tagName)&&(tt={namespaceURI:ve,tagName:"template"});let St=Q4(Ce.tagName),mr=Q4(tt.tagName);return _e[Ce.namespaceURI]?Ce.namespaceURI===q?tt.namespaceURI===pe?St==="svg":tt.namespaceURI===xe?St==="svg"&&(mr==="annotation-xml"||Ve[mr]):!!bt[St]:Ce.namespaceURI===xe?tt.namespaceURI===pe?St==="math":tt.namespaceURI===q?St==="math"&&De[mr]:!!Mt[St]:Ce.namespaceURI===pe?tt.namespaceURI===q&&!De[mr]||tt.namespaceURI===xe&&!Ve[mr]?!1:!Mt[St]&&(qe[St]||!bt[St]):!!(at==="application/xhtml+xml"&&_e[Ce.namespaceURI]):!1},"_checkValidNamespace"),ut=o(function(Ce){Ry(e.removed,{element:Ce});try{w(Ce).removeChild(Ce)}catch{v(Ce)}},"_forceRemove"),Et=o(function(Ce,tt){try{Ry(e.removed,{attribute:tt.getAttributeNode(Ce),from:tt})}catch{Ry(e.removed,{attribute:null,from:tt})}if(tt.removeAttribute(Ce),Ce==="is")if(ce||ae)try{ut(tt)}catch{}else try{tt.setAttribute(Ce,"")}catch{}},"_removeAttribute"),ft=o(function(Ce){let tt=null,St=null;if(Se)Ce="<remove></remove>"+Ce;else{let gn=j$(Ce,/^[\r\n\t ]+/);St=gn&&gn[0]}at==="application/xhtml+xml"&&ve===pe&&(Ce='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+Ce+"</body></html>");let mr=C?C.createHTML(Ce):Ce;if(ve===pe)try{tt=new p().parseFromString(mr,at)}catch{}if(!tt||!tt.documentElement){tt=E.createDocument(ve,"template",null);try{tt.documentElement.innerHTML=Pe?T:mr}catch{}}let rn=tt.body||tt.documentElement;return Ce&&St&&rn.insertBefore(r.createTextNode(St),rn.childNodes[0]||null),ve===pe?_.call(tt,ue?"html":"body")[0]:ue?tt.documentElement:rn},"_initDocument"),yt=o(function(Ce){return A.call(Ce.ownerDocument||Ce,Ce,h.SHOW_ELEMENT|h.SHOW_COMMENT|h.SHOW_TEXT|h.SHOW_PROCESSING_INSTRUCTION|h.SHOW_CDATA_SECTION,null)},"_createNodeIterator"),nt=o(function(Ce){return Ce instanceof d&&(typeof Ce.nodeName!="string"||typeof Ce.textContent!="string"||typeof Ce.removeChild!="function"||!(Ce.attributes instanceof f)||typeof Ce.removeAttribute!="function"||typeof Ce.setAttribute!="function"||typeof Ce.namespaceURI!="string"||typeof Ce.insertBefore!="function"||typeof Ce.hasChildNodes!="function")},"_isClobbered"),dn=o(function(Ce){return typeof l=="function"&&Ce instanceof l},"_isNode");function Tt(At,Ce,tt){j4(At,St=>{St.call(e,Ce,tt,ct)})}o(Tt,"_executeHooks");let On=o(function(Ce){let tt=null;if(Tt(D.beforeSanitizeElements,Ce,null),nt(Ce))return ut(Ce),!0;let St=Ue(Ce.nodeName);if(Tt(D.uponSanitizeElement,Ce,{tagName:St,allowedTags:$}),Ce.hasChildNodes()&&!dn(Ce.firstElementChild)&&Xa(/<[/\w]/g,Ce.innerHTML)&&Xa(/<[/\w]/g,Ce.textContent)||Ce.nodeType===Oy.progressingInstruction||se&&Ce.nodeType===Oy.comment&&Xa(/<[/\w]/g,Ce.data))return ut(Ce),!0;if(!$[St]||ne[St]){if(!ne[St]&&_r(St)&&(ie.tagNameCheck instanceof RegExp&&Xa(ie.tagNameCheck,St)||ie.tagNameCheck instanceof Function&&ie.tagNameCheck(St)))return!1;if($e&&!be[St]){let mr=w(Ce)||Ce.parentNode,rn=b(Ce)||Ce.childNodes;if(rn&&mr){let gn=rn.length;for(let Zr=gn-1;Zr>=0;--Zr){let Ni=y(rn[Zr],!0);Ni.__removalCount=(Ce.__removalCount||0)+1,mr.insertBefore(Ni,x(Ce))}}}return ut(Ce),!0}return Ce instanceof u&&!xt(Ce)||(St==="noscript"||St==="noembed"||St==="noframes")&&Xa(/<\/no(script|embed|frames)/i,Ce.innerHTML)?(ut(Ce),!0):(J&&Ce.nodeType===Oy.text&&(tt=Ce.textContent,j4([k,L,R],mr=>{tt=Ny(tt,mr," ")}),Ce.textContent!==tt&&(Ry(e.removed,{element:Ce.cloneNode()}),Ce.textContent=tt)),Tt(D.afterSanitizeElements,Ce,null),!1)},"_sanitizeElements"),tn=o(function(Ce,tt,St){if(ge&&(tt==="id"||tt==="name")&&(St in r||St in We))return!1;if(!(K&&!le[tt]&&Xa(O,tt))){if(!(he&&Xa(M,tt))){if(!Q[tt]||le[tt]){if(!(_r(Ce)&&(ie.tagNameCheck instanceof RegExp&&Xa(ie.tagNameCheck,Ce)||ie.tagNameCheck instanceof Function&&ie.tagNameCheck(Ce))&&(ie.attributeNameCheck instanceof RegExp&&Xa(ie.attributeNameCheck,tt)||ie.attributeNameCheck instanceof Function&&ie.attributeNameCheck(tt))||tt==="is"&&ie.allowCustomizedBuiltInElements&&(ie.tagNameCheck instanceof RegExp&&Xa(ie.tagNameCheck,St)||ie.tagNameCheck instanceof Function&&ie.tagNameCheck(St))))return!1}else if(!oe[tt]){if(!Xa(z,Ny(St,F,""))){if(!((tt==="src"||tt==="xlink:href"||tt==="href")&&Ce!=="script"&&Bxe(St,"data:")===0&&de[Ce])){if(!(X&&!Xa(B,Ny(St,F,"")))){if(St)return!1}}}}}}return!0},"_isValidAttribute"),_r=o(function(Ce){return Ce!=="annotation-xml"&&j$(Ce,P)},"_isBasicCustomElement"),Dr=o(function(Ce){Tt(D.beforeSanitizeAttributes,Ce,null);let{attributes:tt}=Ce;if(!tt||nt(Ce))return;let St={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Q,forceKeepAttr:void 0},mr=tt.length;for(;mr--;){let rn=tt[mr],{name:gn,namespaceURI:Zr,value:Ni}=rn,Zn=Ue(gn),Sn=gn==="value"?Ni:Fxe(Ni);if(St.attrName=Zn,St.attrValue=Sn,St.keepAttr=!0,St.forceKeepAttr=void 0,Tt(D.uponSanitizeAttribute,Ce,St),Sn=St.attrValue,ze&&(Zn==="id"||Zn==="name")&&(Et(gn,Ce),Sn=He+Sn),se&&Xa(/((--!?|])>)|<\/(style|title)/i,Sn)){Et(gn,Ce);continue}if(St.forceKeepAttr||(Et(gn,Ce),!St.keepAttr))continue;if(!te&&Xa(/\/>/i,Sn)){Et(gn,Ce);continue}J&&j4([k,L,R],et=>{Sn=Ny(Sn,et," ")});let Hr=Ue(Ce.nodeName);if(tn(Hr,Zn,Sn)){if(C&&typeof m=="object"&&typeof m.getAttributeType=="function"&&!Zr)switch(m.getAttributeType(Hr,Zn)){case"TrustedHTML":{Sn=C.createHTML(Sn);break}case"TrustedScriptURL":{Sn=C.createScriptURL(Sn);break}}try{Zr?Ce.setAttributeNS(Zr,gn,Sn):Ce.setAttribute(gn,Sn),nt(Ce)?ut(Ce):X$(e.removed)}catch{}}}Tt(D.afterSanitizeAttributes,Ce,null)},"_sanitizeAttributes"),Pn=o(function At(Ce){let tt=null,St=yt(Ce);for(Tt(D.beforeSanitizeShadowDOM,Ce,null);tt=St.nextNode();)Tt(D.uponSanitizeShadowNode,tt,null),On(tt),Dr(tt),tt.content instanceof a&&At(tt.content);Tt(D.afterSanitizeShadowDOM,Ce,null)},"_sanitizeShadowDOM");return e.sanitize=function(At){let Ce=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},tt=null,St=null,mr=null,rn=null;if(Pe=!At,Pe&&(At="<!-->"),typeof At!="string"&&!dn(At))if(typeof At.toString=="function"){if(At=At.toString(),typeof At!="string")throw My("dirty is not a string, aborting")}else throw My("toString is not a function");if(!e.isSupported)return At;if(Z||Yt(Ce),e.removed=[],typeof At=="string"&&(Re=!1),Re){if(At.nodeName){let Ni=Ue(At.nodeName);if(!$[Ni]||ne[Ni])throw My("root node is forbidden and cannot be sanitized in-place")}}else if(At instanceof l)tt=ft("<!---->"),St=tt.ownerDocument.importNode(At,!0),St.nodeType===Oy.element&&St.nodeName==="BODY"||St.nodeName==="HTML"?tt=St:tt.appendChild(St);else{if(!ce&&!J&&!ue&&At.indexOf("<")===-1)return C&&Oe?C.createHTML(At):At;if(tt=ft(At),!tt)return ce?null:Oe?T:""}tt&&Se&&ut(tt.firstChild);let gn=yt(Re?At:tt);for(;mr=gn.nextNode();)On(mr),Dr(mr),mr.content instanceof a&&Pn(mr.content);if(Re)return At;if(ce){if(ae)for(rn=S.call(tt.ownerDocument);tt.firstChild;)rn.appendChild(tt.firstChild);else rn=tt;return(Q.shadowroot||Q.shadowrootmode)&&(rn=I.call(n,rn,!0)),rn}let Zr=ue?tt.outerHTML:tt.innerHTML;return ue&&$["!doctype"]&&tt.ownerDocument&&tt.ownerDocument.doctype&&tt.ownerDocument.doctype.name&&Xa(az,tt.ownerDocument.doctype.name)&&(Zr="<!DOCTYPE "+tt.ownerDocument.doctype.name+`>
+`+Zr),J&&j4([k,L,R],Ni=>{Zr=Ny(Zr,Ni," ")}),C&&Oe?C.createHTML(Zr):Zr},e.setConfig=function(){let At=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Yt(At),Z=!0},e.clearConfig=function(){ct=null,Z=!1},e.isValidAttribute=function(At,Ce,tt){ct||Yt({});let St=Ue(At),mr=Ue(Ce);return tn(St,mr,tt)},e.addHook=function(At,Ce){typeof Ce=="function"&&Ry(D[At],Ce)},e.removeHook=function(At,Ce){if(Ce!==void 0){let tt=Oxe(D[At],Ce);return tt===-1?void 0:Pxe(D[At],tt,1)[0]}return X$(D[At])},e.removeHooks=function(At){D[At]=[]},e.removeAllHooks=function(){D=tz()},e}var rz,Y$,Nxe,Mxe,Ixe,ja,ko,nz,l7,c7,j4,Oxe,X$,Ry,Pxe,Q4,n7,j$,Ny,Bxe,Fxe,sl,Xa,My,K$,i7,a7,Gxe,s7,Vxe,Q$,Z$,o7,J$,K4,Uxe,Hxe,Wxe,qxe,Yxe,iz,Xxe,jxe,az,Kxe,ez,Oy,Qxe,Zxe,tz,ch,u7=N(()=>{"use strict";({entries:rz,setPrototypeOf:Y$,isFrozen:Nxe,getPrototypeOf:Mxe,getOwnPropertyDescriptor:Ixe}=Object),{freeze:ja,seal:ko,create:nz}=Object,{apply:l7,construct:c7}=typeof Reflect<"u"&&Reflect;ja||(ja=o(function(e){return e},"freeze"));ko||(ko=o(function(e){return e},"seal"));l7||(l7=o(function(e,r,n){return e.apply(r,n)},"apply"));c7||(c7=o(function(e,r){return new e(...r)},"construct"));j4=Ka(Array.prototype.forEach),Oxe=Ka(Array.prototype.lastIndexOf),X$=Ka(Array.prototype.pop),Ry=Ka(Array.prototype.push),Pxe=Ka(Array.prototype.splice),Q4=Ka(String.prototype.toLowerCase),n7=Ka(String.prototype.toString),j$=Ka(String.prototype.match),Ny=Ka(String.prototype.replace),Bxe=Ka(String.prototype.indexOf),Fxe=Ka(String.prototype.trim),sl=Ka(Object.prototype.hasOwnProperty),Xa=Ka(RegExp.prototype.test),My=$xe(TypeError);o(Ka,"unapply");o($xe,"unconstruct");o(Cr,"addToSet");o(zxe,"cleanArray");o(Qf,"clone");o(Iy,"lookupGetter");K$=ja(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),i7=ja(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),a7=ja(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),Gxe=ja(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),s7=ja(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),Vxe=ja(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),Q$=ja(["#text"]),Z$=ja(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),o7=ja(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),J$=ja(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),K4=ja(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),Uxe=ko(/\{\{[\w\W]*|[\w\W]*\}\}/gm),Hxe=ko(/<%[\w\W]*|[\w\W]*%>/gm),Wxe=ko(/\$\{[\w\W]*/gm),qxe=ko(/^data-[\-\w.\u00B7-\uFFFF]+$/),Yxe=ko(/^aria-[\-\w]+$/),iz=ko(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Xxe=ko(/^(?:\w+script|data):/i),jxe=ko(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),az=ko(/^html$/i),Kxe=ko(/^[a-z][.\w]*(-[.\w]+)+$/i),ez=Object.freeze({__proto__:null,ARIA_ATTR:Yxe,ATTR_WHITESPACE:jxe,CUSTOM_ELEMENT:Kxe,DATA_ATTR:qxe,DOCTYPE_NAME:az,ERB_EXPR:Hxe,IS_ALLOWED_URI:iz,IS_SCRIPT_OR_DATA:Xxe,MUSTACHE_EXPR:Uxe,TMPLIT_EXPR:Wxe}),Oy={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},Qxe=o(function(){return typeof window>"u"?null:window},"getGlobal"),Zxe=o(function(e,r){if(typeof e!="object"||typeof e.createPolicy!="function")return null;let n=null,i="data-tt-policy-suffix";r&&r.hasAttribute(i)&&(n=r.getAttribute(i));let a="dompurify"+(n?"#"+n:"");try{return e.createPolicy(a,{createHTML(s){return s},createScriptURL(s){return s}})}catch{return console.warn("TrustedTypes policy "+a+" could not be created."),null}},"_createTrustedTypesPolicy"),tz=o(function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},"_createHooksMap");o(sz,"createDOMPurify");ch=sz()});var MG={};hr(MG,{default:()=>q4e});function abe(t){return String(t).replace(ibe,e=>nbe[e])}function cbe(t){if(t.default)return t.default;var e=t.type,r=Array.isArray(e)?e[0]:e;if(typeof r!="string")return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}function gbe(t){for(var e=0;e<k7.length;e++)for(var r=k7[e],n=0;n<r.blocks.length;n++){var i=r.blocks[n];if(t>=i[0]&&t<=i[1])return r.name}return null}function $z(t){for(var e=0;e<u3.length;e+=2)if(t>=u3[e]&&t<=u3[e+1])return!0;return!1}function Abe(t,e){jl[t]=e}function P7(t,e,r){if(!jl[e])throw new Error("Font metrics not found for font: "+e+".");var n=t.charCodeAt(0),i=jl[e][n];if(!i&&t[0]in lz&&(n=lz[t[0]].charCodeAt(0),i=jl[e][n]),!i&&r==="text"&&$z(n)&&(i=jl[e][77]),i)return{depth:i[0],height:i[1],italic:i[2],skew:i[3],width:i[4]}}function _be(t){var e;if(t>=5?e=0:t>=3?e=1:e=2,!h7[e]){var r=h7[e]={cssEmPerMu:Z4.quad[e]/18};for(var n in Z4)Z4.hasOwnProperty(n)&&(r[n]=Z4[n][e])}return h7[e]}function hz(t){if(t instanceof Ts)return t;throw new Error("Expected symbolNode but got "+String(t)+".")}function Nbe(t){if(t instanceof td)return t;throw new Error("Expected span<HtmlDomNode> but got "+String(t)+".")}function G(t,e,r,n,i,a){An[t][i]={font:e,group:r,replace:n},a&&n&&(An[t][n]=An[t][i])}function Nt(t){for(var{type:e,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:s}=t,l={type:e,numArgs:n.numArgs,argTypes:n.argTypes,allowedInArgument:!!n.allowedInArgument,allowedInText:!!n.allowedInText,allowedInMath:n.allowedInMath===void 0?!0:n.allowedInMath,numOptionalArgs:n.numOptionalArgs||0,infix:!!n.infix,primitive:!!n.primitive,handler:i},u=0;u<r.length;++u)jz[r[u]]=l;e&&(a&&(p3[e]=a),s&&(m3[e]=s))}function rd(t){var{type:e,htmlBuilder:r,mathmlBuilder:n}=t;Nt({type:e,names:[],props:{numArgs:0},handler(){throw new Error("Should never be called.")},htmlBuilder:r,mathmlBuilder:n})}function a3(t,e){var r=lu(["base"],t,e),n=lu(["strut"]);return n.style.height=kt(r.height+r.depth),r.depth&&(n.style.verticalAlign=kt(-r.depth)),r.children.unshift(n),r}function _7(t,e){var r=null;t.length===1&&t[0].type==="tag"&&(r=t[0].tag,t=t[0].body);var n=Pi(t,e,"root"),i;n.length===2&&n[1].hasClass("tag")&&(i=n.pop());for(var a=[],s=[],l=0;l<n.length;l++)if(s.push(n[l]),n[l].hasClass("mbin")||n[l].hasClass("mrel")||n[l].hasClass("allowbreak")){for(var u=!1;l<n.length-1&&n[l+1].hasClass("mspace")&&!n[l+1].hasClass("newline");)l++,s.push(n[l]),n[l].hasClass("nobreak")&&(u=!0);u||(a.push(a3(s,e)),s=[])}else n[l].hasClass("newline")&&(s.pop(),s.length>0&&(a.push(a3(s,e)),s=[]),a.push(n[l]));s.length>0&&a.push(a3(s,e));var h;r?(h=a3(Pi(r,e,!0)),h.classes=["tag"],a.push(h)):i&&a.push(i);var f=lu(["katex-html"],a);if(f.setAttribute("aria-hidden","true"),h){var d=h.children[0];d.style.height=kt(f.height+f.depth),f.depth&&(d.style.verticalAlign=kt(-f.depth))}return f}function Qz(t){return new ed(t)}function gz(t,e,r,n,i){var a=ks(t,r),s;a.length===1&&a[0]instanceof ws&&Jt.contains(["mrow","mtable"],a[0].type)?s=a[0]:s=new dt.MathNode("mrow",a);var l=new dt.MathNode("annotation",[new dt.TextNode(e)]);l.setAttribute("encoding","application/x-tex");var u=new dt.MathNode("semantics",[s,l]),h=new dt.MathNode("math",[u]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&h.setAttribute("display","block");var f=i?"katex":"katex-mathml";return Be.makeSpan([f],[h])}function xr(t,e){if(!t||t.type!==e)throw new Error("Expected node of type "+e+", but got "+(t?"node of type "+t.type:String(t)));return t}function z7(t){var e=w3(t);if(!e)throw new Error("Expected node of symbol group type, but got "+(t?"node of type "+t.type:String(t)));return e}function w3(t){return t&&(t.type==="atom"||Ibe.hasOwnProperty(t.type))?t:null}function tG(t,e){var r=Pi(t.body,e,!0);return u4e([t.mclass],r,e)}function rG(t,e){var r,n=ks(t.body,e);return t.mclass==="minner"?r=new dt.MathNode("mpadded",n):t.mclass==="mord"?t.isCharacterBox?(r=n[0],r.type="mi"):r=new dt.MathNode("mi",n):(t.isCharacterBox?(r=n[0],r.type="mo"):r=new dt.MathNode("mo",n),t.mclass==="mbin"?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):t.mclass==="mpunct"?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):t.mclass==="mopen"||t.mclass==="mclose"?(r.attributes.lspace="0em",r.attributes.rspace="0em"):t.mclass==="minner"&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}function d4e(t,e,r){var n=h4e[t];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[e[0]],[e[1]]);case"\\uparrow":case"\\downarrow":{var i=r.callFunction("\\\\cdleft",[e[0]],[]),a={type:"atom",text:n,mode:"math",family:"rel"},s=r.callFunction("\\Big",[a],[]),l=r.callFunction("\\\\cdright",[e[1]],[]),u={type:"ordgroup",mode:"math",body:[i,s,l]};return r.callFunction("\\\\cdparent",[u],[])}case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":{var h={type:"textord",text:"\\Vert",mode:"math"};return r.callFunction("\\Big",[h],[])}default:return{type:"textord",text:" ",mode:"math"}}}function p4e(t){var e=[];for(t.gullet.beginGroup(),t.gullet.macros.set("\\cr","\\\\\\relax"),t.gullet.beginGroup();;){e.push(t.parseExpression(!1,"\\\\")),t.gullet.endGroup(),t.gullet.beginGroup();var r=t.fetch().text;if(r==="&"||r==="\\\\")t.consume();else if(r==="\\end"){e[e.length-1].length===0&&e.pop();break}else throw new gt("Expected \\\\ or \\cr or \\end",t.nextToken)}for(var n=[],i=[n],a=0;a<e.length;a++){for(var s=e[a],l=yz(),u=0;u<s.length;u++)if(!vz(s[u]))l.body.push(s[u]);else{n.push(l),u+=1;var h=z7(s[u]).text,f=new Array(2);if(f[0]={type:"ordgroup",mode:"math",body:[]},f[1]={type:"ordgroup",mode:"math",body:[]},!("=|.".indexOf(h)>-1))if("<>AV".indexOf(h)>-1)for(var d=0;d<2;d++){for(var p=!0,m=u+1;m<s.length;m++){if(f4e(s[m],h)){p=!1,u=m;break}if(vz(s[m]))throw new gt("Missing a "+h+" character to complete a CD arrow.",s[m]);f[d].body.push(s[m])}if(p)throw new gt("Missing a "+h+" character to complete a CD arrow.",s[u])}else throw new gt('Expected one of "<>AV=|." after @',s[u]);var g=d4e(h,f,t),y={type:"styling",body:[g],mode:"math",style:"display"};n.push(y),l=yz()}a%2===0?n.push(l):n.shift(),n=[],i.push(n)}t.gullet.endGroup(),t.gullet.endGroup();var v=new Array(i[0].length).fill({type:"align",align:"c",pregap:.25,postgap:.25});return{type:"array",mode:"math",body:i,arraystretch:1,addJot:!0,rowGaps:[null],cols:v,colSeparationType:"CD",hLinesBeforeRow:new Array(i.length+1).fill([])}}function k3(t,e){var r=w3(t);if(r&&Jt.contains(A4e,r.text))return r;throw r?new gt("Invalid delimiter '"+r.text+"' after '"+e.funcName+"'",t):new gt("Invalid delimiter type '"+t.type+"'",t)}function bz(t){if(!t.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}function Ql(t){for(var{type:e,names:r,props:n,handler:i,htmlBuilder:a,mathmlBuilder:s}=t,l={type:e,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:i},u=0;u<r.length;++u)mG[r[u]]=l;a&&(p3[e]=a),s&&(m3[e]=s)}function fe(t,e){gG[t]=e}function wz(t){var e=[];t.consumeSpaces();var r=t.fetch().text;for(r==="\\relax"&&(t.consume(),t.consumeSpaces(),r=t.fetch().text);r==="\\hline"||r==="\\hdashline";)t.consume(),e.push(r==="\\hdashline"),t.consumeSpaces(),r=t.fetch().text;return e}function W7(t){if(t.indexOf("ed")===-1)return t.indexOf("*")===-1}function ph(t,e,r){var{hskipBeforeAndAfter:n,addJot:i,cols:a,arraystretch:s,colSeparationType:l,autoTag:u,singleRow:h,emptySingleRow:f,maxNumCols:d,leqno:p}=e;if(t.gullet.beginGroup(),h||t.gullet.macros.set("\\cr","\\\\\\relax"),!s){var m=t.gullet.expandMacroAsText("\\arraystretch");if(m==null)s=1;else if(s=parseFloat(m),!s||s<0)throw new gt("Invalid \\arraystretch: "+m)}t.gullet.beginGroup();var g=[],y=[g],v=[],x=[],b=u!=null?[]:void 0;function w(){u&&t.gullet.macros.set("\\@eqnsw","1",!0)}o(w,"beginRow");function C(){b&&(t.gullet.macros.get("\\df@tag")?(b.push(t.subparse([new So("\\df@tag")])),t.gullet.macros.set("\\df@tag",void 0,!0)):b.push(!!u&&t.gullet.macros.get("\\@eqnsw")==="1"))}for(o(C,"endRow"),w(),x.push(wz(t));;){var T=t.parseExpression(!1,h?"\\end":"\\\\");t.gullet.endGroup(),t.gullet.beginGroup(),T={type:"ordgroup",mode:t.mode,body:T},r&&(T={type:"styling",mode:t.mode,style:r,body:[T]}),g.push(T);var E=t.fetch().text;if(E==="&"){if(d&&g.length===d){if(h||l)throw new gt("Too many tab characters: &",t.nextToken);t.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}t.consume()}else if(E==="\\end"){C(),g.length===1&&T.type==="styling"&&T.body[0].body.length===0&&(y.length>1||!f)&&y.pop(),x.length<y.length+1&&x.push([]);break}else if(E==="\\\\"){t.consume();var A=void 0;t.gullet.future().text!==" "&&(A=t.parseSizeGroup(!0)),v.push(A?A.value:null),C(),x.push(wz(t)),g=[],y.push(g),w()}else throw new gt("Expected & or \\\\ or \\cr or \\end",t.nextToken)}return t.gullet.endGroup(),t.gullet.endGroup(),{type:"array",mode:t.mode,addJot:i,arraystretch:s,body:y,cols:a,rowGaps:v,hskipBeforeAndAfter:n,hLinesBeforeRow:x,colSeparationType:l,tags:b,leqno:p}}function q7(t){return t.slice(0,1)==="d"?"display":"text"}function SG(t,e,r){for(var n=Pi(t,e,!1),i=e.sizeMultiplier/r.sizeMultiplier,a=0;a<n.length;a++){var s=n[a].classes.indexOf("sizing");s<0?Array.prototype.push.apply(n[a].classes,e.sizingClasses(r)):n[a].classes[s+1]==="reset-size"+e.size&&(n[a].classes[s+1]="reset-size"+r.size),n[a].height*=i,n[a].depth*=i}return Be.makeFragment(n)}var Xs,So,gt,Jxe,ebe,tbe,rbe,nbe,ibe,Fz,sbe,obe,lbe,Jt,c3,zy,Yl,O7,h3,f0,su,Gy,Eo,d0,Qa,Xl,ube,hbe,fbe,dbe,pbe,mbe,tr,k7,u3,h0,ybe,vbe,xbe,bbe,wbe,Tbe,kbe,Ebe,Sbe,oz,Cbe,ed,jl,Z4,lz,h7,Dbe,cz,uz,f3,E7,Lbe,zz,ti,kt,fh,Gz,Vz,Uz,td,Vy,S7,Rbe,Ts,ll,Kl,Uy,Mbe,Ibe,An,U,it,ee,ke,Vn,It,Za,p0,er,ki,js,x3,Ee,uu,Le,Hz,fz,f7,J4,dz,d7,e3,d3,Py,t3,sr,Jn,Ca,iu,uh,C7,By,r3,n3,pz,Obe,b3,ol,Pbe,Bbe,Fbe,$be,zbe,B7,bs,Wz,Gbe,Vbe,qz,Ube,Hbe,Wbe,qbe,i3,Yz,Xz,Ybe,Be,ei,Zf,au,Xbe,jbe,jz,p3,m3,g3,di,lu,Kbe,Qbe,Zbe,Jbe,Pi,mz,Kz,e4e,A7,Hy,Fr,ws,Jf,D7,dt,Co,F7,$7,ks,dh,yn,Zz,Jz,t4e,r4e,n4e,i4e,a4e,s4e,o4e,l4e,cu,G7,eG,c4e,s3,u4e,T3,h4e,yz,vz,f4e,nG,iG,L7,aG,m4e,sG,Fy,V7,oG,g4e,y4e,lG,p7,m7,R7,o3,v4e,x4e,cG,g7,y7,v7,b4e,uG,w4e,hG,$y,T4e,k4e,E4e,fG,S4e,dG,pG,C4e,ou,xz,A4e,U7,H7,mG,gG,E3,Zl,_4e,Jl,yG,Tz,vG,xG,kz,bG,Y7,X7,Ez,Sz,wG,D4e,x7,Cz,TG,kG,m0,Wy,L4e,R4e,EG,N4e,Az,M4e,_z,I4e,CG,b7,w7,Dz,Lz,Rz,O4e,Nz,Mz,hh,AG,P4e,B4e,F4e,$4e,N7,z4e,G4e,y3,M7,V4e,Iz,j7,Oz,K7,_G,DG,LG,I7,Pz,l3,T7,Bz,v3,Q7,RG,U4e,H4e,NG,Z7,W4e,q4e,IG=N(()=>{"use strict";Xs=class t{static{o(this,"SourceLocation")}constructor(e,r,n){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=r,this.end=n}static range(e,r){return r?!e||!e.loc||!r.loc||e.loc.lexer!==r.loc.lexer?null:new t(e.loc.lexer,e.loc.start,r.loc.end):e&&e.loc}},So=class t{static{o(this,"Token")}constructor(e,r){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=r}range(e,r){return new t(r,Xs.range(this,e))}},gt=class t{static{o(this,"ParseError")}constructor(e,r){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var n="KaTeX parse error: "+e,i,a,s=r&&r.loc;if(s&&s.start<=s.end){var l=s.lexer.input;i=s.start,a=s.end,i===l.length?n+=" at end of input: ":n+=" at position "+(i+1)+": ";var u=l.slice(i,a).replace(/[^]/g,"$&\u0332"),h;i>15?h="\u2026"+l.slice(i-15,i):h=l.slice(0,i);var f;a+15<l.length?f=l.slice(a,a+15)+"\u2026":f=l.slice(a),n+=h+u+f}var d=new Error(n);return d.name="ParseError",d.__proto__=t.prototype,d.position=i,i!=null&&a!=null&&(d.length=a-i),d.rawMessage=e,d}};gt.prototype.__proto__=Error.prototype;Jxe=o(function(e,r){return e.indexOf(r)!==-1},"contains"),ebe=o(function(e,r){return e===void 0?r:e},"deflt"),tbe=/([A-Z])/g,rbe=o(function(e){return e.replace(tbe,"-$1").toLowerCase()},"hyphenate"),nbe={"&":"&amp;",">":"&gt;","<":"&lt;",'"':"&quot;","'":"&#x27;"},ibe=/[&><"']/g;o(abe,"escape");Fz=o(function t(e){return e.type==="ordgroup"||e.type==="color"?e.body.length===1?t(e.body[0]):e:e.type==="font"?t(e.body):e},"getBaseElem"),sbe=o(function(e){var r=Fz(e);return r.type==="mathord"||r.type==="textord"||r.type==="atom"},"isCharacterBox"),obe=o(function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e},"assert"),lbe=o(function(e){var r=/^[\x00-\x20]*([^\\/#?]*?)(:|&#0*58|&#x0*3a|&colon)/i.exec(e);return r?r[2]!==":"||!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(r[1])?null:r[1].toLowerCase():"_relative"},"protocolFromUrl"),Jt={contains:Jxe,deflt:ebe,escape:abe,hyphenate:rbe,getBaseElem:Fz,isCharacterBox:sbe,protocolFromUrl:lbe},c3={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format <type>"},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color <color>",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:o(t=>"#"+t,"cliProcessor")},macros:{type:"object",cli:"-m, --macro <def>",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:o((t,e)=>(e.push(t),e),"cliProcessor")},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:o(t=>Math.max(0,t),"processor"),cli:"--min-rule-thickness <size>",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:o(t=>Math.max(0,t),"processor"),cli:"-s, --max-size <n>",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:o(t=>Math.max(0,t),"processor"),cli:"-e, --max-expand <n>",cliProcessor:o(t=>t==="Infinity"?1/0:parseInt(t),"cliProcessor")},globalGroup:{type:"boolean",cli:!1}};o(cbe,"getDefaultValue");zy=class{static{o(this,"Settings")}constructor(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{};for(var r in c3)if(c3.hasOwnProperty(r)){var n=c3[r];this[r]=e[r]!==void 0?n.processor?n.processor(e[r]):e[r]:cbe(n)}}reportNonstrict(e,r,n){var i=this.strict;if(typeof i=="function"&&(i=i(e,r,n)),!(!i||i==="ignore")){if(i===!0||i==="error")throw new gt("LaTeX-incompatible input and strict mode is set to 'error': "+(r+" ["+e+"]"),n);i==="warn"?typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+e+"]")):typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+e+"]"))}}useStrictBehavior(e,r,n){var i=this.strict;if(typeof i=="function")try{i=i(e,r,n)}catch{i="error"}return!i||i==="ignore"?!1:i===!0||i==="error"?!0:i==="warn"?(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+(r+" ["+e+"]")),!1):(typeof console<"u"&&console.warn("LaTeX-incompatible input and strict mode is set to "+("unrecognized '"+i+"': "+r+" ["+e+"]")),!1)}isTrusted(e){if(e.url&&!e.protocol){var r=Jt.protocolFromUrl(e.url);if(r==null)return!1;e.protocol=r}var n=typeof this.trust=="function"?this.trust(e):this.trust;return!!n}},Yl=class{static{o(this,"Style")}constructor(e,r,n){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=r,this.cramped=n}sup(){return Xl[ube[this.id]]}sub(){return Xl[hbe[this.id]]}fracNum(){return Xl[fbe[this.id]]}fracDen(){return Xl[dbe[this.id]]}cramp(){return Xl[pbe[this.id]]}text(){return Xl[mbe[this.id]]}isTight(){return this.size>=2}},O7=0,h3=1,f0=2,su=3,Gy=4,Eo=5,d0=6,Qa=7,Xl=[new Yl(O7,0,!1),new Yl(h3,0,!0),new Yl(f0,1,!1),new Yl(su,1,!0),new Yl(Gy,2,!1),new Yl(Eo,2,!0),new Yl(d0,3,!1),new Yl(Qa,3,!0)],ube=[Gy,Eo,Gy,Eo,d0,Qa,d0,Qa],hbe=[Eo,Eo,Eo,Eo,Qa,Qa,Qa,Qa],fbe=[f0,su,Gy,Eo,d0,Qa,d0,Qa],dbe=[su,su,Eo,Eo,Qa,Qa,Qa,Qa],pbe=[h3,h3,su,su,Eo,Eo,Qa,Qa],mbe=[O7,h3,f0,su,f0,su,f0,su],tr={DISPLAY:Xl[O7],TEXT:Xl[f0],SCRIPT:Xl[Gy],SCRIPTSCRIPT:Xl[d0]},k7=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];o(gbe,"scriptFromCodepoint");u3=[];k7.forEach(t=>t.blocks.forEach(e=>u3.push(...e)));o($z,"supportedCodepoint");h0=80,ybe=o(function(e,r){return"M95,"+(622+e+r)+`
+c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
+c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
+c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
+s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
+c69,-144,104.5,-217.7,106.5,-221
+l`+e/2.075+" -"+e+`
+c5.3,-9.3,12,-14,20,-14
+H400000v`+(40+e)+`H845.2724
+s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
+c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
+M`+(834+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtMain"),vbe=o(function(e,r){return"M263,"+(601+e+r)+`c0.7,0,18,39.7,52,119
+c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120
+c340,-704.7,510.7,-1060.3,512,-1067
+l`+e/2.084+" -"+e+`
+c4.7,-7.3,11,-11,19,-11
+H40000v`+(40+e)+`H1012.3
+s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232
+c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1
+s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26
+c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z
+M`+(1001+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtSize1"),xbe=o(function(e,r){return"M983 "+(10+e+r)+`
+l`+e/3.13+" -"+e+`
+c4,-6.7,10,-10,18,-10 H400000v`+(40+e)+`
+H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
+s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
+c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
+c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
+c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
+c53.7,-170.3,84.5,-266.8,92.5,-289.5z
+M`+(1001+e)+" "+r+"h400000v"+(40+e)+"h-400000z"},"sqrtSize2"),bbe=o(function(e,r){return"M424,"+(2398+e+r)+`
+c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514
+c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20
+s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121
+s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081
+l`+e/4.223+" -"+e+`c4,-6.7,10,-10,18,-10 H400000
+v`+(40+e)+`H1014.6
+s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185
+c-2,6,-10,9,-24,9
+c-8,0,-12,-0.7,-12,-2z M`+(1001+e)+" "+r+`
+h400000v`+(40+e)+"h-400000z"},"sqrtSize3"),wbe=o(function(e,r){return"M473,"+(2713+e+r)+`
+c339.3,-1799.3,509.3,-2700,510,-2702 l`+e/5.298+" -"+e+`
+c3.3,-7.3,9.3,-11,18,-11 H400000v`+(40+e)+`H1017.7
+s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
+c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
+c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
+s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
+606zM`+(1001+e)+" "+r+"h400000v"+(40+e)+"H1017.7z"},"sqrtSize4"),Tbe=o(function(e){var r=e/2;return"M400000 "+e+" H0 L"+r+" 0 l65 45 L145 "+(e-80)+" H400000z"},"phasePath"),kbe=o(function(e,r,n){var i=n-54-r-e;return"M702 "+(e+r)+"H400000"+(40+e)+`
+H742v`+i+`l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1
+h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170
+c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667
+219 661 l218 661zM702 `+r+"H400000v"+(40+e)+"H742z"},"sqrtTall"),Ebe=o(function(e,r,n){r=1e3*r;var i="";switch(e){case"sqrtMain":i=ybe(r,h0);break;case"sqrtSize1":i=vbe(r,h0);break;case"sqrtSize2":i=xbe(r,h0);break;case"sqrtSize3":i=bbe(r,h0);break;case"sqrtSize4":i=wbe(r,h0);break;case"sqrtTall":i=kbe(r,h0,n)}return i},"sqrtPath"),Sbe=o(function(e,r){switch(e){case"\u239C":return"M291 0 H417 V"+r+" H291z M291 0 H417 V"+r+" H291z";case"\u2223":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z";case"\u2225":return"M145 0 H188 V"+r+" H145z M145 0 H188 V"+r+" H145z"+("M367 0 H410 V"+r+" H367z M367 0 H410 V"+r+" H367z");case"\u239F":return"M457 0 H583 V"+r+" H457z M457 0 H583 V"+r+" H457z";case"\u23A2":return"M319 0 H403 V"+r+" H319z M319 0 H403 V"+r+" H319z";case"\u23A5":return"M263 0 H347 V"+r+" H263z M263 0 H347 V"+r+" H263z";case"\u23AA":return"M384 0 H504 V"+r+" H384z M384 0 H504 V"+r+" H384z";case"\u23D0":return"M312 0 H355 V"+r+" H312z M312 0 H355 V"+r+" H312z";case"\u2016":return"M257 0 H300 V"+r+" H257z M257 0 H300 V"+r+" H257z"+("M478 0 H521 V"+r+" H478z M478 0 H521 V"+r+" H478z");default:return""}},"innerPath"),oz={doubleleftarrow:`M262 157
+l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3
+ 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28
+ 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5
+c2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5
+ 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87
+-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7
+-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z
+m8 0v40h399730v-40zm0 194v40h399730v-40z`,doublerightarrow:`M399738 392l
+-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5
+ 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88
+-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68
+-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18
+-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782
+c-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3
+-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z`,leftarrow:`M400000 241H110l3-3c68.7-52.7 113.7-120
+ 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8
+-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247
+c-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208
+ 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3
+ 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202
+ l-3-3h399890zM100 241v40h399900v-40z`,leftbrace:`M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117
+-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7
+ 5-6 9-10 13-.7 1-7.3 1-20 1H6z`,leftbraceunder:`M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13
+ 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688
+ 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7
+-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z`,leftgroup:`M400000 80
+H435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0
+ 435 0h399565z`,leftgroupunder:`M400000 262
+H435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219
+ 435 219h399565z`,leftharpoon:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3
+-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5
+-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7
+-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z`,leftharpoonplus:`M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5
+ 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3
+-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7
+-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z
+m0 0v40h400000v-40z`,leftharpoondown:`M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333
+ 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5
+ 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667
+-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z`,leftharpoondownplus:`M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12
+ 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7
+-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0
+v40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,lefthook:`M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5
+-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3
+-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21
+ 71.5 23h399859zM103 281v-40h399897v40z`,leftlinesegment:`M40 281 V428 H0 V94 H40 V241 H400000 v40z
+M40 281 V428 H0 V94 H40 V241 H400000 v40z`,leftmapsto:`M40 281 V448H0V74H40V241H400000v40z
+M40 281 V448H0V74H40V241H400000v40z`,leftToFrom:`M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23
+-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8
+c28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3
+ 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,longequal:`M0 50 h400000 v40H0z m0 194h40000v40H0z
+M0 50 h400000 v40H0z m0 194h40000v40H0z`,midbrace:`M200428 334
+c-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14
+-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7
+ 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11
+ 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z`,midbraceunder:`M199572 214
+c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14
+ 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3
+ 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0
+-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z`,oiintSize1:`M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6
+-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z
+m368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8
+60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z`,oiintSize2:`M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8
+-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z
+m502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2
+c0 110 84 276 504 276s502.4-166 502.4-276z`,oiiintSize1:`M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6
+-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z
+m525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0
+85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z`,oiiintSize2:`M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8
+-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z
+m770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1
+c0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z`,rightarrow:`M0 241v40h399891c-47.3 35.3-84 78-110 128
+-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20
+ 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7
+ 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85
+-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5
+-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67
+ 151.7 139 205zm0 0v40h399900v-40z`,rightbrace:`M400000 542l
+-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5
+s-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1
+c124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z`,rightbraceunder:`M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3
+ 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237
+-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z`,rightgroup:`M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0
+ 3-1 3-3v-38c-76-158-257-219-435-219H0z`,rightgroupunder:`M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18
+ 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z`,rightharpoon:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3
+-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2
+-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58
+ 69.2 92 94.5zm0 0v40h399900v-40z`,rightharpoonplus:`M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11
+-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7
+ 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z
+m0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z`,rightharpoondown:`M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8
+ 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5
+-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95
+-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z`,rightharpoondownplus:`M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8
+ 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3
+ 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3
+-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z
+m0-194v40h400000v-40zm0 0v40h400000v-40z`,righthook:`M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3
+ 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0
+-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21
+ 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,rightlinesegment:`M399960 241 V94 h40 V428 h-40 V281 H0 v-40z
+M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,rightToFrom:`M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23
+ 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32
+-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142
+-167z M100 147v40h399900v-40zM0 341v40h399900v-40z`,twoheadleftarrow:`M0 167c68 40
+ 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69
+-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3
+-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19
+-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101
+ 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z`,twoheadrightarrow:`M400000 167
+c-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3
+ 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42
+ 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333
+-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70
+ 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z`,tilde1:`M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
+-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
+ 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
+ 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
+-68.267.847-113-73.952-191-73.952z`,tilde2:`M344 55.266c-142 0-300.638 81.316-311.5 86.418
+-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9
+ 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114
+c1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751
+ 181.476 676 181.476c-149 0-189-126.21-332-126.21z`,tilde3:`M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457
+-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0
+ 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697
+ 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696
+ -338 0-409-156.573-744-156.573z`,tilde4:`M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345
+-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409
+ 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9
+ 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409
+ -175.236-744-175.236z`,vec:`M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5
+3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11
+10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63
+-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1
+-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59
+H213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359
+c-16-25.333-24-45-24-59z`,widehat1:`M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22
+c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,widehat2:`M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10
+-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat3:`M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10
+-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widehat4:`M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10
+-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,widecheck1:`M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,
+-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`,widecheck2:`M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,
+-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck3:`M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,
+-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,widecheck4:`M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,
+-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,baraboveleftarrow:`M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202
+c4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5
+c-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130
+s-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47
+121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6
+s2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11
+c0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z
+M100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z`,rightarrowabovebar:`M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32
+-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0
+13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39
+-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5
+-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5
+-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67
+151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z`,baraboveshortleftharpoon:`M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11
+c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17
+c2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21
+c-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40
+c-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z
+M0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z`,rightharpoonaboveshortbar:`M0,241 l0,40c399126,0,399993,0,399993,0
+c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,
+-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6
+c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z
+M0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z`,shortbaraboveleftharpoon:`M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11
+c1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,
+1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,
+-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z
+M93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z`,shortrightharpoonabovebar:`M53,241l0,40c398570,0,399437,0,399437,0
+c4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,
+-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6
+c-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z
+M500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`},Cbe=o(function(e,r){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v1759 h347 v-84
+H403z M403 1759 V0 H319 V1759 v`+r+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v1759 H0 v84 H347z
+M347 1759 V0 H263 V1759 v`+r+" v1759 h84z";case"vert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15
+c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15
+c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+" v585 h43z";case"doublevert":return"M145 15 v585 v"+r+` v585 c2.667,10,9.667,15,21,15
+c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15
+c-10,0,-16.667,5,-20,15z M188 15 H145 v585 v`+r+` v585 h43z
+M367 15 v585 v`+r+` v585 c2.667,10,9.667,15,21,15
+c10,0,16.667,-5,20,-15 v-585 v`+-r+` v-585 c-2.667,-10,-9.667,-15,-21,-15
+c-10,0,-16.667,5,-20,15z M410 15 H367 v585 v`+r+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+r+` v1715 h263 v84 H319z
+MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+r+` v1799 H0 v-84 H319z
+MM319 602 V0 H403 V602 v`+r+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+r+` v602 h84z
+M403 1759 V0 H319 V1759 v`+r+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+r+` v602 h84z
+M347 1759 V0 h-84 V1759 v`+r+" v602 h84z";case"lparen":return`M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1
+c-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,
+-36,557 l0,`+(r+84)+`c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,
+949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9
+c0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,
+-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189
+l0,-`+(r+92)+`c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,
+-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z`;case"rparen":return`M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,
+63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5
+c11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,`+(r+9)+`
+c-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664
+c-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11
+c0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17
+c242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558
+l0,-`+(r+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,
+-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z`;default:throw new Error("Unknown stretchy delimiter.")}},"tallDelim"),ed=class{static{o(this,"DocumentFragment")}constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return Jt.contains(this.classes,e)}toNode(){for(var e=document.createDocumentFragment(),r=0;r<this.children.length;r++)e.appendChild(this.children[r].toNode());return e}toMarkup(){for(var e="",r=0;r<this.children.length;r++)e+=this.children[r].toMarkup();return e}toText(){var e=o(r=>r.toText(),"toText");return this.children.map(e).join("")}},jl={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},Z4={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},lz={\u00C5:"A",\u00D0:"D",\u00DE:"o",\u00E5:"a",\u00F0:"d",\u00FE:"o",\u0410:"A",\u0411:"B",\u0412:"B",\u0413:"F",\u0414:"A",\u0415:"E",\u0416:"K",\u0417:"3",\u0418:"N",\u0419:"N",\u041A:"K",\u041B:"N",\u041C:"M",\u041D:"H",\u041E:"O",\u041F:"N",\u0420:"P",\u0421:"C",\u0422:"T",\u0423:"y",\u0424:"O",\u0425:"X",\u0426:"U",\u0427:"h",\u0428:"W",\u0429:"W",\u042A:"B",\u042B:"X",\u042C:"B",\u042D:"3",\u042E:"X",\u042F:"R",\u0430:"a",\u0431:"b",\u0432:"a",\u0433:"r",\u0434:"y",\u0435:"e",\u0436:"m",\u0437:"e",\u0438:"n",\u0439:"n",\u043A:"n",\u043B:"n",\u043C:"m",\u043D:"n",\u043E:"o",\u043F:"n",\u0440:"p",\u0441:"c",\u0442:"o",\u0443:"y",\u0444:"b",\u0445:"x",\u0446:"n",\u0447:"n",\u0448:"w",\u0449:"w",\u044A:"a",\u044B:"m",\u044C:"a",\u044D:"e",\u044E:"m",\u044F:"r"};o(Abe,"setFontMetrics");o(P7,"getCharacterMetrics");h7={};o(_be,"getGlobalMetrics");Dbe=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],cz=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],uz=o(function(e,r){return r.size<2?e:Dbe[e-1][r.size-1]},"sizeAtStyle"),f3=class t{static{o(this,"Options")}constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||t.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=cz[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var r={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);return new t(r)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:uz(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:cz[e-1]})}havingBaseStyle(e){e=e||this.style.text();var r=uz(t.BASESIZE,e);return this.size===r&&this.textSize===t.BASESIZE&&this.style===e?this:this.extend({style:e,size:r})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==t.BASESIZE?["sizing","reset-size"+this.size,"size"+t.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=_be(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}};f3.BASESIZE=6;E7={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:803/800,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:803/800},Lbe={ex:!0,em:!0,mu:!0},zz=o(function(e){return typeof e!="string"&&(e=e.unit),e in E7||e in Lbe||e==="ex"},"validUnit"),ti=o(function(e,r){var n;if(e.unit in E7)n=E7[e.unit]/r.fontMetrics().ptPerEm/r.sizeMultiplier;else if(e.unit==="mu")n=r.fontMetrics().cssEmPerMu;else{var i;if(r.style.isTight()?i=r.havingStyle(r.style.text()):i=r,e.unit==="ex")n=i.fontMetrics().xHeight;else if(e.unit==="em")n=i.fontMetrics().quad;else throw new gt("Invalid unit: '"+e.unit+"'");i!==r&&(n*=i.sizeMultiplier/r.sizeMultiplier)}return Math.min(e.number*n,r.maxSize)},"calculateSize"),kt=o(function(e){return+e.toFixed(4)+"em"},"makeEm"),fh=o(function(e){return e.filter(r=>r).join(" ")},"createClass"),Gz=o(function(e,r,n){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=n||{},r){r.style.isTight()&&this.classes.push("mtight");var i=r.getColor();i&&(this.style.color=i)}},"initNode"),Vz=o(function(e){var r=document.createElement(e);r.className=fh(this.classes);for(var n in this.style)this.style.hasOwnProperty(n)&&(r.style[n]=this.style[n]);for(var i in this.attributes)this.attributes.hasOwnProperty(i)&&r.setAttribute(i,this.attributes[i]);for(var a=0;a<this.children.length;a++)r.appendChild(this.children[a].toNode());return r},"toNode"),Uz=o(function(e){var r="<"+e;this.classes.length&&(r+=' class="'+Jt.escape(fh(this.classes))+'"');var n="";for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=Jt.hyphenate(i)+":"+this.style[i]+";");n&&(r+=' style="'+Jt.escape(n)+'"');for(var a in this.attributes)this.attributes.hasOwnProperty(a)&&(r+=" "+a+'="'+Jt.escape(this.attributes[a])+'"');r+=">";for(var s=0;s<this.children.length;s++)r+=this.children[s].toMarkup();return r+="</"+e+">",r},"toMarkup"),td=class{static{o(this,"Span")}constructor(e,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,Gz.call(this,e,n,i),this.children=r||[]}setAttribute(e,r){this.attributes[e]=r}hasClass(e){return Jt.contains(this.classes,e)}toNode(){return Vz.call(this,"span")}toMarkup(){return Uz.call(this,"span")}},Vy=class{static{o(this,"Anchor")}constructor(e,r,n,i){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,Gz.call(this,r,i),this.children=n||[],this.setAttribute("href",e)}setAttribute(e,r){this.attributes[e]=r}hasClass(e){return Jt.contains(this.classes,e)}toNode(){return Vz.call(this,"a")}toMarkup(){return Uz.call(this,"a")}},S7=class{static{o(this,"Img")}constructor(e,r,n){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=r,this.src=e,this.classes=["mord"],this.style=n}hasClass(e){return Jt.contains(this.classes,e)}toNode(){var e=document.createElement("img");e.src=this.src,e.alt=this.alt,e.className="mord";for(var r in this.style)this.style.hasOwnProperty(r)&&(e.style[r]=this.style[r]);return e}toMarkup(){var e='<img src="'+Jt.escape(this.src)+'"'+(' alt="'+Jt.escape(this.alt)+'"'),r="";for(var n in this.style)this.style.hasOwnProperty(n)&&(r+=Jt.hyphenate(n)+":"+this.style[n]+";");return r&&(e+=' style="'+Jt.escape(r)+'"'),e+="'/>",e}},Rbe={\u00EE:"\u0131\u0302",\u00EF:"\u0131\u0308",\u00ED:"\u0131\u0301",\u00EC:"\u0131\u0300"},Ts=class{static{o(this,"SymbolNode")}constructor(e,r,n,i,a,s,l,u){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=e,this.height=r||0,this.depth=n||0,this.italic=i||0,this.skew=a||0,this.width=s||0,this.classes=l||[],this.style=u||{},this.maxFontSize=0;var h=gbe(this.text.charCodeAt(0));h&&this.classes.push(h+"_fallback"),/[îïíì]/.test(this.text)&&(this.text=Rbe[this.text])}hasClass(e){return Jt.contains(this.classes,e)}toNode(){var e=document.createTextNode(this.text),r=null;this.italic>0&&(r=document.createElement("span"),r.style.marginRight=kt(this.italic)),this.classes.length>0&&(r=r||document.createElement("span"),r.className=fh(this.classes));for(var n in this.style)this.style.hasOwnProperty(n)&&(r=r||document.createElement("span"),r.style[n]=this.style[n]);return r?(r.appendChild(e),r):e}toMarkup(){var e=!1,r="<span";this.classes.length&&(e=!0,r+=' class="',r+=Jt.escape(fh(this.classes)),r+='"');var n="";this.italic>0&&(n+="margin-right:"+this.italic+"em;");for(var i in this.style)this.style.hasOwnProperty(i)&&(n+=Jt.hyphenate(i)+":"+this.style[i]+";");n&&(e=!0,r+=' style="'+Jt.escape(n)+'"');var a=Jt.escape(this.text);return e?(r+=">",r+=a,r+="</span>",r):a}},ll=class{static{o(this,"SvgNode")}constructor(e,r){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=r||{}}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"svg");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);for(var i=0;i<this.children.length;i++)r.appendChild(this.children[i].toNode());return r}toMarkup(){var e='<svg xmlns="http://www.w3.org/2000/svg"';for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&(e+=" "+r+'="'+Jt.escape(this.attributes[r])+'"');e+=">";for(var n=0;n<this.children.length;n++)e+=this.children[n].toMarkup();return e+="</svg>",e}},Kl=class{static{o(this,"PathNode")}constructor(e,r){this.pathName=void 0,this.alternate=void 0,this.pathName=e,this.alternate=r}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"path");return this.alternate?r.setAttribute("d",this.alternate):r.setAttribute("d",oz[this.pathName]),r}toMarkup(){return this.alternate?'<path d="'+Jt.escape(this.alternate)+'"/>':'<path d="'+Jt.escape(oz[this.pathName])+'"/>'}},Uy=class{static{o(this,"LineNode")}constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e="http://www.w3.org/2000/svg",r=document.createElementNS(e,"line");for(var n in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,n)&&r.setAttribute(n,this.attributes[n]);return r}toMarkup(){var e="<line";for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&(e+=" "+r+'="'+Jt.escape(this.attributes[r])+'"');return e+="/>",e}};o(hz,"assertSymbolDomNode");o(Nbe,"assertSpan");Mbe={bin:1,close:1,inner:1,open:1,punct:1,rel:1},Ibe={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},An={math:{},text:{}};o(G,"defineSymbol");U="math",it="text",ee="main",ke="ams",Vn="accent-token",It="bin",Za="close",p0="inner",er="mathord",ki="op-token",js="open",x3="punct",Ee="rel",uu="spacing",Le="textord";G(U,ee,Ee,"\u2261","\\equiv",!0);G(U,ee,Ee,"\u227A","\\prec",!0);G(U,ee,Ee,"\u227B","\\succ",!0);G(U,ee,Ee,"\u223C","\\sim",!0);G(U,ee,Ee,"\u22A5","\\perp");G(U,ee,Ee,"\u2AAF","\\preceq",!0);G(U,ee,Ee,"\u2AB0","\\succeq",!0);G(U,ee,Ee,"\u2243","\\simeq",!0);G(U,ee,Ee,"\u2223","\\mid",!0);G(U,ee,Ee,"\u226A","\\ll",!0);G(U,ee,Ee,"\u226B","\\gg",!0);G(U,ee,Ee,"\u224D","\\asymp",!0);G(U,ee,Ee,"\u2225","\\parallel");G(U,ee,Ee,"\u22C8","\\bowtie",!0);G(U,ee,Ee,"\u2323","\\smile",!0);G(U,ee,Ee,"\u2291","\\sqsubseteq",!0);G(U,ee,Ee,"\u2292","\\sqsupseteq",!0);G(U,ee,Ee,"\u2250","\\doteq",!0);G(U,ee,Ee,"\u2322","\\frown",!0);G(U,ee,Ee,"\u220B","\\ni",!0);G(U,ee,Ee,"\u221D","\\propto",!0);G(U,ee,Ee,"\u22A2","\\vdash",!0);G(U,ee,Ee,"\u22A3","\\dashv",!0);G(U,ee,Ee,"\u220B","\\owns");G(U,ee,x3,".","\\ldotp");G(U,ee,x3,"\u22C5","\\cdotp");G(U,ee,Le,"#","\\#");G(it,ee,Le,"#","\\#");G(U,ee,Le,"&","\\&");G(it,ee,Le,"&","\\&");G(U,ee,Le,"\u2135","\\aleph",!0);G(U,ee,Le,"\u2200","\\forall",!0);G(U,ee,Le,"\u210F","\\hbar",!0);G(U,ee,Le,"\u2203","\\exists",!0);G(U,ee,Le,"\u2207","\\nabla",!0);G(U,ee,Le,"\u266D","\\flat",!0);G(U,ee,Le,"\u2113","\\ell",!0);G(U,ee,Le,"\u266E","\\natural",!0);G(U,ee,Le,"\u2663","\\clubsuit",!0);G(U,ee,Le,"\u2118","\\wp",!0);G(U,ee,Le,"\u266F","\\sharp",!0);G(U,ee,Le,"\u2662","\\diamondsuit",!0);G(U,ee,Le,"\u211C","\\Re",!0);G(U,ee,Le,"\u2661","\\heartsuit",!0);G(U,ee,Le,"\u2111","\\Im",!0);G(U,ee,Le,"\u2660","\\spadesuit",!0);G(U,ee,Le,"\xA7","\\S",!0);G(it,ee,Le,"\xA7","\\S");G(U,ee,Le,"\xB6","\\P",!0);G(it,ee,Le,"\xB6","\\P");G(U,ee,Le,"\u2020","\\dag");G(it,ee,Le,"\u2020","\\dag");G(it,ee,Le,"\u2020","\\textdagger");G(U,ee,Le,"\u2021","\\ddag");G(it,ee,Le,"\u2021","\\ddag");G(it,ee,Le,"\u2021","\\textdaggerdbl");G(U,ee,Za,"\u23B1","\\rmoustache",!0);G(U,ee,js,"\u23B0","\\lmoustache",!0);G(U,ee,Za,"\u27EF","\\rgroup",!0);G(U,ee,js,"\u27EE","\\lgroup",!0);G(U,ee,It,"\u2213","\\mp",!0);G(U,ee,It,"\u2296","\\ominus",!0);G(U,ee,It,"\u228E","\\uplus",!0);G(U,ee,It,"\u2293","\\sqcap",!0);G(U,ee,It,"\u2217","\\ast");G(U,ee,It,"\u2294","\\sqcup",!0);G(U,ee,It,"\u25EF","\\bigcirc",!0);G(U,ee,It,"\u2219","\\bullet",!0);G(U,ee,It,"\u2021","\\ddagger");G(U,ee,It,"\u2240","\\wr",!0);G(U,ee,It,"\u2A3F","\\amalg");G(U,ee,It,"&","\\And");G(U,ee,Ee,"\u27F5","\\longleftarrow",!0);G(U,ee,Ee,"\u21D0","\\Leftarrow",!0);G(U,ee,Ee,"\u27F8","\\Longleftarrow",!0);G(U,ee,Ee,"\u27F6","\\longrightarrow",!0);G(U,ee,Ee,"\u21D2","\\Rightarrow",!0);G(U,ee,Ee,"\u27F9","\\Longrightarrow",!0);G(U,ee,Ee,"\u2194","\\leftrightarrow",!0);G(U,ee,Ee,"\u27F7","\\longleftrightarrow",!0);G(U,ee,Ee,"\u21D4","\\Leftrightarrow",!0);G(U,ee,Ee,"\u27FA","\\Longleftrightarrow",!0);G(U,ee,Ee,"\u21A6","\\mapsto",!0);G(U,ee,Ee,"\u27FC","\\longmapsto",!0);G(U,ee,Ee,"\u2197","\\nearrow",!0);G(U,ee,Ee,"\u21A9","\\hookleftarrow",!0);G(U,ee,Ee,"\u21AA","\\hookrightarrow",!0);G(U,ee,Ee,"\u2198","\\searrow",!0);G(U,ee,Ee,"\u21BC","\\leftharpoonup",!0);G(U,ee,Ee,"\u21C0","\\rightharpoonup",!0);G(U,ee,Ee,"\u2199","\\swarrow",!0);G(U,ee,Ee,"\u21BD","\\leftharpoondown",!0);G(U,ee,Ee,"\u21C1","\\rightharpoondown",!0);G(U,ee,Ee,"\u2196","\\nwarrow",!0);G(U,ee,Ee,"\u21CC","\\rightleftharpoons",!0);G(U,ke,Ee,"\u226E","\\nless",!0);G(U,ke,Ee,"\uE010","\\@nleqslant");G(U,ke,Ee,"\uE011","\\@nleqq");G(U,ke,Ee,"\u2A87","\\lneq",!0);G(U,ke,Ee,"\u2268","\\lneqq",!0);G(U,ke,Ee,"\uE00C","\\@lvertneqq");G(U,ke,Ee,"\u22E6","\\lnsim",!0);G(U,ke,Ee,"\u2A89","\\lnapprox",!0);G(U,ke,Ee,"\u2280","\\nprec",!0);G(U,ke,Ee,"\u22E0","\\npreceq",!0);G(U,ke,Ee,"\u22E8","\\precnsim",!0);G(U,ke,Ee,"\u2AB9","\\precnapprox",!0);G(U,ke,Ee,"\u2241","\\nsim",!0);G(U,ke,Ee,"\uE006","\\@nshortmid");G(U,ke,Ee,"\u2224","\\nmid",!0);G(U,ke,Ee,"\u22AC","\\nvdash",!0);G(U,ke,Ee,"\u22AD","\\nvDash",!0);G(U,ke,Ee,"\u22EA","\\ntriangleleft");G(U,ke,Ee,"\u22EC","\\ntrianglelefteq",!0);G(U,ke,Ee,"\u228A","\\subsetneq",!0);G(U,ke,Ee,"\uE01A","\\@varsubsetneq");G(U,ke,Ee,"\u2ACB","\\subsetneqq",!0);G(U,ke,Ee,"\uE017","\\@varsubsetneqq");G(U,ke,Ee,"\u226F","\\ngtr",!0);G(U,ke,Ee,"\uE00F","\\@ngeqslant");G(U,ke,Ee,"\uE00E","\\@ngeqq");G(U,ke,Ee,"\u2A88","\\gneq",!0);G(U,ke,Ee,"\u2269","\\gneqq",!0);G(U,ke,Ee,"\uE00D","\\@gvertneqq");G(U,ke,Ee,"\u22E7","\\gnsim",!0);G(U,ke,Ee,"\u2A8A","\\gnapprox",!0);G(U,ke,Ee,"\u2281","\\nsucc",!0);G(U,ke,Ee,"\u22E1","\\nsucceq",!0);G(U,ke,Ee,"\u22E9","\\succnsim",!0);G(U,ke,Ee,"\u2ABA","\\succnapprox",!0);G(U,ke,Ee,"\u2246","\\ncong",!0);G(U,ke,Ee,"\uE007","\\@nshortparallel");G(U,ke,Ee,"\u2226","\\nparallel",!0);G(U,ke,Ee,"\u22AF","\\nVDash",!0);G(U,ke,Ee,"\u22EB","\\ntriangleright");G(U,ke,Ee,"\u22ED","\\ntrianglerighteq",!0);G(U,ke,Ee,"\uE018","\\@nsupseteqq");G(U,ke,Ee,"\u228B","\\supsetneq",!0);G(U,ke,Ee,"\uE01B","\\@varsupsetneq");G(U,ke,Ee,"\u2ACC","\\supsetneqq",!0);G(U,ke,Ee,"\uE019","\\@varsupsetneqq");G(U,ke,Ee,"\u22AE","\\nVdash",!0);G(U,ke,Ee,"\u2AB5","\\precneqq",!0);G(U,ke,Ee,"\u2AB6","\\succneqq",!0);G(U,ke,Ee,"\uE016","\\@nsubseteqq");G(U,ke,It,"\u22B4","\\unlhd");G(U,ke,It,"\u22B5","\\unrhd");G(U,ke,Ee,"\u219A","\\nleftarrow",!0);G(U,ke,Ee,"\u219B","\\nrightarrow",!0);G(U,ke,Ee,"\u21CD","\\nLeftarrow",!0);G(U,ke,Ee,"\u21CF","\\nRightarrow",!0);G(U,ke,Ee,"\u21AE","\\nleftrightarrow",!0);G(U,ke,Ee,"\u21CE","\\nLeftrightarrow",!0);G(U,ke,Ee,"\u25B3","\\vartriangle");G(U,ke,Le,"\u210F","\\hslash");G(U,ke,Le,"\u25BD","\\triangledown");G(U,ke,Le,"\u25CA","\\lozenge");G(U,ke,Le,"\u24C8","\\circledS");G(U,ke,Le,"\xAE","\\circledR");G(it,ke,Le,"\xAE","\\circledR");G(U,ke,Le,"\u2221","\\measuredangle",!0);G(U,ke,Le,"\u2204","\\nexists");G(U,ke,Le,"\u2127","\\mho");G(U,ke,Le,"\u2132","\\Finv",!0);G(U,ke,Le,"\u2141","\\Game",!0);G(U,ke,Le,"\u2035","\\backprime");G(U,ke,Le,"\u25B2","\\blacktriangle");G(U,ke,Le,"\u25BC","\\blacktriangledown");G(U,ke,Le,"\u25A0","\\blacksquare");G(U,ke,Le,"\u29EB","\\blacklozenge");G(U,ke,Le,"\u2605","\\bigstar");G(U,ke,Le,"\u2222","\\sphericalangle",!0);G(U,ke,Le,"\u2201","\\complement",!0);G(U,ke,Le,"\xF0","\\eth",!0);G(it,ee,Le,"\xF0","\xF0");G(U,ke,Le,"\u2571","\\diagup");G(U,ke,Le,"\u2572","\\diagdown");G(U,ke,Le,"\u25A1","\\square");G(U,ke,Le,"\u25A1","\\Box");G(U,ke,Le,"\u25CA","\\Diamond");G(U,ke,Le,"\xA5","\\yen",!0);G(it,ke,Le,"\xA5","\\yen",!0);G(U,ke,Le,"\u2713","\\checkmark",!0);G(it,ke,Le,"\u2713","\\checkmark");G(U,ke,Le,"\u2136","\\beth",!0);G(U,ke,Le,"\u2138","\\daleth",!0);G(U,ke,Le,"\u2137","\\gimel",!0);G(U,ke,Le,"\u03DD","\\digamma",!0);G(U,ke,Le,"\u03F0","\\varkappa");G(U,ke,js,"\u250C","\\@ulcorner",!0);G(U,ke,Za,"\u2510","\\@urcorner",!0);G(U,ke,js,"\u2514","\\@llcorner",!0);G(U,ke,Za,"\u2518","\\@lrcorner",!0);G(U,ke,Ee,"\u2266","\\leqq",!0);G(U,ke,Ee,"\u2A7D","\\leqslant",!0);G(U,ke,Ee,"\u2A95","\\eqslantless",!0);G(U,ke,Ee,"\u2272","\\lesssim",!0);G(U,ke,Ee,"\u2A85","\\lessapprox",!0);G(U,ke,Ee,"\u224A","\\approxeq",!0);G(U,ke,It,"\u22D6","\\lessdot");G(U,ke,Ee,"\u22D8","\\lll",!0);G(U,ke,Ee,"\u2276","\\lessgtr",!0);G(U,ke,Ee,"\u22DA","\\lesseqgtr",!0);G(U,ke,Ee,"\u2A8B","\\lesseqqgtr",!0);G(U,ke,Ee,"\u2251","\\doteqdot");G(U,ke,Ee,"\u2253","\\risingdotseq",!0);G(U,ke,Ee,"\u2252","\\fallingdotseq",!0);G(U,ke,Ee,"\u223D","\\backsim",!0);G(U,ke,Ee,"\u22CD","\\backsimeq",!0);G(U,ke,Ee,"\u2AC5","\\subseteqq",!0);G(U,ke,Ee,"\u22D0","\\Subset",!0);G(U,ke,Ee,"\u228F","\\sqsubset",!0);G(U,ke,Ee,"\u227C","\\preccurlyeq",!0);G(U,ke,Ee,"\u22DE","\\curlyeqprec",!0);G(U,ke,Ee,"\u227E","\\precsim",!0);G(U,ke,Ee,"\u2AB7","\\precapprox",!0);G(U,ke,Ee,"\u22B2","\\vartriangleleft");G(U,ke,Ee,"\u22B4","\\trianglelefteq");G(U,ke,Ee,"\u22A8","\\vDash",!0);G(U,ke,Ee,"\u22AA","\\Vvdash",!0);G(U,ke,Ee,"\u2323","\\smallsmile");G(U,ke,Ee,"\u2322","\\smallfrown");G(U,ke,Ee,"\u224F","\\bumpeq",!0);G(U,ke,Ee,"\u224E","\\Bumpeq",!0);G(U,ke,Ee,"\u2267","\\geqq",!0);G(U,ke,Ee,"\u2A7E","\\geqslant",!0);G(U,ke,Ee,"\u2A96","\\eqslantgtr",!0);G(U,ke,Ee,"\u2273","\\gtrsim",!0);G(U,ke,Ee,"\u2A86","\\gtrapprox",!0);G(U,ke,It,"\u22D7","\\gtrdot");G(U,ke,Ee,"\u22D9","\\ggg",!0);G(U,ke,Ee,"\u2277","\\gtrless",!0);G(U,ke,Ee,"\u22DB","\\gtreqless",!0);G(U,ke,Ee,"\u2A8C","\\gtreqqless",!0);G(U,ke,Ee,"\u2256","\\eqcirc",!0);G(U,ke,Ee,"\u2257","\\circeq",!0);G(U,ke,Ee,"\u225C","\\triangleq",!0);G(U,ke,Ee,"\u223C","\\thicksim");G(U,ke,Ee,"\u2248","\\thickapprox");G(U,ke,Ee,"\u2AC6","\\supseteqq",!0);G(U,ke,Ee,"\u22D1","\\Supset",!0);G(U,ke,Ee,"\u2290","\\sqsupset",!0);G(U,ke,Ee,"\u227D","\\succcurlyeq",!0);G(U,ke,Ee,"\u22DF","\\curlyeqsucc",!0);G(U,ke,Ee,"\u227F","\\succsim",!0);G(U,ke,Ee,"\u2AB8","\\succapprox",!0);G(U,ke,Ee,"\u22B3","\\vartriangleright");G(U,ke,Ee,"\u22B5","\\trianglerighteq");G(U,ke,Ee,"\u22A9","\\Vdash",!0);G(U,ke,Ee,"\u2223","\\shortmid");G(U,ke,Ee,"\u2225","\\shortparallel");G(U,ke,Ee,"\u226C","\\between",!0);G(U,ke,Ee,"\u22D4","\\pitchfork",!0);G(U,ke,Ee,"\u221D","\\varpropto");G(U,ke,Ee,"\u25C0","\\blacktriangleleft");G(U,ke,Ee,"\u2234","\\therefore",!0);G(U,ke,Ee,"\u220D","\\backepsilon");G(U,ke,Ee,"\u25B6","\\blacktriangleright");G(U,ke,Ee,"\u2235","\\because",!0);G(U,ke,Ee,"\u22D8","\\llless");G(U,ke,Ee,"\u22D9","\\gggtr");G(U,ke,It,"\u22B2","\\lhd");G(U,ke,It,"\u22B3","\\rhd");G(U,ke,Ee,"\u2242","\\eqsim",!0);G(U,ee,Ee,"\u22C8","\\Join");G(U,ke,Ee,"\u2251","\\Doteq",!0);G(U,ke,It,"\u2214","\\dotplus",!0);G(U,ke,It,"\u2216","\\smallsetminus");G(U,ke,It,"\u22D2","\\Cap",!0);G(U,ke,It,"\u22D3","\\Cup",!0);G(U,ke,It,"\u2A5E","\\doublebarwedge",!0);G(U,ke,It,"\u229F","\\boxminus",!0);G(U,ke,It,"\u229E","\\boxplus",!0);G(U,ke,It,"\u22C7","\\divideontimes",!0);G(U,ke,It,"\u22C9","\\ltimes",!0);G(U,ke,It,"\u22CA","\\rtimes",!0);G(U,ke,It,"\u22CB","\\leftthreetimes",!0);G(U,ke,It,"\u22CC","\\rightthreetimes",!0);G(U,ke,It,"\u22CF","\\curlywedge",!0);G(U,ke,It,"\u22CE","\\curlyvee",!0);G(U,ke,It,"\u229D","\\circleddash",!0);G(U,ke,It,"\u229B","\\circledast",!0);G(U,ke,It,"\u22C5","\\centerdot");G(U,ke,It,"\u22BA","\\intercal",!0);G(U,ke,It,"\u22D2","\\doublecap");G(U,ke,It,"\u22D3","\\doublecup");G(U,ke,It,"\u22A0","\\boxtimes",!0);G(U,ke,Ee,"\u21E2","\\dashrightarrow",!0);G(U,ke,Ee,"\u21E0","\\dashleftarrow",!0);G(U,ke,Ee,"\u21C7","\\leftleftarrows",!0);G(U,ke,Ee,"\u21C6","\\leftrightarrows",!0);G(U,ke,Ee,"\u21DA","\\Lleftarrow",!0);G(U,ke,Ee,"\u219E","\\twoheadleftarrow",!0);G(U,ke,Ee,"\u21A2","\\leftarrowtail",!0);G(U,ke,Ee,"\u21AB","\\looparrowleft",!0);G(U,ke,Ee,"\u21CB","\\leftrightharpoons",!0);G(U,ke,Ee,"\u21B6","\\curvearrowleft",!0);G(U,ke,Ee,"\u21BA","\\circlearrowleft",!0);G(U,ke,Ee,"\u21B0","\\Lsh",!0);G(U,ke,Ee,"\u21C8","\\upuparrows",!0);G(U,ke,Ee,"\u21BF","\\upharpoonleft",!0);G(U,ke,Ee,"\u21C3","\\downharpoonleft",!0);G(U,ee,Ee,"\u22B6","\\origof",!0);G(U,ee,Ee,"\u22B7","\\imageof",!0);G(U,ke,Ee,"\u22B8","\\multimap",!0);G(U,ke,Ee,"\u21AD","\\leftrightsquigarrow",!0);G(U,ke,Ee,"\u21C9","\\rightrightarrows",!0);G(U,ke,Ee,"\u21C4","\\rightleftarrows",!0);G(U,ke,Ee,"\u21A0","\\twoheadrightarrow",!0);G(U,ke,Ee,"\u21A3","\\rightarrowtail",!0);G(U,ke,Ee,"\u21AC","\\looparrowright",!0);G(U,ke,Ee,"\u21B7","\\curvearrowright",!0);G(U,ke,Ee,"\u21BB","\\circlearrowright",!0);G(U,ke,Ee,"\u21B1","\\Rsh",!0);G(U,ke,Ee,"\u21CA","\\downdownarrows",!0);G(U,ke,Ee,"\u21BE","\\upharpoonright",!0);G(U,ke,Ee,"\u21C2","\\downharpoonright",!0);G(U,ke,Ee,"\u21DD","\\rightsquigarrow",!0);G(U,ke,Ee,"\u21DD","\\leadsto");G(U,ke,Ee,"\u21DB","\\Rrightarrow",!0);G(U,ke,Ee,"\u21BE","\\restriction");G(U,ee,Le,"\u2018","`");G(U,ee,Le,"$","\\$");G(it,ee,Le,"$","\\$");G(it,ee,Le,"$","\\textdollar");G(U,ee,Le,"%","\\%");G(it,ee,Le,"%","\\%");G(U,ee,Le,"_","\\_");G(it,ee,Le,"_","\\_");G(it,ee,Le,"_","\\textunderscore");G(U,ee,Le,"\u2220","\\angle",!0);G(U,ee,Le,"\u221E","\\infty",!0);G(U,ee,Le,"\u2032","\\prime");G(U,ee,Le,"\u25B3","\\triangle");G(U,ee,Le,"\u0393","\\Gamma",!0);G(U,ee,Le,"\u0394","\\Delta",!0);G(U,ee,Le,"\u0398","\\Theta",!0);G(U,ee,Le,"\u039B","\\Lambda",!0);G(U,ee,Le,"\u039E","\\Xi",!0);G(U,ee,Le,"\u03A0","\\Pi",!0);G(U,ee,Le,"\u03A3","\\Sigma",!0);G(U,ee,Le,"\u03A5","\\Upsilon",!0);G(U,ee,Le,"\u03A6","\\Phi",!0);G(U,ee,Le,"\u03A8","\\Psi",!0);G(U,ee,Le,"\u03A9","\\Omega",!0);G(U,ee,Le,"A","\u0391");G(U,ee,Le,"B","\u0392");G(U,ee,Le,"E","\u0395");G(U,ee,Le,"Z","\u0396");G(U,ee,Le,"H","\u0397");G(U,ee,Le,"I","\u0399");G(U,ee,Le,"K","\u039A");G(U,ee,Le,"M","\u039C");G(U,ee,Le,"N","\u039D");G(U,ee,Le,"O","\u039F");G(U,ee,Le,"P","\u03A1");G(U,ee,Le,"T","\u03A4");G(U,ee,Le,"X","\u03A7");G(U,ee,Le,"\xAC","\\neg",!0);G(U,ee,Le,"\xAC","\\lnot");G(U,ee,Le,"\u22A4","\\top");G(U,ee,Le,"\u22A5","\\bot");G(U,ee,Le,"\u2205","\\emptyset");G(U,ke,Le,"\u2205","\\varnothing");G(U,ee,er,"\u03B1","\\alpha",!0);G(U,ee,er,"\u03B2","\\beta",!0);G(U,ee,er,"\u03B3","\\gamma",!0);G(U,ee,er,"\u03B4","\\delta",!0);G(U,ee,er,"\u03F5","\\epsilon",!0);G(U,ee,er,"\u03B6","\\zeta",!0);G(U,ee,er,"\u03B7","\\eta",!0);G(U,ee,er,"\u03B8","\\theta",!0);G(U,ee,er,"\u03B9","\\iota",!0);G(U,ee,er,"\u03BA","\\kappa",!0);G(U,ee,er,"\u03BB","\\lambda",!0);G(U,ee,er,"\u03BC","\\mu",!0);G(U,ee,er,"\u03BD","\\nu",!0);G(U,ee,er,"\u03BE","\\xi",!0);G(U,ee,er,"\u03BF","\\omicron",!0);G(U,ee,er,"\u03C0","\\pi",!0);G(U,ee,er,"\u03C1","\\rho",!0);G(U,ee,er,"\u03C3","\\sigma",!0);G(U,ee,er,"\u03C4","\\tau",!0);G(U,ee,er,"\u03C5","\\upsilon",!0);G(U,ee,er,"\u03D5","\\phi",!0);G(U,ee,er,"\u03C7","\\chi",!0);G(U,ee,er,"\u03C8","\\psi",!0);G(U,ee,er,"\u03C9","\\omega",!0);G(U,ee,er,"\u03B5","\\varepsilon",!0);G(U,ee,er,"\u03D1","\\vartheta",!0);G(U,ee,er,"\u03D6","\\varpi",!0);G(U,ee,er,"\u03F1","\\varrho",!0);G(U,ee,er,"\u03C2","\\varsigma",!0);G(U,ee,er,"\u03C6","\\varphi",!0);G(U,ee,It,"\u2217","*",!0);G(U,ee,It,"+","+");G(U,ee,It,"\u2212","-",!0);G(U,ee,It,"\u22C5","\\cdot",!0);G(U,ee,It,"\u2218","\\circ",!0);G(U,ee,It,"\xF7","\\div",!0);G(U,ee,It,"\xB1","\\pm",!0);G(U,ee,It,"\xD7","\\times",!0);G(U,ee,It,"\u2229","\\cap",!0);G(U,ee,It,"\u222A","\\cup",!0);G(U,ee,It,"\u2216","\\setminus",!0);G(U,ee,It,"\u2227","\\land");G(U,ee,It,"\u2228","\\lor");G(U,ee,It,"\u2227","\\wedge",!0);G(U,ee,It,"\u2228","\\vee",!0);G(U,ee,Le,"\u221A","\\surd");G(U,ee,js,"\u27E8","\\langle",!0);G(U,ee,js,"\u2223","\\lvert");G(U,ee,js,"\u2225","\\lVert");G(U,ee,Za,"?","?");G(U,ee,Za,"!","!");G(U,ee,Za,"\u27E9","\\rangle",!0);G(U,ee,Za,"\u2223","\\rvert");G(U,ee,Za,"\u2225","\\rVert");G(U,ee,Ee,"=","=");G(U,ee,Ee,":",":");G(U,ee,Ee,"\u2248","\\approx",!0);G(U,ee,Ee,"\u2245","\\cong",!0);G(U,ee,Ee,"\u2265","\\ge");G(U,ee,Ee,"\u2265","\\geq",!0);G(U,ee,Ee,"\u2190","\\gets");G(U,ee,Ee,">","\\gt",!0);G(U,ee,Ee,"\u2208","\\in",!0);G(U,ee,Ee,"\uE020","\\@not");G(U,ee,Ee,"\u2282","\\subset",!0);G(U,ee,Ee,"\u2283","\\supset",!0);G(U,ee,Ee,"\u2286","\\subseteq",!0);G(U,ee,Ee,"\u2287","\\supseteq",!0);G(U,ke,Ee,"\u2288","\\nsubseteq",!0);G(U,ke,Ee,"\u2289","\\nsupseteq",!0);G(U,ee,Ee,"\u22A8","\\models");G(U,ee,Ee,"\u2190","\\leftarrow",!0);G(U,ee,Ee,"\u2264","\\le");G(U,ee,Ee,"\u2264","\\leq",!0);G(U,ee,Ee,"<","\\lt",!0);G(U,ee,Ee,"\u2192","\\rightarrow",!0);G(U,ee,Ee,"\u2192","\\to");G(U,ke,Ee,"\u2271","\\ngeq",!0);G(U,ke,Ee,"\u2270","\\nleq",!0);G(U,ee,uu,"\xA0","\\ ");G(U,ee,uu,"\xA0","\\space");G(U,ee,uu,"\xA0","\\nobreakspace");G(it,ee,uu,"\xA0","\\ ");G(it,ee,uu,"\xA0"," ");G(it,ee,uu,"\xA0","\\space");G(it,ee,uu,"\xA0","\\nobreakspace");G(U,ee,uu,null,"\\nobreak");G(U,ee,uu,null,"\\allowbreak");G(U,ee,x3,",",",");G(U,ee,x3,";",";");G(U,ke,It,"\u22BC","\\barwedge",!0);G(U,ke,It,"\u22BB","\\veebar",!0);G(U,ee,It,"\u2299","\\odot",!0);G(U,ee,It,"\u2295","\\oplus",!0);G(U,ee,It,"\u2297","\\otimes",!0);G(U,ee,Le,"\u2202","\\partial",!0);G(U,ee,It,"\u2298","\\oslash",!0);G(U,ke,It,"\u229A","\\circledcirc",!0);G(U,ke,It,"\u22A1","\\boxdot",!0);G(U,ee,It,"\u25B3","\\bigtriangleup");G(U,ee,It,"\u25BD","\\bigtriangledown");G(U,ee,It,"\u2020","\\dagger");G(U,ee,It,"\u22C4","\\diamond");G(U,ee,It,"\u22C6","\\star");G(U,ee,It,"\u25C3","\\triangleleft");G(U,ee,It,"\u25B9","\\triangleright");G(U,ee,js,"{","\\{");G(it,ee,Le,"{","\\{");G(it,ee,Le,"{","\\textbraceleft");G(U,ee,Za,"}","\\}");G(it,ee,Le,"}","\\}");G(it,ee,Le,"}","\\textbraceright");G(U,ee,js,"{","\\lbrace");G(U,ee,Za,"}","\\rbrace");G(U,ee,js,"[","\\lbrack",!0);G(it,ee,Le,"[","\\lbrack",!0);G(U,ee,Za,"]","\\rbrack",!0);G(it,ee,Le,"]","\\rbrack",!0);G(U,ee,js,"(","\\lparen",!0);G(U,ee,Za,")","\\rparen",!0);G(it,ee,Le,"<","\\textless",!0);G(it,ee,Le,">","\\textgreater",!0);G(U,ee,js,"\u230A","\\lfloor",!0);G(U,ee,Za,"\u230B","\\rfloor",!0);G(U,ee,js,"\u2308","\\lceil",!0);G(U,ee,Za,"\u2309","\\rceil",!0);G(U,ee,Le,"\\","\\backslash");G(U,ee,Le,"\u2223","|");G(U,ee,Le,"\u2223","\\vert");G(it,ee,Le,"|","\\textbar",!0);G(U,ee,Le,"\u2225","\\|");G(U,ee,Le,"\u2225","\\Vert");G(it,ee,Le,"\u2225","\\textbardbl");G(it,ee,Le,"~","\\textasciitilde");G(it,ee,Le,"\\","\\textbackslash");G(it,ee,Le,"^","\\textasciicircum");G(U,ee,Ee,"\u2191","\\uparrow",!0);G(U,ee,Ee,"\u21D1","\\Uparrow",!0);G(U,ee,Ee,"\u2193","\\downarrow",!0);G(U,ee,Ee,"\u21D3","\\Downarrow",!0);G(U,ee,Ee,"\u2195","\\updownarrow",!0);G(U,ee,Ee,"\u21D5","\\Updownarrow",!0);G(U,ee,ki,"\u2210","\\coprod");G(U,ee,ki,"\u22C1","\\bigvee");G(U,ee,ki,"\u22C0","\\bigwedge");G(U,ee,ki,"\u2A04","\\biguplus");G(U,ee,ki,"\u22C2","\\bigcap");G(U,ee,ki,"\u22C3","\\bigcup");G(U,ee,ki,"\u222B","\\int");G(U,ee,ki,"\u222B","\\intop");G(U,ee,ki,"\u222C","\\iint");G(U,ee,ki,"\u222D","\\iiint");G(U,ee,ki,"\u220F","\\prod");G(U,ee,ki,"\u2211","\\sum");G(U,ee,ki,"\u2A02","\\bigotimes");G(U,ee,ki,"\u2A01","\\bigoplus");G(U,ee,ki,"\u2A00","\\bigodot");G(U,ee,ki,"\u222E","\\oint");G(U,ee,ki,"\u222F","\\oiint");G(U,ee,ki,"\u2230","\\oiiint");G(U,ee,ki,"\u2A06","\\bigsqcup");G(U,ee,ki,"\u222B","\\smallint");G(it,ee,p0,"\u2026","\\textellipsis");G(U,ee,p0,"\u2026","\\mathellipsis");G(it,ee,p0,"\u2026","\\ldots",!0);G(U,ee,p0,"\u2026","\\ldots",!0);G(U,ee,p0,"\u22EF","\\@cdots",!0);G(U,ee,p0,"\u22F1","\\ddots",!0);G(U,ee,Le,"\u22EE","\\varvdots");G(U,ee,Vn,"\u02CA","\\acute");G(U,ee,Vn,"\u02CB","\\grave");G(U,ee,Vn,"\xA8","\\ddot");G(U,ee,Vn,"~","\\tilde");G(U,ee,Vn,"\u02C9","\\bar");G(U,ee,Vn,"\u02D8","\\breve");G(U,ee,Vn,"\u02C7","\\check");G(U,ee,Vn,"^","\\hat");G(U,ee,Vn,"\u20D7","\\vec");G(U,ee,Vn,"\u02D9","\\dot");G(U,ee,Vn,"\u02DA","\\mathring");G(U,ee,er,"\uE131","\\@imath");G(U,ee,er,"\uE237","\\@jmath");G(U,ee,Le,"\u0131","\u0131");G(U,ee,Le,"\u0237","\u0237");G(it,ee,Le,"\u0131","\\i",!0);G(it,ee,Le,"\u0237","\\j",!0);G(it,ee,Le,"\xDF","\\ss",!0);G(it,ee,Le,"\xE6","\\ae",!0);G(it,ee,Le,"\u0153","\\oe",!0);G(it,ee,Le,"\xF8","\\o",!0);G(it,ee,Le,"\xC6","\\AE",!0);G(it,ee,Le,"\u0152","\\OE",!0);G(it,ee,Le,"\xD8","\\O",!0);G(it,ee,Vn,"\u02CA","\\'");G(it,ee,Vn,"\u02CB","\\`");G(it,ee,Vn,"\u02C6","\\^");G(it,ee,Vn,"\u02DC","\\~");G(it,ee,Vn,"\u02C9","\\=");G(it,ee,Vn,"\u02D8","\\u");G(it,ee,Vn,"\u02D9","\\.");G(it,ee,Vn,"\xB8","\\c");G(it,ee,Vn,"\u02DA","\\r");G(it,ee,Vn,"\u02C7","\\v");G(it,ee,Vn,"\xA8",'\\"');G(it,ee,Vn,"\u02DD","\\H");G(it,ee,Vn,"\u25EF","\\textcircled");Hz={"--":!0,"---":!0,"``":!0,"''":!0};G(it,ee,Le,"\u2013","--",!0);G(it,ee,Le,"\u2013","\\textendash");G(it,ee,Le,"\u2014","---",!0);G(it,ee,Le,"\u2014","\\textemdash");G(it,ee,Le,"\u2018","`",!0);G(it,ee,Le,"\u2018","\\textquoteleft");G(it,ee,Le,"\u2019","'",!0);G(it,ee,Le,"\u2019","\\textquoteright");G(it,ee,Le,"\u201C","``",!0);G(it,ee,Le,"\u201C","\\textquotedblleft");G(it,ee,Le,"\u201D","''",!0);G(it,ee,Le,"\u201D","\\textquotedblright");G(U,ee,Le,"\xB0","\\degree",!0);G(it,ee,Le,"\xB0","\\degree");G(it,ee,Le,"\xB0","\\textdegree",!0);G(U,ee,Le,"\xA3","\\pounds");G(U,ee,Le,"\xA3","\\mathsterling",!0);G(it,ee,Le,"\xA3","\\pounds");G(it,ee,Le,"\xA3","\\textsterling",!0);G(U,ke,Le,"\u2720","\\maltese");G(it,ke,Le,"\u2720","\\maltese");fz='0123456789/@."';for(J4=0;J4<fz.length;J4++)f7=fz.charAt(J4),G(U,ee,Le,f7,f7);dz='0123456789!@*()-=+";:?/.,';for(e3=0;e3<dz.length;e3++)d7=dz.charAt(e3),G(it,ee,Le,d7,d7);d3="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";for(t3=0;t3<d3.length;t3++)Py=d3.charAt(t3),G(U,ee,er,Py,Py),G(it,ee,Le,Py,Py);G(U,ke,Le,"C","\u2102");G(it,ke,Le,"C","\u2102");G(U,ke,Le,"H","\u210D");G(it,ke,Le,"H","\u210D");G(U,ke,Le,"N","\u2115");G(it,ke,Le,"N","\u2115");G(U,ke,Le,"P","\u2119");G(it,ke,Le,"P","\u2119");G(U,ke,Le,"Q","\u211A");G(it,ke,Le,"Q","\u211A");G(U,ke,Le,"R","\u211D");G(it,ke,Le,"R","\u211D");G(U,ke,Le,"Z","\u2124");G(it,ke,Le,"Z","\u2124");G(U,ee,er,"h","\u210E");G(it,ee,er,"h","\u210E");sr="";for(Ca=0;Ca<d3.length;Ca++)Jn=d3.charAt(Ca),sr=String.fromCharCode(55349,56320+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56372+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56424+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56580+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56684+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56736+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56788+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56840+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56944+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),Ca<26&&(sr=String.fromCharCode(55349,56632+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr),sr=String.fromCharCode(55349,56476+Ca),G(U,ee,er,Jn,sr),G(it,ee,Le,Jn,sr));sr="\u{1D55C}";G(U,ee,er,"k",sr);G(it,ee,Le,"k",sr);for(uh=0;uh<10;uh++)iu=uh.toString(),sr=String.fromCharCode(55349,57294+uh),G(U,ee,er,iu,sr),G(it,ee,Le,iu,sr),sr=String.fromCharCode(55349,57314+uh),G(U,ee,er,iu,sr),G(it,ee,Le,iu,sr),sr=String.fromCharCode(55349,57324+uh),G(U,ee,er,iu,sr),G(it,ee,Le,iu,sr),sr=String.fromCharCode(55349,57334+uh),G(U,ee,er,iu,sr),G(it,ee,Le,iu,sr);C7="\xD0\xDE\xFE";for(r3=0;r3<C7.length;r3++)By=C7.charAt(r3),G(U,ee,er,By,By),G(it,ee,Le,By,By);n3=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],pz=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Obe=o(function(e,r){var n=e.charCodeAt(0),i=e.charCodeAt(1),a=(n-55296)*1024+(i-56320)+65536,s=r==="math"?0:1;if(119808<=a&&a<120484){var l=Math.floor((a-119808)/26);return[n3[l][2],n3[l][s]]}else if(120782<=a&&a<=120831){var u=Math.floor((a-120782)/10);return[pz[u][2],pz[u][s]]}else{if(a===120485||a===120486)return[n3[0][2],n3[0][s]];if(120486<a&&a<120782)return["",""];throw new gt("Unsupported character: "+e)}},"wideCharacterFont"),b3=o(function(e,r,n){return An[n][e]&&An[n][e].replace&&(e=An[n][e].replace),{value:e,metrics:P7(e,r,n)}},"lookupSymbol"),ol=o(function(e,r,n,i,a){var s=b3(e,r,n),l=s.metrics;e=s.value;var u;if(l){var h=l.italic;(n==="text"||i&&i.font==="mathit")&&(h=0),u=new Ts(e,l.height,l.depth,h,l.skew,l.width,a)}else typeof console<"u"&&console.warn("No character metrics "+("for '"+e+"' in style '"+r+"' and mode '"+n+"'")),u=new Ts(e,0,0,0,0,0,a);if(i){u.maxFontSize=i.sizeMultiplier,i.style.isTight()&&u.classes.push("mtight");var f=i.getColor();f&&(u.style.color=f)}return u},"makeSymbol"),Pbe=o(function(e,r,n,i){return i===void 0&&(i=[]),n.font==="boldsymbol"&&b3(e,"Main-Bold",r).metrics?ol(e,"Main-Bold",r,n,i.concat(["mathbf"])):e==="\\"||An[r][e].font==="main"?ol(e,"Main-Regular",r,n,i):ol(e,"AMS-Regular",r,n,i.concat(["amsrm"]))},"mathsym"),Bbe=o(function(e,r,n,i,a){return a!=="textord"&&b3(e,"Math-BoldItalic",r).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}},"boldsymbol"),Fbe=o(function(e,r,n){var i=e.mode,a=e.text,s=["mord"],l=i==="math"||i==="text"&&r.font,u=l?r.font:r.fontFamily,h="",f="";if(a.charCodeAt(0)===55349&&([h,f]=Obe(a,i)),h.length>0)return ol(a,h,i,r,s.concat(f));if(u){var d,p;if(u==="boldsymbol"){var m=Bbe(a,i,r,s,n);d=m.fontName,p=[m.fontClass]}else l?(d=Yz[u].fontName,p=[u]):(d=i3(u,r.fontWeight,r.fontShape),p=[u,r.fontWeight,r.fontShape]);if(b3(a,d,i).metrics)return ol(a,d,i,r,s.concat(p));if(Hz.hasOwnProperty(a)&&d.slice(0,10)==="Typewriter"){for(var g=[],y=0;y<a.length;y++)g.push(ol(a[y],d,i,r,s.concat(p)));return qz(g)}}if(n==="mathord")return ol(a,"Math-Italic",i,r,s.concat(["mathnormal"]));if(n==="textord"){var v=An[i][a]&&An[i][a].font;if(v==="ams"){var x=i3("amsrm",r.fontWeight,r.fontShape);return ol(a,x,i,r,s.concat("amsrm",r.fontWeight,r.fontShape))}else if(v==="main"||!v){var b=i3("textrm",r.fontWeight,r.fontShape);return ol(a,b,i,r,s.concat(r.fontWeight,r.fontShape))}else{var w=i3(v,r.fontWeight,r.fontShape);return ol(a,w,i,r,s.concat(w,r.fontWeight,r.fontShape))}}else throw new Error("unexpected type: "+n+" in makeOrd")},"makeOrd"),$be=o((t,e)=>{if(fh(t.classes)!==fh(e.classes)||t.skew!==e.skew||t.maxFontSize!==e.maxFontSize)return!1;if(t.classes.length===1){var r=t.classes[0];if(r==="mbin"||r==="mord")return!1}for(var n in t.style)if(t.style.hasOwnProperty(n)&&t.style[n]!==e.style[n])return!1;for(var i in e.style)if(e.style.hasOwnProperty(i)&&t.style[i]!==e.style[i])return!1;return!0},"canCombine"),zbe=o(t=>{for(var e=0;e<t.length-1;e++){var r=t[e],n=t[e+1];r instanceof Ts&&n instanceof Ts&&$be(r,n)&&(r.text+=n.text,r.height=Math.max(r.height,n.height),r.depth=Math.max(r.depth,n.depth),r.italic=n.italic,t.splice(e+1,1),e--)}return t},"tryCombineChars"),B7=o(function(e){for(var r=0,n=0,i=0,a=0;a<e.children.length;a++){var s=e.children[a];s.height>r&&(r=s.height),s.depth>n&&(n=s.depth),s.maxFontSize>i&&(i=s.maxFontSize)}e.height=r,e.depth=n,e.maxFontSize=i},"sizeElementFromChildren"),bs=o(function(e,r,n,i){var a=new td(e,r,n,i);return B7(a),a},"makeSpan"),Wz=o((t,e,r,n)=>new td(t,e,r,n),"makeSvgSpan"),Gbe=o(function(e,r,n){var i=bs([e],[],r);return i.height=Math.max(n||r.fontMetrics().defaultRuleThickness,r.minRuleThickness),i.style.borderBottomWidth=kt(i.height),i.maxFontSize=1,i},"makeLineSpan"),Vbe=o(function(e,r,n,i){var a=new Vy(e,r,n,i);return B7(a),a},"makeAnchor"),qz=o(function(e){var r=new ed(e);return B7(r),r},"makeFragment"),Ube=o(function(e,r){return e instanceof ed?bs([],[e],r):e},"wrapFragment"),Hbe=o(function(e){if(e.positionType==="individualShift"){for(var r=e.children,n=[r[0]],i=-r[0].shift-r[0].elem.depth,a=i,s=1;s<r.length;s++){var l=-r[s].shift-a-r[s].elem.depth,u=l-(r[s-1].elem.height+r[s-1].elem.depth);a=a+l,n.push({type:"kern",size:u}),n.push(r[s])}return{children:n,depth:i}}var h;if(e.positionType==="top"){for(var f=e.positionData,d=0;d<e.children.length;d++){var p=e.children[d];f-=p.type==="kern"?p.size:p.elem.height+p.elem.depth}h=f}else if(e.positionType==="bottom")h=-e.positionData;else{var m=e.children[0];if(m.type!=="elem")throw new Error('First child must have type "elem".');if(e.positionType==="shift")h=-m.elem.depth-e.positionData;else if(e.positionType==="firstBaseline")h=-m.elem.depth;else throw new Error("Invalid positionType "+e.positionType+".")}return{children:e.children,depth:h}},"getVListChildrenAndDepth"),Wbe=o(function(e,r){for(var{children:n,depth:i}=Hbe(e),a=0,s=0;s<n.length;s++){var l=n[s];if(l.type==="elem"){var u=l.elem;a=Math.max(a,u.maxFontSize,u.height)}}a+=2;var h=bs(["pstrut"],[]);h.style.height=kt(a);for(var f=[],d=i,p=i,m=i,g=0;g<n.length;g++){var y=n[g];if(y.type==="kern")m+=y.size;else{var v=y.elem,x=y.wrapperClasses||[],b=y.wrapperStyle||{},w=bs(x,[h,v],void 0,b);w.style.top=kt(-a-m-v.depth),y.marginLeft&&(w.style.marginLeft=y.marginLeft),y.marginRight&&(w.style.marginRight=y.marginRight),f.push(w),m+=v.height+v.depth}d=Math.min(d,m),p=Math.max(p,m)}var C=bs(["vlist"],f);C.style.height=kt(p);var T;if(d<0){var E=bs([],[]),A=bs(["vlist"],[E]);A.style.height=kt(-d);var S=bs(["vlist-s"],[new Ts("\u200B")]);T=[bs(["vlist-r"],[C,S]),bs(["vlist-r"],[A])]}else T=[bs(["vlist-r"],[C])];var _=bs(["vlist-t"],T);return T.length===2&&_.classes.push("vlist-t2"),_.height=p,_.depth=-d,_},"makeVList"),qbe=o((t,e)=>{var r=bs(["mspace"],[],e),n=ti(t,e);return r.style.marginRight=kt(n),r},"makeGlue"),i3=o(function(e,r,n){var i="";switch(e){case"amsrm":i="AMS";break;case"textrm":i="Main";break;case"textsf":i="SansSerif";break;case"texttt":i="Typewriter";break;default:i=e}var a;return r==="textbf"&&n==="textit"?a="BoldItalic":r==="textbf"?a="Bold":r==="textit"?a="Italic":a="Regular",i+"-"+a},"retrieveTextFontName"),Yz={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Xz={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Ybe=o(function(e,r){var[n,i,a]=Xz[e],s=new Kl(n),l=new ll([s],{width:kt(i),height:kt(a),style:"width:"+kt(i),viewBox:"0 0 "+1e3*i+" "+1e3*a,preserveAspectRatio:"xMinYMin"}),u=Wz(["overlay"],[l],r);return u.height=a,u.style.height=kt(a),u.style.width=kt(i),u},"staticSvg"),Be={fontMap:Yz,makeSymbol:ol,mathsym:Pbe,makeSpan:bs,makeSvgSpan:Wz,makeLineSpan:Gbe,makeAnchor:Vbe,makeFragment:qz,wrapFragment:Ube,makeVList:Wbe,makeOrd:Fbe,makeGlue:qbe,staticSvg:Ybe,svgData:Xz,tryCombineChars:zbe},ei={number:3,unit:"mu"},Zf={number:4,unit:"mu"},au={number:5,unit:"mu"},Xbe={mord:{mop:ei,mbin:Zf,mrel:au,minner:ei},mop:{mord:ei,mop:ei,mrel:au,minner:ei},mbin:{mord:Zf,mop:Zf,mopen:Zf,minner:Zf},mrel:{mord:au,mop:au,mopen:au,minner:au},mopen:{},mclose:{mop:ei,mbin:Zf,mrel:au,minner:ei},mpunct:{mord:ei,mop:ei,mrel:au,mopen:ei,mclose:ei,mpunct:ei,minner:ei},minner:{mord:ei,mop:ei,mbin:Zf,mrel:au,mopen:ei,mpunct:ei,minner:ei}},jbe={mord:{mop:ei},mop:{mord:ei,mop:ei},mbin:{},mrel:{},mopen:{},mclose:{mop:ei},mpunct:{},minner:{mop:ei}},jz={},p3={},m3={};o(Nt,"defineFunction");o(rd,"defineFunctionBuilders");g3=o(function(e){return e.type==="ordgroup"&&e.body.length===1?e.body[0]:e},"normalizeArgument"),di=o(function(e){return e.type==="ordgroup"?e.body:[e]},"ordargument"),lu=Be.makeSpan,Kbe=["leftmost","mbin","mopen","mrel","mop","mpunct"],Qbe=["rightmost","mrel","mclose","mpunct"],Zbe={display:tr.DISPLAY,text:tr.TEXT,script:tr.SCRIPT,scriptscript:tr.SCRIPTSCRIPT},Jbe={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},Pi=o(function(e,r,n,i){i===void 0&&(i=[null,null]);for(var a=[],s=0;s<e.length;s++){var l=Fr(e[s],r);if(l instanceof ed){var u=l.children;a.push(...u)}else a.push(l)}if(Be.tryCombineChars(a),!n)return a;var h=r;if(e.length===1){var f=e[0];f.type==="sizing"?h=r.havingSize(f.size):f.type==="styling"&&(h=r.havingStyle(Zbe[f.style]))}var d=lu([i[0]||"leftmost"],[],r),p=lu([i[1]||"rightmost"],[],r),m=n==="root";return mz(a,(g,y)=>{var v=y.classes[0],x=g.classes[0];v==="mbin"&&Jt.contains(Qbe,x)?y.classes[0]="mord":x==="mbin"&&Jt.contains(Kbe,v)&&(g.classes[0]="mord")},{node:d},p,m),mz(a,(g,y)=>{var v=A7(y),x=A7(g),b=v&&x?g.hasClass("mtight")?jbe[v][x]:Xbe[v][x]:null;if(b)return Be.makeGlue(b,h)},{node:d},p,m),a},"buildExpression"),mz=o(function t(e,r,n,i,a){i&&e.push(i);for(var s=0;s<e.length;s++){var l=e[s],u=Kz(l);if(u){t(u.children,r,n,null,a);continue}var h=!l.hasClass("mspace");if(h){var f=r(l,n.node);f&&(n.insertAfter?n.insertAfter(f):(e.unshift(f),s++))}h?n.node=l:a&&l.hasClass("newline")&&(n.node=lu(["leftmost"])),n.insertAfter=(d=>p=>{e.splice(d+1,0,p),s++})(s)}i&&e.pop()},"traverseNonSpaceNodes"),Kz=o(function(e){return e instanceof ed||e instanceof Vy||e instanceof td&&e.hasClass("enclosing")?e:null},"checkPartialGroup"),e4e=o(function t(e,r){var n=Kz(e);if(n){var i=n.children;if(i.length){if(r==="right")return t(i[i.length-1],"right");if(r==="left")return t(i[0],"left")}}return e},"getOutermostNode"),A7=o(function(e,r){return e?(r&&(e=e4e(e,r)),Jbe[e.classes[0]]||null):null},"getTypeOfDomTree"),Hy=o(function(e,r){var n=["nulldelimiter"].concat(e.baseSizingClasses());return lu(r.concat(n))},"makeNullDelimiter"),Fr=o(function(e,r,n){if(!e)return lu();if(p3[e.type]){var i=p3[e.type](e,r);if(n&&r.size!==n.size){i=lu(r.sizingClasses(n),[i],r);var a=r.sizeMultiplier/n.sizeMultiplier;i.height*=a,i.depth*=a}return i}else throw new gt("Got group of unknown type: '"+e.type+"'")},"buildGroup");o(a3,"buildHTMLUnbreakable");o(_7,"buildHTML");o(Qz,"newDocumentFragment");ws=class{static{o(this,"MathNode")}constructor(e,r,n){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=r||[],this.classes=n||[]}setAttribute(e,r){this.attributes[e]=r}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&e.setAttribute(r,this.attributes[r]);this.classes.length>0&&(e.className=fh(this.classes));for(var n=0;n<this.children.length;n++)e.appendChild(this.children[n].toNode());return e}toMarkup(){var e="<"+this.type;for(var r in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,r)&&(e+=" "+r+'="',e+=Jt.escape(this.attributes[r]),e+='"');this.classes.length>0&&(e+=' class ="'+Jt.escape(fh(this.classes))+'"'),e+=">";for(var n=0;n<this.children.length;n++)e+=this.children[n].toMarkup();return e+="</"+this.type+">",e}toText(){return this.children.map(e=>e.toText()).join("")}},Jf=class{static{o(this,"TextNode")}constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return Jt.escape(this.toText())}toText(){return this.text}},D7=class{static{o(this,"SpaceNode")}constructor(e){this.width=void 0,this.character=void 0,this.width=e,e>=.05555&&e<=.05556?this.character="\u200A":e>=.1666&&e<=.1667?this.character="\u2009":e>=.2222&&e<=.2223?this.character="\u2005":e>=.2777&&e<=.2778?this.character="\u2005\u200A":e>=-.05556&&e<=-.05555?this.character="\u200A\u2063":e>=-.1667&&e<=-.1666?this.character="\u2009\u2063":e>=-.2223&&e<=-.2222?this.character="\u205F\u2063":e>=-.2778&&e<=-.2777?this.character="\u2005\u2063":this.character=null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",kt(this.width)),e}toMarkup(){return this.character?"<mtext>"+this.character+"</mtext>":'<mspace width="'+kt(this.width)+'"/>'}toText(){return this.character?this.character:" "}},dt={MathNode:ws,TextNode:Jf,SpaceNode:D7,newDocumentFragment:Qz},Co=o(function(e,r,n){return An[r][e]&&An[r][e].replace&&e.charCodeAt(0)!==55349&&!(Hz.hasOwnProperty(e)&&n&&(n.fontFamily&&n.fontFamily.slice(4,6)==="tt"||n.font&&n.font.slice(4,6)==="tt"))&&(e=An[r][e].replace),new dt.TextNode(e)},"makeText"),F7=o(function(e){return e.length===1?e[0]:new dt.MathNode("mrow",e)},"makeRow"),$7=o(function(e,r){if(r.fontFamily==="texttt")return"monospace";if(r.fontFamily==="textsf")return r.fontShape==="textit"&&r.fontWeight==="textbf"?"sans-serif-bold-italic":r.fontShape==="textit"?"sans-serif-italic":r.fontWeight==="textbf"?"bold-sans-serif":"sans-serif";if(r.fontShape==="textit"&&r.fontWeight==="textbf")return"bold-italic";if(r.fontShape==="textit")return"italic";if(r.fontWeight==="textbf")return"bold";var n=r.font;if(!n||n==="mathnormal")return null;var i=e.mode;if(n==="mathit")return"italic";if(n==="boldsymbol")return e.type==="textord"?"bold":"bold-italic";if(n==="mathbf")return"bold";if(n==="mathbb")return"double-struck";if(n==="mathfrak")return"fraktur";if(n==="mathscr"||n==="mathcal")return"script";if(n==="mathsf")return"sans-serif";if(n==="mathtt")return"monospace";var a=e.text;if(Jt.contains(["\\imath","\\jmath"],a))return null;An[i][a]&&An[i][a].replace&&(a=An[i][a].replace);var s=Be.fontMap[n].fontName;return P7(a,s,i)?Be.fontMap[n].variant:null},"getVariant"),ks=o(function(e,r,n){if(e.length===1){var i=yn(e[0],r);return n&&i instanceof ws&&i.type==="mo"&&(i.setAttribute("lspace","0em"),i.setAttribute("rspace","0em")),[i]}for(var a=[],s,l=0;l<e.length;l++){var u=yn(e[l],r);if(u instanceof ws&&s instanceof ws){if(u.type==="mtext"&&s.type==="mtext"&&u.getAttribute("mathvariant")===s.getAttribute("mathvariant")){s.children.push(...u.children);continue}else if(u.type==="mn"&&s.type==="mn"){s.children.push(...u.children);continue}else if(u.type==="mi"&&u.children.length===1&&s.type==="mn"){var h=u.children[0];if(h instanceof Jf&&h.text==="."){s.children.push(...u.children);continue}}else if(s.type==="mi"&&s.children.length===1){var f=s.children[0];if(f instanceof Jf&&f.text==="\u0338"&&(u.type==="mo"||u.type==="mi"||u.type==="mn")){var d=u.children[0];d instanceof Jf&&d.text.length>0&&(d.text=d.text.slice(0,1)+"\u0338"+d.text.slice(1),a.pop())}}}a.push(u),s=u}return a},"buildExpression"),dh=o(function(e,r,n){return F7(ks(e,r,n))},"buildExpressionRow"),yn=o(function(e,r){if(!e)return new dt.MathNode("mrow");if(m3[e.type]){var n=m3[e.type](e,r);return n}else throw new gt("Got group of unknown type: '"+e.type+"'")},"buildGroup");o(gz,"buildMathML");Zz=o(function(e){return new f3({style:e.displayMode?tr.DISPLAY:tr.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},"optionsFromSettings"),Jz=o(function(e,r){if(r.displayMode){var n=["katex-display"];r.leqno&&n.push("leqno"),r.fleqn&&n.push("fleqn"),e=Be.makeSpan(n,[e])}return e},"displayWrap"),t4e=o(function(e,r,n){var i=Zz(n),a;if(n.output==="mathml")return gz(e,r,i,n.displayMode,!0);if(n.output==="html"){var s=_7(e,i);a=Be.makeSpan(["katex"],[s])}else{var l=gz(e,r,i,n.displayMode,!1),u=_7(e,i);a=Be.makeSpan(["katex"],[l,u])}return Jz(a,n)},"buildTree"),r4e=o(function(e,r,n){var i=Zz(n),a=_7(e,i),s=Be.makeSpan(["katex"],[a]);return Jz(s,n)},"buildHTMLTree"),n4e={widehat:"^",widecheck:"\u02C7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23DF",overbrace:"\u23DE",overgroup:"\u23E0",undergroup:"\u23E1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21D2",xRightarrow:"\u21D2",overleftharpoon:"\u21BC",xleftharpoonup:"\u21BC",overrightharpoon:"\u21C0",xrightharpoonup:"\u21C0",xLeftarrow:"\u21D0",xLeftrightarrow:"\u21D4",xhookleftarrow:"\u21A9",xhookrightarrow:"\u21AA",xmapsto:"\u21A6",xrightharpoondown:"\u21C1",xleftharpoondown:"\u21BD",xrightleftharpoons:"\u21CC",xleftrightharpoons:"\u21CB",xtwoheadleftarrow:"\u219E",xtwoheadrightarrow:"\u21A0",xlongequal:"=",xtofrom:"\u21C4",xrightleftarrows:"\u21C4",xrightequilibrium:"\u21CC",xleftequilibrium:"\u21CB","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},i4e=o(function(e){var r=new dt.MathNode("mo",[new dt.TextNode(n4e[e.replace(/^\\/,"")])]);return r.setAttribute("stretchy","true"),r},"mathMLnode"),a4e={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},s4e=o(function(e){return e.type==="ordgroup"?e.body.length:1},"groupLength"),o4e=o(function(e,r){function n(){var l=4e5,u=e.label.slice(1);if(Jt.contains(["widehat","widecheck","widetilde","utilde"],u)){var h=e,f=s4e(h.base),d,p,m;if(f>5)u==="widehat"||u==="widecheck"?(d=420,l=2364,m=.42,p=u+"4"):(d=312,l=2340,m=.34,p="tilde4");else{var g=[1,1,2,2,3,3][f];u==="widehat"||u==="widecheck"?(l=[0,1062,2364,2364,2364][g],d=[0,239,300,360,420][g],m=[0,.24,.3,.3,.36,.42][g],p=u+g):(l=[0,600,1033,2339,2340][g],d=[0,260,286,306,312][g],m=[0,.26,.286,.3,.306,.34][g],p="tilde"+g)}var y=new Kl(p),v=new ll([y],{width:"100%",height:kt(m),viewBox:"0 0 "+l+" "+d,preserveAspectRatio:"none"});return{span:Be.makeSvgSpan([],[v],r),minWidth:0,height:m}}else{var x=[],b=a4e[u],[w,C,T]=b,E=T/1e3,A=w.length,S,_;if(A===1){var I=b[3];S=["hide-tail"],_=[I]}else if(A===2)S=["halfarrow-left","halfarrow-right"],_=["xMinYMin","xMaxYMin"];else if(A===3)S=["brace-left","brace-center","brace-right"],_=["xMinYMin","xMidYMin","xMaxYMin"];else throw new Error(`Correct katexImagesData or update code here to support
+ `+A+" children.");for(var D=0;D<A;D++){var k=new Kl(w[D]),L=new ll([k],{width:"400em",height:kt(E),viewBox:"0 0 "+l+" "+T,preserveAspectRatio:_[D]+" slice"}),R=Be.makeSvgSpan([S[D]],[L],r);if(A===1)return{span:R,minWidth:C,height:E};R.style.height=kt(E),x.push(R)}return{span:Be.makeSpan(["stretchy"],x,r),minWidth:C,height:E}}}o(n,"buildSvgSpan_");var{span:i,minWidth:a,height:s}=n();return i.height=s,i.style.height=kt(s),a>0&&(i.style.minWidth=kt(a)),i},"svgSpan"),l4e=o(function(e,r,n,i,a){var s,l=e.height+e.depth+n+i;if(/fbox|color|angl/.test(r)){if(s=Be.makeSpan(["stretchy",r],[],a),r==="fbox"){var u=a.color&&a.getColor();u&&(s.style.borderColor=u)}}else{var h=[];/^[bx]cancel$/.test(r)&&h.push(new Uy({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(r)&&h.push(new Uy({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var f=new ll(h,{width:"100%",height:kt(l)});s=Be.makeSvgSpan([],[f],a)}return s.height=l,s.style.height=kt(l),s},"encloseSpan"),cu={encloseSpan:l4e,mathMLnode:i4e,svgSpan:o4e};o(xr,"assertNodeType");o(z7,"assertSymbolNodeType");o(w3,"checkSymbolNodeType");G7=o((t,e)=>{var r,n,i;t&&t.type==="supsub"?(n=xr(t.base,"accent"),r=n.base,t.base=r,i=Nbe(Fr(t,e)),t.base=n):(n=xr(t,"accent"),r=n.base);var a=Fr(r,e.havingCrampedStyle()),s=n.isShifty&&Jt.isCharacterBox(r),l=0;if(s){var u=Jt.getBaseElem(r),h=Fr(u,e.havingCrampedStyle());l=hz(h).skew}var f=n.label==="\\c",d=f?a.height+a.depth:Math.min(a.height,e.fontMetrics().xHeight),p;if(n.isStretchy)p=cu.svgSpan(n,e),p=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"elem",elem:p,wrapperClasses:["svg-align"],wrapperStyle:l>0?{width:"calc(100% - "+kt(2*l)+")",marginLeft:kt(2*l)}:void 0}]},e);else{var m,g;n.label==="\\vec"?(m=Be.staticSvg("vec",e),g=Be.svgData.vec[1]):(m=Be.makeOrd({mode:n.mode,text:n.label},e,"textord"),m=hz(m),m.italic=0,g=m.width,f&&(d+=m.depth)),p=Be.makeSpan(["accent-body"],[m]);var y=n.label==="\\textcircled";y&&(p.classes.push("accent-full"),d=a.height);var v=l;y||(v-=g/2),p.style.left=kt(v),n.label==="\\textcircled"&&(p.style.top=".2em"),p=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:-d},{type:"elem",elem:p}]},e)}var x=Be.makeSpan(["mord","accent"],[p],e);return i?(i.children[0]=x,i.height=Math.max(x.height,i.height),i.classes[0]="mord",i):x},"htmlBuilder$a"),eG=o((t,e)=>{var r=t.isStretchy?cu.mathMLnode(t.label):new dt.MathNode("mo",[Co(t.label,t.mode)]),n=new dt.MathNode("mover",[yn(t.base,e),r]);return n.setAttribute("accent","true"),n},"mathmlBuilder$9"),c4e=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(t=>"\\"+t).join("|"));Nt({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:o((t,e)=>{var r=g3(e[0]),n=!c4e.test(t.funcName),i=!n||t.funcName==="\\widehat"||t.funcName==="\\widetilde"||t.funcName==="\\widecheck";return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:n,isShifty:i,base:r}},"handler"),htmlBuilder:G7,mathmlBuilder:eG});Nt({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:o((t,e)=>{var r=e[0],n=t.parser.mode;return n==="math"&&(t.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+t.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:t.funcName,isStretchy:!1,isShifty:!0,base:r}},"handler"),htmlBuilder:G7,mathmlBuilder:eG});Nt({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"accentUnder",mode:r.mode,label:n,base:i}},"handler"),htmlBuilder:o((t,e)=>{var r=Fr(t.base,e),n=cu.svgSpan(t,e),i=t.label==="\\utilde"?.12:0,a=Be.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:i},{type:"elem",elem:r}]},e);return Be.makeSpan(["mord","accentunder"],[a],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=cu.mathMLnode(t.label),n=new dt.MathNode("munder",[yn(t.base,e),r]);return n.setAttribute("accentunder","true"),n},"mathmlBuilder")});s3=o(t=>{var e=new dt.MathNode("mpadded",t?[t]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e},"paddedNode");Nt({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,r){var{parser:n,funcName:i}=t;return{type:"xArrow",mode:n.mode,label:i,body:e[0],below:r[0]}},htmlBuilder(t,e){var r=e.style,n=e.havingStyle(r.sup()),i=Be.wrapFragment(Fr(t.body,n,e),e),a=t.label.slice(0,2)==="\\x"?"x":"cd";i.classes.push(a+"-arrow-pad");var s;t.below&&(n=e.havingStyle(r.sub()),s=Be.wrapFragment(Fr(t.below,n,e),e),s.classes.push(a+"-arrow-pad"));var l=cu.svgSpan(t,e),u=-e.fontMetrics().axisHeight+.5*l.height,h=-e.fontMetrics().axisHeight-.5*l.height-.111;(i.depth>.25||t.label==="\\xleftequilibrium")&&(h-=i.depth);var f;if(s){var d=-e.fontMetrics().axisHeight+s.height+.5*l.height+.111;f=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:l,shift:u},{type:"elem",elem:s,shift:d}]},e)}else f=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:l,shift:u}]},e);return f.children[0].children[0].children[1].classes.push("svg-align"),Be.makeSpan(["mrel","x-arrow"],[f],e)},mathmlBuilder(t,e){var r=cu.mathMLnode(t.label);r.setAttribute("minsize",t.label.charAt(0)==="x"?"1.75em":"3.0em");var n;if(t.body){var i=s3(yn(t.body,e));if(t.below){var a=s3(yn(t.below,e));n=new dt.MathNode("munderover",[r,a,i])}else n=new dt.MathNode("mover",[r,i])}else if(t.below){var s=s3(yn(t.below,e));n=new dt.MathNode("munder",[r,s])}else n=s3(),n=new dt.MathNode("mover",[r,n]);return n}});u4e=Be.makeSpan;o(tG,"htmlBuilder$9");o(rG,"mathmlBuilder$8");Nt({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:di(i),isCharacterBox:Jt.isCharacterBox(i)}},htmlBuilder:tG,mathmlBuilder:rG});T3=o(t=>{var e=t.type==="ordgroup"&&t.body.length?t.body[0]:t;return e.type==="atom"&&(e.family==="bin"||e.family==="rel")?"m"+e.family:"mord"},"binrelClass");Nt({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(t,e){var{parser:r}=t;return{type:"mclass",mode:r.mode,mclass:T3(e[0]),body:di(e[1]),isCharacterBox:Jt.isCharacterBox(e[1])}}});Nt({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(t,e){var{parser:r,funcName:n}=t,i=e[1],a=e[0],s;n!=="\\stackrel"?s=T3(i):s="mrel";var l={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:n!=="\\stackrel",body:di(i)},u={type:"supsub",mode:a.mode,base:l,sup:n==="\\underset"?null:a,sub:n==="\\underset"?a:null};return{type:"mclass",mode:r.mode,mclass:s,body:[u],isCharacterBox:Jt.isCharacterBox(u)}},htmlBuilder:tG,mathmlBuilder:rG});Nt({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"pmb",mode:r.mode,mclass:T3(e[0]),body:di(e[0])}},htmlBuilder(t,e){var r=Pi(t.body,e,!0),n=Be.makeSpan([t.mclass],r,e);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder(t,e){var r=ks(t.body,e),n=new dt.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});h4e={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},yz=o(()=>({type:"styling",body:[],mode:"math",style:"display"}),"newCell"),vz=o(t=>t.type==="textord"&&t.text==="@","isStartOfArrow"),f4e=o((t,e)=>(t.type==="mathord"||t.type==="atom")&&t.text===e,"isLabelEnd");o(d4e,"cdArrow");o(p4e,"parseCD");Nt({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:e[0]}},htmlBuilder(t,e){var r=e.havingStyle(e.style.sup()),n=Be.wrapFragment(Fr(t.label,r,e),e);return n.classes.push("cd-label-"+t.side),n.style.bottom=kt(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder(t,e){var r=new dt.MathNode("mrow",[yn(t.label,e)]);return r=new dt.MathNode("mpadded",[r]),r.setAttribute("width","0"),t.side==="left"&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),r=new dt.MathNode("mstyle",[r]),r.setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}});Nt({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(t,e){var{parser:r}=t;return{type:"cdlabelparent",mode:r.mode,fragment:e[0]}},htmlBuilder(t,e){var r=Be.wrapFragment(Fr(t.fragment,e),e);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder(t,e){return new dt.MathNode("mrow",[yn(t.fragment,e)])}});Nt({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(t,e){for(var{parser:r}=t,n=xr(e[0],"ordgroup"),i=n.body,a="",s=0;s<i.length;s++){var l=xr(i[s],"textord");a+=l.text}var u=parseInt(a),h;if(isNaN(u))throw new gt("\\@char has non-numeric argument "+a);if(u<0||u>=1114111)throw new gt("\\@char with invalid code point "+a);return u<=65535?h=String.fromCharCode(u):(u-=65536,h=String.fromCharCode((u>>10)+55296,(u&1023)+56320)),{type:"textord",mode:r.mode,text:h}}});nG=o((t,e)=>{var r=Pi(t.body,e.withColor(t.color),!1);return Be.makeFragment(r)},"htmlBuilder$8"),iG=o((t,e)=>{var r=ks(t.body,e.withColor(t.color)),n=new dt.MathNode("mstyle",r);return n.setAttribute("mathcolor",t.color),n},"mathmlBuilder$7");Nt({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(t,e){var{parser:r}=t,n=xr(e[0],"color-token").color,i=e[1];return{type:"color",mode:r.mode,color:n,body:di(i)}},htmlBuilder:nG,mathmlBuilder:iG});Nt({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(t,e){var{parser:r,breakOnTokenText:n}=t,i=xr(e[0],"color-token").color;r.gullet.macros.set("\\current@color",i);var a=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:i,body:a}},htmlBuilder:nG,mathmlBuilder:iG});Nt({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(t,e,r){var{parser:n}=t,i=n.gullet.future().text==="["?n.parseSizeGroup(!0):null,a=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:a,size:i&&xr(i,"size").value}},htmlBuilder(t,e){var r=Be.makeSpan(["mspace"],[],e);return t.newLine&&(r.classes.push("newline"),t.size&&(r.style.marginTop=kt(ti(t.size,e)))),r},mathmlBuilder(t,e){var r=new dt.MathNode("mspace");return t.newLine&&(r.setAttribute("linebreak","newline"),t.size&&r.setAttribute("height",kt(ti(t.size,e)))),r}});L7={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},aG=o(t=>{var e=t.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new gt("Expected a control sequence",t);return e},"checkControlSequence"),m4e=o(t=>{var e=t.gullet.popToken();return e.text==="="&&(e=t.gullet.popToken(),e.text===" "&&(e=t.gullet.popToken())),e},"getRHS"),sG=o((t,e,r,n)=>{var i=t.gullet.macros.get(r.text);i==null&&(r.noexpand=!0,i={tokens:[r],numArgs:0,unexpandable:!t.gullet.isExpandable(r.text)}),t.gullet.macros.set(e,i,n)},"letCommand");Nt({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(t){var{parser:e,funcName:r}=t;e.consumeSpaces();var n=e.fetch();if(L7[n.text])return(r==="\\global"||r==="\\\\globallong")&&(n.text=L7[n.text]),xr(e.parseFunction(),"internal");throw new gt("Invalid token after macro prefix",n)}});Nt({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=e.gullet.popToken(),i=n.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new gt("Expected a control sequence",n);for(var a=0,s,l=[[]];e.gullet.future().text!=="{";)if(n=e.gullet.popToken(),n.text==="#"){if(e.gullet.future().text==="{"){s=e.gullet.future(),l[a].push("{");break}if(n=e.gullet.popToken(),!/^[1-9]$/.test(n.text))throw new gt('Invalid argument number "'+n.text+'"');if(parseInt(n.text)!==a+1)throw new gt('Argument number "'+n.text+'" out of order');a++,l.push([])}else{if(n.text==="EOF")throw new gt("Expected a macro definition");l[a].push(n.text)}var{tokens:u}=e.gullet.consumeArg();return s&&u.unshift(s),(r==="\\edef"||r==="\\xdef")&&(u=e.gullet.expandTokens(u),u.reverse()),e.gullet.macros.set(i,{tokens:u,numArgs:a,delimiters:l},r===L7[r]),{type:"internal",mode:e.mode}}});Nt({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=aG(e.gullet.popToken());e.gullet.consumeSpaces();var i=m4e(e);return sG(e,n,i,r==="\\\\globallet"),{type:"internal",mode:e.mode}}});Nt({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t){var{parser:e,funcName:r}=t,n=aG(e.gullet.popToken()),i=e.gullet.popToken(),a=e.gullet.popToken();return sG(e,n,a,r==="\\\\globalfuture"),e.gullet.pushToken(a),e.gullet.pushToken(i),{type:"internal",mode:e.mode}}});Fy=o(function(e,r,n){var i=An.math[e]&&An.math[e].replace,a=P7(i||e,r,n);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+r+".");return a},"getMetrics"),V7=o(function(e,r,n,i){var a=n.havingBaseStyle(r),s=Be.makeSpan(i.concat(a.sizingClasses(n)),[e],n),l=a.sizeMultiplier/n.sizeMultiplier;return s.height*=l,s.depth*=l,s.maxFontSize=a.sizeMultiplier,s},"styleWrap"),oG=o(function(e,r,n){var i=r.havingBaseStyle(n),a=(1-r.sizeMultiplier/i.sizeMultiplier)*r.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=kt(a),e.height-=a,e.depth+=a},"centerSpan"),g4e=o(function(e,r,n,i,a,s){var l=Be.makeSymbol(e,"Main-Regular",a,i),u=V7(l,r,i,s);return n&&oG(u,i,r),u},"makeSmallDelim"),y4e=o(function(e,r,n,i){return Be.makeSymbol(e,"Size"+r+"-Regular",n,i)},"mathrmSize"),lG=o(function(e,r,n,i,a,s){var l=y4e(e,r,a,i),u=V7(Be.makeSpan(["delimsizing","size"+r],[l],i),tr.TEXT,i,s);return n&&oG(u,i,tr.TEXT),u},"makeLargeDelim"),p7=o(function(e,r,n){var i;r==="Size1-Regular"?i="delim-size1":i="delim-size4";var a=Be.makeSpan(["delimsizinginner",i],[Be.makeSpan([],[Be.makeSymbol(e,r,n)])]);return{type:"elem",elem:a}},"makeGlyphSpan"),m7=o(function(e,r,n){var i=jl["Size4-Regular"][e.charCodeAt(0)]?jl["Size4-Regular"][e.charCodeAt(0)][4]:jl["Size1-Regular"][e.charCodeAt(0)][4],a=new Kl("inner",Sbe(e,Math.round(1e3*r))),s=new ll([a],{width:kt(i),height:kt(r),style:"width:"+kt(i),viewBox:"0 0 "+1e3*i+" "+Math.round(1e3*r),preserveAspectRatio:"xMinYMin"}),l=Be.makeSvgSpan([],[s],n);return l.height=r,l.style.height=kt(r),l.style.width=kt(i),{type:"elem",elem:l}},"makeInner"),R7=.008,o3={type:"kern",size:-1*R7},v4e=["|","\\lvert","\\rvert","\\vert"],x4e=["\\|","\\lVert","\\rVert","\\Vert"],cG=o(function(e,r,n,i,a,s){var l,u,h,f,d="",p=0;l=h=f=e,u=null;var m="Size1-Regular";e==="\\uparrow"?h=f="\u23D0":e==="\\Uparrow"?h=f="\u2016":e==="\\downarrow"?l=h="\u23D0":e==="\\Downarrow"?l=h="\u2016":e==="\\updownarrow"?(l="\\uparrow",h="\u23D0",f="\\downarrow"):e==="\\Updownarrow"?(l="\\Uparrow",h="\u2016",f="\\Downarrow"):Jt.contains(v4e,e)?(h="\u2223",d="vert",p=333):Jt.contains(x4e,e)?(h="\u2225",d="doublevert",p=556):e==="["||e==="\\lbrack"?(l="\u23A1",h="\u23A2",f="\u23A3",m="Size4-Regular",d="lbrack",p=667):e==="]"||e==="\\rbrack"?(l="\u23A4",h="\u23A5",f="\u23A6",m="Size4-Regular",d="rbrack",p=667):e==="\\lfloor"||e==="\u230A"?(h=l="\u23A2",f="\u23A3",m="Size4-Regular",d="lfloor",p=667):e==="\\lceil"||e==="\u2308"?(l="\u23A1",h=f="\u23A2",m="Size4-Regular",d="lceil",p=667):e==="\\rfloor"||e==="\u230B"?(h=l="\u23A5",f="\u23A6",m="Size4-Regular",d="rfloor",p=667):e==="\\rceil"||e==="\u2309"?(l="\u23A4",h=f="\u23A5",m="Size4-Regular",d="rceil",p=667):e==="("||e==="\\lparen"?(l="\u239B",h="\u239C",f="\u239D",m="Size4-Regular",d="lparen",p=875):e===")"||e==="\\rparen"?(l="\u239E",h="\u239F",f="\u23A0",m="Size4-Regular",d="rparen",p=875):e==="\\{"||e==="\\lbrace"?(l="\u23A7",u="\u23A8",f="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\}"||e==="\\rbrace"?(l="\u23AB",u="\u23AC",f="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lgroup"||e==="\u27EE"?(l="\u23A7",f="\u23A9",h="\u23AA",m="Size4-Regular"):e==="\\rgroup"||e==="\u27EF"?(l="\u23AB",f="\u23AD",h="\u23AA",m="Size4-Regular"):e==="\\lmoustache"||e==="\u23B0"?(l="\u23A7",f="\u23AD",h="\u23AA",m="Size4-Regular"):(e==="\\rmoustache"||e==="\u23B1")&&(l="\u23AB",f="\u23A9",h="\u23AA",m="Size4-Regular");var g=Fy(l,m,a),y=g.height+g.depth,v=Fy(h,m,a),x=v.height+v.depth,b=Fy(f,m,a),w=b.height+b.depth,C=0,T=1;if(u!==null){var E=Fy(u,m,a);C=E.height+E.depth,T=2}var A=y+w+C,S=Math.max(0,Math.ceil((r-A)/(T*x))),_=A+S*T*x,I=i.fontMetrics().axisHeight;n&&(I*=i.sizeMultiplier);var D=_/2-I,k=[];if(d.length>0){var L=_-y-w,R=Math.round(_*1e3),O=Cbe(d,Math.round(L*1e3)),M=new Kl(d,O),B=(p/1e3).toFixed(3)+"em",F=(R/1e3).toFixed(3)+"em",P=new ll([M],{width:B,height:F,viewBox:"0 0 "+p+" "+R}),z=Be.makeSvgSpan([],[P],i);z.height=R/1e3,z.style.width=B,z.style.height=F,k.push({type:"elem",elem:z})}else{if(k.push(p7(f,m,a)),k.push(o3),u===null){var $=_-y-w+2*R7;k.push(m7(h,$,i))}else{var H=(_-y-w-C)/2+2*R7;k.push(m7(h,H,i)),k.push(o3),k.push(p7(u,m,a)),k.push(o3),k.push(m7(h,H,i))}k.push(o3),k.push(p7(l,m,a))}var Q=i.havingBaseStyle(tr.TEXT),j=Be.makeVList({positionType:"bottom",positionData:D,children:k},Q);return V7(Be.makeSpan(["delimsizing","mult"],[j],Q),tr.TEXT,i,s)},"makeStackedDelim"),g7=80,y7=.08,v7=o(function(e,r,n,i,a){var s=Ebe(e,i,n),l=new Kl(e,s),u=new ll([l],{width:"400em",height:kt(r),viewBox:"0 0 400000 "+n,preserveAspectRatio:"xMinYMin slice"});return Be.makeSvgSpan(["hide-tail"],[u],a)},"sqrtSvg"),b4e=o(function(e,r){var n=r.havingBaseSizing(),i=dG("\\surd",e*n.sizeMultiplier,fG,n),a=n.sizeMultiplier,s=Math.max(0,r.minRuleThickness-r.fontMetrics().sqrtRuleThickness),l,u=0,h=0,f=0,d;return i.type==="small"?(f=1e3+1e3*s+g7,e<1?a=1:e<1.4&&(a=.7),u=(1+s+y7)/a,h=(1+s)/a,l=v7("sqrtMain",u,f,s,r),l.style.minWidth="0.853em",d=.833/a):i.type==="large"?(f=(1e3+g7)*$y[i.size],h=($y[i.size]+s)/a,u=($y[i.size]+s+y7)/a,l=v7("sqrtSize"+i.size,u,f,s,r),l.style.minWidth="1.02em",d=1/a):(u=e+s+y7,h=e+s,f=Math.floor(1e3*e+s)+g7,l=v7("sqrtTall",u,f,s,r),l.style.minWidth="0.742em",d=1.056),l.height=h,l.style.height=kt(u),{span:l,advanceWidth:d,ruleWidth:(r.fontMetrics().sqrtRuleThickness+s)*a}},"makeSqrtImage"),uG=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","\\surd"],w4e=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1"],hG=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],$y=[0,1.2,1.8,2.4,3],T4e=o(function(e,r,n,i,a){if(e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle"),Jt.contains(uG,e)||Jt.contains(hG,e))return lG(e,r,!1,n,i,a);if(Jt.contains(w4e,e))return cG(e,$y[r],!1,n,i,a);throw new gt("Illegal delimiter: '"+e+"'")},"makeSizedDelim"),k4e=[{type:"small",style:tr.SCRIPTSCRIPT},{type:"small",style:tr.SCRIPT},{type:"small",style:tr.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],E4e=[{type:"small",style:tr.SCRIPTSCRIPT},{type:"small",style:tr.SCRIPT},{type:"small",style:tr.TEXT},{type:"stack"}],fG=[{type:"small",style:tr.SCRIPTSCRIPT},{type:"small",style:tr.SCRIPT},{type:"small",style:tr.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],S4e=o(function(e){if(e.type==="small")return"Main-Regular";if(e.type==="large")return"Size"+e.size+"-Regular";if(e.type==="stack")return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},"delimTypeToFont"),dG=o(function(e,r,n,i){for(var a=Math.min(2,3-i.style.size),s=a;s<n.length&&n[s].type!=="stack";s++){var l=Fy(e,S4e(n[s]),"math"),u=l.height+l.depth;if(n[s].type==="small"){var h=i.havingBaseStyle(n[s].style);u*=h.sizeMultiplier}if(u>r)return n[s]}return n[n.length-1]},"traverseSequence"),pG=o(function(e,r,n,i,a,s){e==="<"||e==="\\lt"||e==="\u27E8"?e="\\langle":(e===">"||e==="\\gt"||e==="\u27E9")&&(e="\\rangle");var l;Jt.contains(hG,e)?l=k4e:Jt.contains(uG,e)?l=fG:l=E4e;var u=dG(e,r,l,i);return u.type==="small"?g4e(e,u.style,n,i,a,s):u.type==="large"?lG(e,u.size,n,i,a,s):cG(e,r,n,i,a,s)},"makeCustomSizedDelim"),C4e=o(function(e,r,n,i,a,s){var l=i.fontMetrics().axisHeight*i.sizeMultiplier,u=901,h=5/i.fontMetrics().ptPerEm,f=Math.max(r-l,n+l),d=Math.max(f/500*u,2*f-h);return pG(e,d,!0,i,a,s)},"makeLeftRightDelim"),ou={sqrtImage:b4e,sizedDelim:T4e,sizeToMaxHeight:$y,customSizedDelim:pG,leftRightDelim:C4e},xz={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},A4e=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230A","\u230B","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27E8","\\rangle","\u27E9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27EE","\u27EF","\\lmoustache","\\rmoustache","\u23B0","\u23B1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];o(k3,"checkDelimiter");Nt({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:o((t,e)=>{var r=k3(e[0],t);return{type:"delimsizing",mode:t.parser.mode,size:xz[t.funcName].size,mclass:xz[t.funcName].mclass,delim:r.text}},"handler"),htmlBuilder:o((t,e)=>t.delim==="."?Be.makeSpan([t.mclass]):ou.sizedDelim(t.delim,t.size,e,t.mode,[t.mclass]),"htmlBuilder"),mathmlBuilder:o(t=>{var e=[];t.delim!=="."&&e.push(Co(t.delim,t.mode));var r=new dt.MathNode("mo",e);t.mclass==="mopen"||t.mclass==="mclose"?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=kt(ou.sizeToMaxHeight[t.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r},"mathmlBuilder")});o(bz,"assertParsed");Nt({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=t.parser.gullet.macros.get("\\current@color");if(r&&typeof r!="string")throw new gt("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:t.parser.mode,delim:k3(e[0],t).text,color:r}},"handler")});Nt({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=k3(e[0],t),n=t.parser;++n.leftrightDepth;var i=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var a=xr(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:i,left:r.text,right:a.delim,rightColor:a.color}},"handler"),htmlBuilder:o((t,e)=>{bz(t);for(var r=Pi(t.body,e,!0,["mopen","mclose"]),n=0,i=0,a=!1,s=0;s<r.length;s++)r[s].isMiddle?a=!0:(n=Math.max(r[s].height,n),i=Math.max(r[s].depth,i));n*=e.sizeMultiplier,i*=e.sizeMultiplier;var l;if(t.left==="."?l=Hy(e,["mopen"]):l=ou.leftRightDelim(t.left,n,i,e,t.mode,["mopen"]),r.unshift(l),a)for(var u=1;u<r.length;u++){var h=r[u],f=h.isMiddle;f&&(r[u]=ou.leftRightDelim(f.delim,n,i,f.options,t.mode,[]))}var d;if(t.right===".")d=Hy(e,["mclose"]);else{var p=t.rightColor?e.withColor(t.rightColor):e;d=ou.leftRightDelim(t.right,n,i,p,t.mode,["mclose"])}return r.push(d),Be.makeSpan(["minner"],r,e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{bz(t);var r=ks(t.body,e);if(t.left!=="."){var n=new dt.MathNode("mo",[Co(t.left,t.mode)]);n.setAttribute("fence","true"),r.unshift(n)}if(t.right!=="."){var i=new dt.MathNode("mo",[Co(t.right,t.mode)]);i.setAttribute("fence","true"),t.rightColor&&i.setAttribute("mathcolor",t.rightColor),r.push(i)}return F7(r)},"mathmlBuilder")});Nt({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var r=k3(e[0],t);if(!t.parser.leftrightDepth)throw new gt("\\middle without preceding \\left",r);return{type:"middle",mode:t.parser.mode,delim:r.text}},"handler"),htmlBuilder:o((t,e)=>{var r;if(t.delim===".")r=Hy(e,[]);else{r=ou.sizedDelim(t.delim,1,e,t.mode,[]);var n={delim:t.delim,options:e};r.isMiddle=n}return r},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=t.delim==="\\vert"||t.delim==="|"?Co("|","text"):Co(t.delim,t.mode),n=new dt.MathNode("mo",[r]);return n.setAttribute("fence","true"),n.setAttribute("lspace","0.05em"),n.setAttribute("rspace","0.05em"),n},"mathmlBuilder")});U7=o((t,e)=>{var r=Be.wrapFragment(Fr(t.body,e),e),n=t.label.slice(1),i=e.sizeMultiplier,a,s=0,l=Jt.isCharacterBox(t.body);if(n==="sout")a=Be.makeSpan(["stretchy","sout"]),a.height=e.fontMetrics().defaultRuleThickness/i,s=-.5*e.fontMetrics().xHeight;else if(n==="phase"){var u=ti({number:.6,unit:"pt"},e),h=ti({number:.35,unit:"ex"},e),f=e.havingBaseSizing();i=i/f.sizeMultiplier;var d=r.height+r.depth+u+h;r.style.paddingLeft=kt(d/2+u);var p=Math.floor(1e3*d*i),m=Tbe(p),g=new ll([new Kl("phase",m)],{width:"400em",height:kt(p/1e3),viewBox:"0 0 400000 "+p,preserveAspectRatio:"xMinYMin slice"});a=Be.makeSvgSpan(["hide-tail"],[g],e),a.style.height=kt(d),s=r.depth+u+h}else{/cancel/.test(n)?l||r.classes.push("cancel-pad"):n==="angl"?r.classes.push("anglpad"):r.classes.push("boxpad");var y=0,v=0,x=0;/box/.test(n)?(x=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),y=e.fontMetrics().fboxsep+(n==="colorbox"?0:x),v=y):n==="angl"?(x=Math.max(e.fontMetrics().defaultRuleThickness,e.minRuleThickness),y=4*x,v=Math.max(0,.25-r.depth)):(y=l?.2:0,v=y),a=cu.encloseSpan(r,n,y,v,e),/fbox|boxed|fcolorbox/.test(n)?(a.style.borderStyle="solid",a.style.borderWidth=kt(x)):n==="angl"&&x!==.049&&(a.style.borderTopWidth=kt(x),a.style.borderRightWidth=kt(x)),s=r.depth+v,t.backgroundColor&&(a.style.backgroundColor=t.backgroundColor,t.borderColor&&(a.style.borderColor=t.borderColor))}var b;if(t.backgroundColor)b=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:s},{type:"elem",elem:r,shift:0}]},e);else{var w=/cancel|phase/.test(n)?["svg-align"]:[];b=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:0},{type:"elem",elem:a,shift:s,wrapperClasses:w}]},e)}return/cancel/.test(n)&&(b.height=r.height,b.depth=r.depth),/cancel/.test(n)&&!l?Be.makeSpan(["mord","cancel-lap"],[b],e):Be.makeSpan(["mord"],[b],e)},"htmlBuilder$7"),H7=o((t,e)=>{var r=0,n=new dt.MathNode(t.label.indexOf("colorbox")>-1?"mpadded":"menclose",[yn(t.body,e)]);switch(t.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),t.label==="\\fcolorbox"){var i=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);n.setAttribute("style","border: "+i+"em solid "+String(t.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike");break}return t.backgroundColor&&n.setAttribute("mathbackground",t.backgroundColor),n},"mathmlBuilder$6");Nt({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(t,e,r){var{parser:n,funcName:i}=t,a=xr(e[0],"color-token").color,s=e[1];return{type:"enclose",mode:n.mode,label:i,backgroundColor:a,body:s}},htmlBuilder:U7,mathmlBuilder:H7});Nt({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(t,e,r){var{parser:n,funcName:i}=t,a=xr(e[0],"color-token").color,s=xr(e[1],"color-token").color,l=e[2];return{type:"enclose",mode:n.mode,label:i,backgroundColor:s,borderColor:a,body:l}},htmlBuilder:U7,mathmlBuilder:H7});Nt({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"enclose",mode:r.mode,label:"\\fbox",body:e[0]}}});Nt({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"enclose",mode:r.mode,label:n,body:i}},htmlBuilder:U7,mathmlBuilder:H7});Nt({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(t,e){var{parser:r}=t;return{type:"enclose",mode:r.mode,label:"\\angl",body:e[0]}}});mG={};o(Ql,"defineEnvironment");gG={};o(fe,"defineMacro");o(wz,"getHLines");E3=o(t=>{var e=t.parser.settings;if(!e.displayMode)throw new gt("{"+t.envName+"} can be used only in display mode.")},"validateAmsEnvironmentContext");o(W7,"getAutoTag");o(ph,"parseArray");o(q7,"dCellStyle");Zl=o(function(e,r){var n,i,a=e.body.length,s=e.hLinesBeforeRow,l=0,u=new Array(a),h=[],f=Math.max(r.fontMetrics().arrayRuleWidth,r.minRuleThickness),d=1/r.fontMetrics().ptPerEm,p=5*d;if(e.colSeparationType&&e.colSeparationType==="small"){var m=r.havingStyle(tr.SCRIPT).sizeMultiplier;p=.2778*(m/r.sizeMultiplier)}var g=e.colSeparationType==="CD"?ti({number:3,unit:"ex"},r):12*d,y=3*d,v=e.arraystretch*g,x=.7*v,b=.3*v,w=0;function C(ae){for(var Oe=0;Oe<ae.length;++Oe)Oe>0&&(w+=.25),h.push({pos:w,isDashed:ae[Oe]})}for(o(C,"setHLinePos"),C(s[0]),n=0;n<e.body.length;++n){var T=e.body[n],E=x,A=b;l<T.length&&(l=T.length);var S=new Array(T.length);for(i=0;i<T.length;++i){var _=Fr(T[i],r);A<_.depth&&(A=_.depth),E<_.height&&(E=_.height),S[i]=_}var I=e.rowGaps[n],D=0;I&&(D=ti(I,r),D>0&&(D+=b,A<D&&(A=D),D=0)),e.addJot&&(A+=y),S.height=E,S.depth=A,w+=E,S.pos=w,w+=A+D,u[n]=S,C(s[n+1])}var k=w/2+r.fontMetrics().axisHeight,L=e.cols||[],R=[],O,M,B=[];if(e.tags&&e.tags.some(ae=>ae))for(n=0;n<a;++n){var F=u[n],P=F.pos-k,z=e.tags[n],$=void 0;z===!0?$=Be.makeSpan(["eqn-num"],[],r):z===!1?$=Be.makeSpan([],[],r):$=Be.makeSpan([],Pi(z,r,!0),r),$.depth=F.depth,$.height=F.height,B.push({type:"elem",elem:$,shift:P})}for(i=0,M=0;i<l||M<L.length;++i,++M){for(var H=L[M]||{},Q=!0;H.type==="separator";){if(Q||(O=Be.makeSpan(["arraycolsep"],[]),O.style.width=kt(r.fontMetrics().doubleRuleSep),R.push(O)),H.separator==="|"||H.separator===":"){var j=H.separator==="|"?"solid":"dashed",ie=Be.makeSpan(["vertical-separator"],[],r);ie.style.height=kt(w),ie.style.borderRightWidth=kt(f),ie.style.borderRightStyle=j,ie.style.margin="0 "+kt(-f/2);var ne=w-k;ne&&(ie.style.verticalAlign=kt(-ne)),R.push(ie)}else throw new gt("Invalid separator type: "+H.separator);M++,H=L[M]||{},Q=!1}if(!(i>=l)){var le=void 0;(i>0||e.hskipBeforeAndAfter)&&(le=Jt.deflt(H.pregap,p),le!==0&&(O=Be.makeSpan(["arraycolsep"],[]),O.style.width=kt(le),R.push(O)));var he=[];for(n=0;n<a;++n){var K=u[n],X=K[i];if(X){var te=K.pos-k;X.depth=K.depth,X.height=K.height,he.push({type:"elem",elem:X,shift:te})}}he=Be.makeVList({positionType:"individualShift",children:he},r),he=Be.makeSpan(["col-align-"+(H.align||"c")],[he]),R.push(he),(i<l-1||e.hskipBeforeAndAfter)&&(le=Jt.deflt(H.postgap,p),le!==0&&(O=Be.makeSpan(["arraycolsep"],[]),O.style.width=kt(le),R.push(O)))}}if(u=Be.makeSpan(["mtable"],R),h.length>0){for(var J=Be.makeLineSpan("hline",r,f),se=Be.makeLineSpan("hdashline",r,f),ue=[{type:"elem",elem:u,shift:0}];h.length>0;){var Z=h.pop(),Se=Z.pos-k;Z.isDashed?ue.push({type:"elem",elem:se,shift:Se}):ue.push({type:"elem",elem:J,shift:Se})}u=Be.makeVList({positionType:"individualShift",children:ue},r)}if(B.length===0)return Be.makeSpan(["mord"],[u],r);var ce=Be.makeVList({positionType:"individualShift",children:B},r);return ce=Be.makeSpan(["tag"],[ce],r),Be.makeFragment([u,ce])},"htmlBuilder"),_4e={c:"center ",l:"left ",r:"right "},Jl=o(function(e,r){for(var n=[],i=new dt.MathNode("mtd",[],["mtr-glue"]),a=new dt.MathNode("mtd",[],["mml-eqn-num"]),s=0;s<e.body.length;s++){for(var l=e.body[s],u=[],h=0;h<l.length;h++)u.push(new dt.MathNode("mtd",[yn(l[h],r)]));e.tags&&e.tags[s]&&(u.unshift(i),u.push(i),e.leqno?u.unshift(a):u.push(a)),n.push(new dt.MathNode("mtr",u))}var f=new dt.MathNode("mtable",n),d=e.arraystretch===.5?.1:.16+e.arraystretch-1+(e.addJot?.09:0);f.setAttribute("rowspacing",kt(d));var p="",m="";if(e.cols&&e.cols.length>0){var g=e.cols,y="",v=!1,x=0,b=g.length;g[0].type==="separator"&&(p+="top ",x=1),g[g.length-1].type==="separator"&&(p+="bottom ",b-=1);for(var w=x;w<b;w++)g[w].type==="align"?(m+=_4e[g[w].align],v&&(y+="none "),v=!0):g[w].type==="separator"&&v&&(y+=g[w].separator==="|"?"solid ":"dashed ",v=!1);f.setAttribute("columnalign",m.trim()),/[sd]/.test(y)&&f.setAttribute("columnlines",y.trim())}if(e.colSeparationType==="align"){for(var C=e.cols||[],T="",E=1;E<C.length;E++)T+=E%2?"0em ":"1em ";f.setAttribute("columnspacing",T.trim())}else e.colSeparationType==="alignat"||e.colSeparationType==="gather"?f.setAttribute("columnspacing","0em"):e.colSeparationType==="small"?f.setAttribute("columnspacing","0.2778em"):e.colSeparationType==="CD"?f.setAttribute("columnspacing","0.5em"):f.setAttribute("columnspacing","1em");var A="",S=e.hLinesBeforeRow;p+=S[0].length>0?"left ":"",p+=S[S.length-1].length>0?"right ":"";for(var _=1;_<S.length-1;_++)A+=S[_].length===0?"none ":S[_][0]?"dashed ":"solid ";return/[sd]/.test(A)&&f.setAttribute("rowlines",A.trim()),p!==""&&(f=new dt.MathNode("menclose",[f]),f.setAttribute("notation",p.trim())),e.arraystretch&&e.arraystretch<1&&(f=new dt.MathNode("mstyle",[f]),f.setAttribute("scriptlevel","1")),f},"mathmlBuilder"),yG=o(function(e,r){e.envName.indexOf("ed")===-1&&E3(e);var n=[],i=e.envName.indexOf("at")>-1?"alignat":"align",a=e.envName==="split",s=ph(e.parser,{cols:n,addJot:!0,autoTag:a?void 0:W7(e.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:a?2:void 0,leqno:e.parser.settings.leqno},"display"),l,u=0,h={type:"ordgroup",mode:e.mode,body:[]};if(r[0]&&r[0].type==="ordgroup"){for(var f="",d=0;d<r[0].body.length;d++){var p=xr(r[0].body[d],"textord");f+=p.text}l=Number(f),u=l*2}var m=!u;s.body.forEach(function(x){for(var b=1;b<x.length;b+=2){var w=xr(x[b],"styling"),C=xr(w.body[0],"ordgroup");C.body.unshift(h)}if(m)u<x.length&&(u=x.length);else{var T=x.length/2;if(l<T)throw new gt("Too many math in a row: "+("expected "+l+", but got "+T),x[0])}});for(var g=0;g<u;++g){var y="r",v=0;g%2===1?y="l":g>0&&m&&(v=1),n[g]={type:"align",align:y,pregap:v,postgap:0}}return s.colSeparationType=m?"align":"alignat",s},"alignedHandler");Ql({type:"array",names:["array","darray"],props:{numArgs:1},handler(t,e){var r=w3(e[0]),n=r?[e[0]]:xr(e[0],"ordgroup").body,i=n.map(function(s){var l=z7(s),u=l.text;if("lcr".indexOf(u)!==-1)return{type:"align",align:u};if(u==="|")return{type:"separator",separator:"|"};if(u===":")return{type:"separator",separator:":"};throw new gt("Unknown column alignment: "+u,s)}),a={cols:i,hskipBeforeAndAfter:!0,maxNumCols:i.length};return ph(t.parser,a,q7(t.envName))},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(t){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[t.envName.replace("*","")],r="c",n={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if(t.envName.charAt(t.envName.length-1)==="*"){var i=t.parser;if(i.consumeSpaces(),i.fetch().text==="["){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,"lcr".indexOf(r)===-1)throw new gt("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),n.cols=[{type:"align",align:r}]}}var a=ph(t.parser,n,q7(t.envName)),s=Math.max(0,...a.body.map(l=>l.length));return a.cols=new Array(s).fill({type:"align",align:r}),e?{type:"leftright",mode:t.mode,body:[a],left:e[0],right:e[1],rightColor:void 0}:a},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(t){var e={arraystretch:.5},r=ph(t.parser,e,"script");return r.colSeparationType="small",r},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["subarray"],props:{numArgs:1},handler(t,e){var r=w3(e[0]),n=r?[e[0]]:xr(e[0],"ordgroup").body,i=n.map(function(s){var l=z7(s),u=l.text;if("lc".indexOf(u)!==-1)return{type:"align",align:u};throw new gt("Unknown column alignment: "+u,s)});if(i.length>1)throw new gt("{subarray} can contain only one column");var a={cols:i,hskipBeforeAndAfter:!1,arraystretch:.5};if(a=ph(t.parser,a,"script"),a.body.length>0&&a.body[0].length>1)throw new gt("{subarray} can contain only one column");return a},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(t){var e={arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},r=ph(t.parser,e,q7(t.envName));return{type:"leftright",mode:t.mode,body:[r],left:t.envName.indexOf("r")>-1?".":"\\{",right:t.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:yG,htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(t){Jt.contains(["gather","gather*"],t.envName)&&E3(t);var e={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:W7(t.envName),emptySingleRow:!0,leqno:t.parser.settings.leqno};return ph(t.parser,e,"display")},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:yG,htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(t){E3(t);var e={autoTag:W7(t.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:t.parser.settings.leqno};return ph(t.parser,e,"display")},htmlBuilder:Zl,mathmlBuilder:Jl});Ql({type:"array",names:["CD"],props:{numArgs:0},handler(t){return E3(t),p4e(t.parser)},htmlBuilder:Zl,mathmlBuilder:Jl});fe("\\nonumber","\\gdef\\@eqnsw{0}");fe("\\notag","\\nonumber");Nt({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler(t,e){throw new gt(t.funcName+" valid only within array environment")}});Tz=mG;Nt({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];if(i.type!=="ordgroup")throw new gt("Invalid environment name",i);for(var a="",s=0;s<i.body.length;++s)a+=xr(i.body[s],"textord").text;if(n==="\\begin"){if(!Tz.hasOwnProperty(a))throw new gt("No such environment: "+a,i);var l=Tz[a],{args:u,optArgs:h}=r.parseArguments("\\begin{"+a+"}",l),f={mode:r.mode,envName:a,parser:r},d=l.handler(f,u,h);r.expect("\\end",!1);var p=r.nextToken,m=xr(r.parseFunction(),"environment");if(m.name!==a)throw new gt("Mismatch: \\begin{"+a+"} matched by \\end{"+m.name+"}",p);return d}return{type:"environment",mode:r.mode,name:a,nameGroup:i}}});vG=o((t,e)=>{var r=t.font,n=e.withFont(r);return Fr(t.body,n)},"htmlBuilder$5"),xG=o((t,e)=>{var r=t.font,n=e.withFont(r);return yn(t.body,n)},"mathmlBuilder$4"),kz={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};Nt({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=g3(e[0]),a=n;return a in kz&&(a=kz[a]),{type:"font",mode:r.mode,font:a.slice(1),body:i}},"handler"),htmlBuilder:vG,mathmlBuilder:xG});Nt({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r}=t,n=e[0],i=Jt.isCharacterBox(n);return{type:"mclass",mode:r.mode,mclass:T3(n),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:n}],isCharacterBox:i}},"handler")});Nt({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n,breakOnTokenText:i}=t,{mode:a}=r,s=r.parseExpression(!0,i),l="math"+n.slice(1);return{type:"font",mode:a,font:l,body:{type:"ordgroup",mode:r.mode,body:s}}},"handler"),htmlBuilder:vG,mathmlBuilder:xG});bG=o((t,e)=>{var r=e;return t==="display"?r=r.id>=tr.SCRIPT.id?r.text():tr.DISPLAY:t==="text"&&r.size===tr.DISPLAY.size?r=tr.TEXT:t==="script"?r=tr.SCRIPT:t==="scriptscript"&&(r=tr.SCRIPTSCRIPT),r},"adjustStyle"),Y7=o((t,e)=>{var r=bG(t.size,e.style),n=r.fracNum(),i=r.fracDen(),a;a=e.havingStyle(n);var s=Fr(t.numer,a,e);if(t.continued){var l=8.5/e.fontMetrics().ptPerEm,u=3.5/e.fontMetrics().ptPerEm;s.height=s.height<l?l:s.height,s.depth=s.depth<u?u:s.depth}a=e.havingStyle(i);var h=Fr(t.denom,a,e),f,d,p;t.hasBarLine?(t.barSize?(d=ti(t.barSize,e),f=Be.makeLineSpan("frac-line",e,d)):f=Be.makeLineSpan("frac-line",e),d=f.height,p=f.height):(f=null,d=0,p=e.fontMetrics().defaultRuleThickness);var m,g,y;r.size===tr.DISPLAY.size||t.size==="display"?(m=e.fontMetrics().num1,d>0?g=3*p:g=7*p,y=e.fontMetrics().denom1):(d>0?(m=e.fontMetrics().num2,g=p):(m=e.fontMetrics().num3,g=3*p),y=e.fontMetrics().denom2);var v;if(f){var b=e.fontMetrics().axisHeight;m-s.depth-(b+.5*d)<g&&(m+=g-(m-s.depth-(b+.5*d))),b-.5*d-(h.height-y)<g&&(y+=g-(b-.5*d-(h.height-y)));var w=-(b-.5*d);v=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:h,shift:y},{type:"elem",elem:f,shift:w},{type:"elem",elem:s,shift:-m}]},e)}else{var x=m-s.depth-(h.height-y);x<g&&(m+=.5*(g-x),y+=.5*(g-x)),v=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:h,shift:y},{type:"elem",elem:s,shift:-m}]},e)}a=e.havingStyle(r),v.height*=a.sizeMultiplier/e.sizeMultiplier,v.depth*=a.sizeMultiplier/e.sizeMultiplier;var C;r.size===tr.DISPLAY.size?C=e.fontMetrics().delim1:r.size===tr.SCRIPTSCRIPT.size?C=e.havingStyle(tr.SCRIPT).fontMetrics().delim2:C=e.fontMetrics().delim2;var T,E;return t.leftDelim==null?T=Hy(e,["mopen"]):T=ou.customSizedDelim(t.leftDelim,C,!0,e.havingStyle(r),t.mode,["mopen"]),t.continued?E=Be.makeSpan([]):t.rightDelim==null?E=Hy(e,["mclose"]):E=ou.customSizedDelim(t.rightDelim,C,!0,e.havingStyle(r),t.mode,["mclose"]),Be.makeSpan(["mord"].concat(a.sizingClasses(e)),[T,Be.makeSpan(["mfrac"],[v]),E],e)},"htmlBuilder$4"),X7=o((t,e)=>{var r=new dt.MathNode("mfrac",[yn(t.numer,e),yn(t.denom,e)]);if(!t.hasBarLine)r.setAttribute("linethickness","0px");else if(t.barSize){var n=ti(t.barSize,e);r.setAttribute("linethickness",kt(n))}var i=bG(t.size,e.style);if(i.size!==e.style.size){r=new dt.MathNode("mstyle",[r]);var a=i.size===tr.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",a),r.setAttribute("scriptlevel","0")}if(t.leftDelim!=null||t.rightDelim!=null){var s=[];if(t.leftDelim!=null){var l=new dt.MathNode("mo",[new dt.TextNode(t.leftDelim.replace("\\",""))]);l.setAttribute("fence","true"),s.push(l)}if(s.push(r),t.rightDelim!=null){var u=new dt.MathNode("mo",[new dt.TextNode(t.rightDelim.replace("\\",""))]);u.setAttribute("fence","true"),s.push(u)}return F7(s)}return r},"mathmlBuilder$3");Nt({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=e[1],s,l=null,u=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":s=!0;break;case"\\\\atopfrac":s=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":s=!1,l="(",u=")";break;case"\\\\bracefrac":s=!1,l="\\{",u="\\}";break;case"\\\\brackfrac":s=!1,l="[",u="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text";break}return{type:"genfrac",mode:r.mode,continued:!1,numer:i,denom:a,hasBarLine:s,leftDelim:l,rightDelim:u,size:h,barSize:null}},"handler"),htmlBuilder:Y7,mathmlBuilder:X7});Nt({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=e[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:i,denom:a,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}},"handler")});Nt({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(t){var{parser:e,funcName:r,token:n}=t,i;switch(r){case"\\over":i="\\frac";break;case"\\choose":i="\\binom";break;case"\\atop":i="\\\\atopfrac";break;case"\\brace":i="\\\\bracefrac";break;case"\\brack":i="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:e.mode,replaceWith:i,token:n}}});Ez=["display","text","script","scriptscript"],Sz=o(function(e){var r=null;return e.length>0&&(r=e,r=r==="."?null:r),r},"delimFromValue");Nt({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(t,e){var{parser:r}=t,n=e[4],i=e[5],a=g3(e[0]),s=a.type==="atom"&&a.family==="open"?Sz(a.text):null,l=g3(e[1]),u=l.type==="atom"&&l.family==="close"?Sz(l.text):null,h=xr(e[2],"size"),f,d=null;h.isBlank?f=!0:(d=h.value,f=d.number>0);var p="auto",m=e[3];if(m.type==="ordgroup"){if(m.body.length>0){var g=xr(m.body[0],"textord");p=Ez[Number(g.text)]}}else m=xr(m,"textord"),p=Ez[Number(m.text)];return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:f,barSize:d,leftDelim:s,rightDelim:u,size:p}},htmlBuilder:Y7,mathmlBuilder:X7});Nt({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(t,e){var{parser:r,funcName:n,token:i}=t;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:xr(e[0],"size").value,token:i}}});Nt({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0],a=obe(xr(e[1],"infix").size),s=e[2],l=a.number>0;return{type:"genfrac",mode:r.mode,numer:i,denom:s,continued:!1,hasBarLine:l,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},"handler"),htmlBuilder:Y7,mathmlBuilder:X7});wG=o((t,e)=>{var r=e.style,n,i;t.type==="supsub"?(n=t.sup?Fr(t.sup,e.havingStyle(r.sup()),e):Fr(t.sub,e.havingStyle(r.sub()),e),i=xr(t.base,"horizBrace")):i=xr(t,"horizBrace");var a=Fr(i.base,e.havingBaseStyle(tr.DISPLAY)),s=cu.svgSpan(i,e),l;if(i.isOver?(l=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:a},{type:"kern",size:.1},{type:"elem",elem:s}]},e),l.children[0].children[0].children[1].classes.push("svg-align")):(l=Be.makeVList({positionType:"bottom",positionData:a.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:a}]},e),l.children[0].children[0].children[0].classes.push("svg-align")),n){var u=Be.makeSpan(["mord",i.isOver?"mover":"munder"],[l],e);i.isOver?l=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:u},{type:"kern",size:.2},{type:"elem",elem:n}]},e):l=Be.makeVList({positionType:"bottom",positionData:u.depth+.2+n.height+n.depth,children:[{type:"elem",elem:n},{type:"kern",size:.2},{type:"elem",elem:u}]},e)}return Be.makeSpan(["mord",i.isOver?"mover":"munder"],[l],e)},"htmlBuilder$3"),D4e=o((t,e)=>{var r=cu.mathMLnode(t.label);return new dt.MathNode(t.isOver?"mover":"munder",[yn(t.base,e),r])},"mathmlBuilder$2");Nt({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(t,e){var{parser:r,funcName:n}=t;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:e[0]}},htmlBuilder:wG,mathmlBuilder:D4e});Nt({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[1],i=xr(e[0],"url").url;return r.settings.isTrusted({command:"\\href",url:i})?{type:"href",mode:r.mode,href:i,body:di(n)}:r.formatUnsupportedCmd("\\href")},"handler"),htmlBuilder:o((t,e)=>{var r=Pi(t.body,e,!1);return Be.makeAnchor(t.href,[],r,e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=dh(t.body,e);return r instanceof ws||(r=new ws("mrow",[r])),r.setAttribute("href",t.href),r},"mathmlBuilder")});Nt({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=xr(e[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var i=[],a=0;a<n.length;a++){var s=n[a];s==="~"&&(s="\\textasciitilde"),i.push({type:"textord",mode:"text",text:s})}var l={type:"text",mode:r.mode,font:"\\texttt",body:i};return{type:"href",mode:r.mode,href:n,body:di(l)}},"handler")});Nt({type:"hbox",names:["\\hbox"],props:{numArgs:1,argTypes:["text"],allowedInText:!0,primitive:!0},handler(t,e){var{parser:r}=t;return{type:"hbox",mode:r.mode,body:di(e[0])}},htmlBuilder(t,e){var r=Pi(t.body,e,!1);return Be.makeFragment(r)},mathmlBuilder(t,e){return new dt.MathNode("mrow",ks(t.body,e))}});Nt({type:"html",names:["\\htmlClass","\\htmlId","\\htmlStyle","\\htmlData"],props:{numArgs:2,argTypes:["raw","original"],allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n,token:i}=t,a=xr(e[0],"raw").string,s=e[1];r.settings.strict&&r.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var l,u={};switch(n){case"\\htmlClass":u.class=a,l={command:"\\htmlClass",class:a};break;case"\\htmlId":u.id=a,l={command:"\\htmlId",id:a};break;case"\\htmlStyle":u.style=a,l={command:"\\htmlStyle",style:a};break;case"\\htmlData":{for(var h=a.split(","),f=0;f<h.length;f++){var d=h[f].split("=");if(d.length!==2)throw new gt("Error parsing key-value for \\htmlData");u["data-"+d[0].trim()]=d[1].trim()}l={command:"\\htmlData",attributes:u};break}default:throw new Error("Unrecognized html command")}return r.settings.isTrusted(l)?{type:"html",mode:r.mode,attributes:u,body:di(s)}:r.formatUnsupportedCmd(n)},"handler"),htmlBuilder:o((t,e)=>{var r=Pi(t.body,e,!1),n=["enclosing"];t.attributes.class&&n.push(...t.attributes.class.trim().split(/\s+/));var i=Be.makeSpan(n,r,e);for(var a in t.attributes)a!=="class"&&t.attributes.hasOwnProperty(a)&&i.setAttribute(a,t.attributes[a]);return i},"htmlBuilder"),mathmlBuilder:o((t,e)=>dh(t.body,e),"mathmlBuilder")});Nt({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t;return{type:"htmlmathml",mode:r.mode,html:di(e[0]),mathml:di(e[1])}},"handler"),htmlBuilder:o((t,e)=>{var r=Pi(t.html,e,!1);return Be.makeFragment(r)},"htmlBuilder"),mathmlBuilder:o((t,e)=>dh(t.mathml,e),"mathmlBuilder")});x7=o(function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var r=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!r)throw new gt("Invalid size: '"+e+"' in \\includegraphics");var n={number:+(r[1]+r[2]),unit:r[3]};if(!zz(n))throw new gt("Invalid unit: '"+n.unit+"' in \\includegraphics.");return n},"sizeData");Nt({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:o((t,e,r)=>{var{parser:n}=t,i={number:0,unit:"em"},a={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var u=xr(r[0],"raw").string,h=u.split(","),f=0;f<h.length;f++){var d=h[f].split("=");if(d.length===2){var p=d[1].trim();switch(d[0].trim()){case"alt":l=p;break;case"width":i=x7(p);break;case"height":a=x7(p);break;case"totalheight":s=x7(p);break;default:throw new gt("Invalid key: '"+d[0]+"' in \\includegraphics.")}}}var m=xr(e[0],"url").url;return l===""&&(l=m,l=l.replace(/^.*[\\/]/,""),l=l.substring(0,l.lastIndexOf("."))),n.settings.isTrusted({command:"\\includegraphics",url:m})?{type:"includegraphics",mode:n.mode,alt:l,width:i,height:a,totalheight:s,src:m}:n.formatUnsupportedCmd("\\includegraphics")},"handler"),htmlBuilder:o((t,e)=>{var r=ti(t.height,e),n=0;t.totalheight.number>0&&(n=ti(t.totalheight,e)-r);var i=0;t.width.number>0&&(i=ti(t.width,e));var a={height:kt(r+n)};i>0&&(a.width=kt(i)),n>0&&(a.verticalAlign=kt(-n));var s=new S7(t.src,t.alt,a);return s.height=r,s.depth=n,s},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mglyph",[]);r.setAttribute("alt",t.alt);var n=ti(t.height,e),i=0;if(t.totalheight.number>0&&(i=ti(t.totalheight,e)-n,r.setAttribute("valign",kt(-i))),r.setAttribute("height",kt(n+i)),t.width.number>0){var a=ti(t.width,e);r.setAttribute("width",kt(a))}return r.setAttribute("src",t.src),r},"mathmlBuilder")});Nt({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(t,e){var{parser:r,funcName:n}=t,i=xr(e[0],"size");if(r.settings.strict){var a=n[1]==="m",s=i.value.unit==="mu";a?(s||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, "+("not "+i.value.unit+" units")),r.mode!=="math"&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):s&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:i.value}},htmlBuilder(t,e){return Be.makeGlue(t.dimension,e)},mathmlBuilder(t,e){var r=ti(t.dimension,e);return new dt.SpaceNode(r)}});Nt({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:i}},"handler"),htmlBuilder:o((t,e)=>{var r;t.alignment==="clap"?(r=Be.makeSpan([],[Fr(t.body,e)]),r=Be.makeSpan(["inner"],[r],e)):r=Be.makeSpan(["inner"],[Fr(t.body,e)]);var n=Be.makeSpan(["fix"],[]),i=Be.makeSpan([t.alignment],[r,n],e),a=Be.makeSpan(["strut"]);return a.style.height=kt(i.height+i.depth),i.depth&&(a.style.verticalAlign=kt(-i.depth)),i.children.unshift(a),i=Be.makeSpan(["thinbox"],[i],e),Be.makeSpan(["mord","vbox"],[i],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mpadded",[yn(t.body,e)]);if(t.alignment!=="rlap"){var n=t.alignment==="llap"?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r},"mathmlBuilder")});Nt({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){var{funcName:r,parser:n}=t,i=n.mode;n.switchMode("math");var a=r==="\\("?"\\)":"$",s=n.parseExpression(!1,a);return n.expect(a),n.switchMode(i),{type:"styling",mode:n.mode,style:"text",body:s}}});Nt({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(t,e){throw new gt("Mismatched "+t.funcName)}});Cz=o((t,e)=>{switch(e.style.size){case tr.DISPLAY.size:return t.display;case tr.TEXT.size:return t.text;case tr.SCRIPT.size:return t.script;case tr.SCRIPTSCRIPT.size:return t.scriptscript;default:return t.text}},"chooseMathStyle");Nt({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:o((t,e)=>{var{parser:r}=t;return{type:"mathchoice",mode:r.mode,display:di(e[0]),text:di(e[1]),script:di(e[2]),scriptscript:di(e[3])}},"handler"),htmlBuilder:o((t,e)=>{var r=Cz(t,e),n=Pi(r,e,!1);return Be.makeFragment(n)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=Cz(t,e);return dh(r,e)},"mathmlBuilder")});TG=o((t,e,r,n,i,a,s)=>{t=Be.makeSpan([],[t]);var l=r&&Jt.isCharacterBox(r),u,h;if(e){var f=Fr(e,n.havingStyle(i.sup()),n);h={elem:f,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-f.depth)}}if(r){var d=Fr(r,n.havingStyle(i.sub()),n);u={elem:d,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-d.height)}}var p;if(h&&u){var m=n.fontMetrics().bigOpSpacing5+u.elem.height+u.elem.depth+u.kern+t.depth+s;p=Be.makeVList({positionType:"bottom",positionData:m,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:u.elem,marginLeft:kt(-a)},{type:"kern",size:u.kern},{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:kt(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(u){var g=t.height-s;p=Be.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:u.elem,marginLeft:kt(-a)},{type:"kern",size:u.kern},{type:"elem",elem:t}]},n)}else if(h){var y=t.depth+s;p=Be.makeVList({positionType:"bottom",positionData:y,children:[{type:"elem",elem:t},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:kt(a)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else return t;var v=[p];if(u&&a!==0&&!l){var x=Be.makeSpan(["mspace"],[],n);x.style.marginRight=kt(a),v.unshift(x)}return Be.makeSpan(["mop","op-limits"],v,n)},"assembleSupSub"),kG=["\\smallint"],m0=o((t,e)=>{var r,n,i=!1,a;t.type==="supsub"?(r=t.sup,n=t.sub,a=xr(t.base,"op"),i=!0):a=xr(t,"op");var s=e.style,l=!1;s.size===tr.DISPLAY.size&&a.symbol&&!Jt.contains(kG,a.name)&&(l=!0);var u;if(a.symbol){var h=l?"Size2-Regular":"Size1-Regular",f="";if((a.name==="\\oiint"||a.name==="\\oiiint")&&(f=a.name.slice(1),a.name=f==="oiint"?"\\iint":"\\iiint"),u=Be.makeSymbol(a.name,h,"math",e,["mop","op-symbol",l?"large-op":"small-op"]),f.length>0){var d=u.italic,p=Be.staticSvg(f+"Size"+(l?"2":"1"),e);u=Be.makeVList({positionType:"individualShift",children:[{type:"elem",elem:u,shift:0},{type:"elem",elem:p,shift:l?.08:0}]},e),a.name="\\"+f,u.classes.unshift("mop"),u.italic=d}}else if(a.body){var m=Pi(a.body,e,!0);m.length===1&&m[0]instanceof Ts?(u=m[0],u.classes[0]="mop"):u=Be.makeSpan(["mop"],m,e)}else{for(var g=[],y=1;y<a.name.length;y++)g.push(Be.mathsym(a.name[y],a.mode,e));u=Be.makeSpan(["mop"],g,e)}var v=0,x=0;return(u instanceof Ts||a.name==="\\oiint"||a.name==="\\oiiint")&&!a.suppressBaseShift&&(v=(u.height-u.depth)/2-e.fontMetrics().axisHeight,x=u.italic),i?TG(u,r,n,e,s,x,v):(v&&(u.style.position="relative",u.style.top=kt(v)),u)},"htmlBuilder$2"),Wy=o((t,e)=>{var r;if(t.symbol)r=new ws("mo",[Co(t.name,t.mode)]),Jt.contains(kG,t.name)&&r.setAttribute("largeop","false");else if(t.body)r=new ws("mo",ks(t.body,e));else{r=new ws("mi",[new Jf(t.name.slice(1))]);var n=new ws("mo",[Co("\u2061","text")]);t.parentIsSupSub?r=new ws("mrow",[r,n]):r=Qz([r,n])}return r},"mathmlBuilder$1"),L4e={"\u220F":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22C0":"\\bigwedge","\u22C1":"\\bigvee","\u22C2":"\\bigcap","\u22C3":"\\bigcup","\u2A00":"\\bigodot","\u2A01":"\\bigoplus","\u2A02":"\\bigotimes","\u2A04":"\\biguplus","\u2A06":"\\bigsqcup"};Nt({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220F","\u2210","\u2211","\u22C0","\u22C1","\u22C2","\u22C3","\u2A00","\u2A01","\u2A02","\u2A04","\u2A06"],props:{numArgs:0},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=n;return i.length===1&&(i=L4e[i]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:i}},"handler"),htmlBuilder:m0,mathmlBuilder:Wy});Nt({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:di(n)}},"handler"),htmlBuilder:m0,mathmlBuilder:Wy});R4e={"\u222B":"\\int","\u222C":"\\iint","\u222D":"\\iiint","\u222E":"\\oint","\u222F":"\\oiint","\u2230":"\\oiiint"};Nt({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:m0,mathmlBuilder:Wy});Nt({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:m0,mathmlBuilder:Wy});Nt({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222B","\u222C","\u222D","\u222E","\u222F","\u2230"],props:{numArgs:0},handler(t){var{parser:e,funcName:r}=t,n=r;return n.length===1&&(n=R4e[n]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:m0,mathmlBuilder:Wy});EG=o((t,e)=>{var r,n,i=!1,a;t.type==="supsub"?(r=t.sup,n=t.sub,a=xr(t.base,"operatorname"),i=!0):a=xr(t,"operatorname");var s;if(a.body.length>0){for(var l=a.body.map(d=>{var p=d.text;return typeof p=="string"?{type:"textord",mode:d.mode,text:p}:d}),u=Pi(l,e.withFont("mathrm"),!0),h=0;h<u.length;h++){var f=u[h];f instanceof Ts&&(f.text=f.text.replace(/\u2212/,"-").replace(/\u2217/,"*"))}s=Be.makeSpan(["mop"],u,e)}else s=Be.makeSpan(["mop"],[],e);return i?TG(s,r,n,e,e.style,0,0):s},"htmlBuilder$1"),N4e=o((t,e)=>{for(var r=ks(t.body,e.withFont("mathrm")),n=!0,i=0;i<r.length;i++){var a=r[i];if(!(a instanceof dt.SpaceNode))if(a instanceof dt.MathNode)switch(a.type){case"mi":case"mn":case"ms":case"mspace":case"mtext":break;case"mo":{var s=a.children[0];a.children.length===1&&s instanceof dt.TextNode?s.text=s.text.replace(/\u2212/,"-").replace(/\u2217/,"*"):n=!1;break}default:n=!1}else n=!1}if(n){var l=r.map(f=>f.toText()).join("");r=[new dt.TextNode(l)]}var u=new dt.MathNode("mi",r);u.setAttribute("mathvariant","normal");var h=new dt.MathNode("mo",[Co("\u2061","text")]);return t.parentIsSupSub?new dt.MathNode("mrow",[u,h]):dt.newDocumentFragment([u,h])},"mathmlBuilder");Nt({type:"operatorname",names:["\\operatorname@","\\operatornamewithlimits"],props:{numArgs:1},handler:o((t,e)=>{var{parser:r,funcName:n}=t,i=e[0];return{type:"operatorname",mode:r.mode,body:di(i),alwaysHandleSupSub:n==="\\operatornamewithlimits",limits:!1,parentIsSupSub:!1}},"handler"),htmlBuilder:EG,mathmlBuilder:N4e});fe("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@");rd({type:"ordgroup",htmlBuilder(t,e){return t.semisimple?Be.makeFragment(Pi(t.body,e,!1)):Be.makeSpan(["mord"],Pi(t.body,e,!0),e)},mathmlBuilder(t,e){return dh(t.body,e,!0)}});Nt({type:"overline",names:["\\overline"],props:{numArgs:1},handler(t,e){var{parser:r}=t,n=e[0];return{type:"overline",mode:r.mode,body:n}},htmlBuilder(t,e){var r=Fr(t.body,e.havingCrampedStyle()),n=Be.makeLineSpan("overline-line",e),i=e.fontMetrics().defaultRuleThickness,a=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*i},{type:"elem",elem:n},{type:"kern",size:i}]},e);return Be.makeSpan(["mord","overline"],[a],e)},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[new dt.TextNode("\u203E")]);r.setAttribute("stretchy","true");var n=new dt.MathNode("mover",[yn(t.body,e),r]);return n.setAttribute("accent","true"),n}});Nt({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"phantom",mode:r.mode,body:di(n)}},"handler"),htmlBuilder:o((t,e)=>{var r=Pi(t.body,e.withPhantom(),!1);return Be.makeFragment(r)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=ks(t.body,e);return new dt.MathNode("mphantom",r)},"mathmlBuilder")});Nt({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"hphantom",mode:r.mode,body:n}},"handler"),htmlBuilder:o((t,e)=>{var r=Be.makeSpan([],[Fr(t.body,e.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var n=0;n<r.children.length;n++)r.children[n].height=0,r.children[n].depth=0;return r=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r}]},e),Be.makeSpan(["mord"],[r],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=ks(di(t.body),e),n=new dt.MathNode("mphantom",r),i=new dt.MathNode("mpadded",[n]);return i.setAttribute("height","0px"),i.setAttribute("depth","0px"),i},"mathmlBuilder")});Nt({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:o((t,e)=>{var{parser:r}=t,n=e[0];return{type:"vphantom",mode:r.mode,body:n}},"handler"),htmlBuilder:o((t,e)=>{var r=Be.makeSpan(["inner"],[Fr(t.body,e.withPhantom())]),n=Be.makeSpan(["fix"],[]);return Be.makeSpan(["mord","rlap"],[r,n],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=ks(di(t.body),e),n=new dt.MathNode("mphantom",r),i=new dt.MathNode("mpadded",[n]);return i.setAttribute("width","0px"),i},"mathmlBuilder")});Nt({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(t,e){var{parser:r}=t,n=xr(e[0],"size").value,i=e[1];return{type:"raisebox",mode:r.mode,dy:n,body:i}},htmlBuilder(t,e){var r=Fr(t.body,e),n=ti(t.dy,e);return Be.makeVList({positionType:"shift",positionData:-n,children:[{type:"elem",elem:r}]},e)},mathmlBuilder(t,e){var r=new dt.MathNode("mpadded",[yn(t.body,e)]),n=t.dy.number+t.dy.unit;return r.setAttribute("voffset",n),r}});Nt({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0},handler(t){var{parser:e}=t;return{type:"internal",mode:e.mode}}});Nt({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,argTypes:["size","size","size"]},handler(t,e,r){var{parser:n}=t,i=r[0],a=xr(e[0],"size"),s=xr(e[1],"size");return{type:"rule",mode:n.mode,shift:i&&xr(i,"size").value,width:a.value,height:s.value}},htmlBuilder(t,e){var r=Be.makeSpan(["mord","rule"],[],e),n=ti(t.width,e),i=ti(t.height,e),a=t.shift?ti(t.shift,e):0;return r.style.borderRightWidth=kt(n),r.style.borderTopWidth=kt(i),r.style.bottom=kt(a),r.width=n,r.height=i+a,r.depth=-a,r.maxFontSize=i*1.125*e.sizeMultiplier,r},mathmlBuilder(t,e){var r=ti(t.width,e),n=ti(t.height,e),i=t.shift?ti(t.shift,e):0,a=e.color&&e.getColor()||"black",s=new dt.MathNode("mspace");s.setAttribute("mathbackground",a),s.setAttribute("width",kt(r)),s.setAttribute("height",kt(n));var l=new dt.MathNode("mpadded",[s]);return i>=0?l.setAttribute("height",kt(i)):(l.setAttribute("height",kt(i)),l.setAttribute("depth",kt(-i))),l.setAttribute("voffset",kt(i)),l}});o(SG,"sizingGroup");Az=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"],M4e=o((t,e)=>{var r=e.havingSize(t.size);return SG(t.body,r,e)},"htmlBuilder");Nt({type:"sizing",names:Az,props:{numArgs:0,allowedInText:!0},handler:o((t,e)=>{var{breakOnTokenText:r,funcName:n,parser:i}=t,a=i.parseExpression(!1,r);return{type:"sizing",mode:i.mode,size:Az.indexOf(n)+1,body:a}},"handler"),htmlBuilder:M4e,mathmlBuilder:o((t,e)=>{var r=e.havingSize(t.size),n=ks(t.body,r),i=new dt.MathNode("mstyle",n);return i.setAttribute("mathsize",kt(r.sizeMultiplier)),i},"mathmlBuilder")});Nt({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:o((t,e,r)=>{var{parser:n}=t,i=!1,a=!1,s=r[0]&&xr(r[0],"ordgroup");if(s)for(var l="",u=0;u<s.body.length;++u){var h=s.body[u];if(l=h.text,l==="t")i=!0;else if(l==="b")a=!0;else{i=!1,a=!1;break}}else i=!0,a=!0;var f=e[0];return{type:"smash",mode:n.mode,body:f,smashHeight:i,smashDepth:a}},"handler"),htmlBuilder:o((t,e)=>{var r=Be.makeSpan([],[Fr(t.body,e)]);if(!t.smashHeight&&!t.smashDepth)return r;if(t.smashHeight&&(r.height=0,r.children))for(var n=0;n<r.children.length;n++)r.children[n].height=0;if(t.smashDepth&&(r.depth=0,r.children))for(var i=0;i<r.children.length;i++)r.children[i].depth=0;var a=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r}]},e);return Be.makeSpan(["mord"],[a],e)},"htmlBuilder"),mathmlBuilder:o((t,e)=>{var r=new dt.MathNode("mpadded",[yn(t.body,e)]);return t.smashHeight&&r.setAttribute("height","0px"),t.smashDepth&&r.setAttribute("depth","0px"),r},"mathmlBuilder")});Nt({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(t,e,r){var{parser:n}=t,i=r[0],a=e[0];return{type:"sqrt",mode:n.mode,body:a,index:i}},htmlBuilder(t,e){var r=Fr(t.body,e.havingCrampedStyle());r.height===0&&(r.height=e.fontMetrics().xHeight),r=Be.wrapFragment(r,e);var n=e.fontMetrics(),i=n.defaultRuleThickness,a=i;e.style.id<tr.TEXT.id&&(a=e.fontMetrics().xHeight);var s=i+a/4,l=r.height+r.depth+s+i,{span:u,ruleWidth:h,advanceWidth:f}=ou.sqrtImage(l,e),d=u.height-h;d>r.height+r.depth+s&&(s=(s+d-r.height-r.depth)/2);var p=u.height-r.height-s-h;r.style.paddingLeft=kt(f);var m=Be.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+p)},{type:"elem",elem:u},{type:"kern",size:h}]},e);if(t.index){var g=e.havingStyle(tr.SCRIPTSCRIPT),y=Fr(t.index,g,e),v=.6*(m.height-m.depth),x=Be.makeVList({positionType:"shift",positionData:-v,children:[{type:"elem",elem:y}]},e),b=Be.makeSpan(["root"],[x]);return Be.makeSpan(["mord","sqrt"],[b,m],e)}else return Be.makeSpan(["mord","sqrt"],[m],e)},mathmlBuilder(t,e){var{body:r,index:n}=t;return n?new dt.MathNode("mroot",[yn(r,e),yn(n,e)]):new dt.MathNode("msqrt",[yn(r,e)])}});_z={display:tr.DISPLAY,text:tr.TEXT,script:tr.SCRIPT,scriptscript:tr.SCRIPTSCRIPT};Nt({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(t,e){var{breakOnTokenText:r,funcName:n,parser:i}=t,a=i.parseExpression(!0,r),s=n.slice(1,n.length-5);return{type:"styling",mode:i.mode,style:s,body:a}},htmlBuilder(t,e){var r=_z[t.style],n=e.havingStyle(r).withFont("");return SG(t.body,n,e)},mathmlBuilder(t,e){var r=_z[t.style],n=e.havingStyle(r),i=ks(t.body,n),a=new dt.MathNode("mstyle",i),s={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]},l=s[t.style];return a.setAttribute("scriptlevel",l[0]),a.setAttribute("displaystyle",l[1]),a}});I4e=o(function(e,r){var n=e.base;if(n)if(n.type==="op"){var i=n.limits&&(r.style.size===tr.DISPLAY.size||n.alwaysHandleSupSub);return i?m0:null}else if(n.type==="operatorname"){var a=n.alwaysHandleSupSub&&(r.style.size===tr.DISPLAY.size||n.limits);return a?EG:null}else{if(n.type==="accent")return Jt.isCharacterBox(n.base)?G7:null;if(n.type==="horizBrace"){var s=!e.sub;return s===n.isOver?wG:null}else return null}else return null},"htmlBuilderDelegate");rd({type:"supsub",htmlBuilder(t,e){var r=I4e(t,e);if(r)return r(t,e);var{base:n,sup:i,sub:a}=t,s=Fr(n,e),l,u,h=e.fontMetrics(),f=0,d=0,p=n&&Jt.isCharacterBox(n);if(i){var m=e.havingStyle(e.style.sup());l=Fr(i,m,e),p||(f=s.height-m.fontMetrics().supDrop*m.sizeMultiplier/e.sizeMultiplier)}if(a){var g=e.havingStyle(e.style.sub());u=Fr(a,g,e),p||(d=s.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}var y;e.style===tr.DISPLAY?y=h.sup1:e.style.cramped?y=h.sup3:y=h.sup2;var v=e.sizeMultiplier,x=kt(.5/h.ptPerEm/v),b=null;if(u){var w=t.base&&t.base.type==="op"&&t.base.name&&(t.base.name==="\\oiint"||t.base.name==="\\oiiint");(s instanceof Ts||w)&&(b=kt(-s.italic))}var C;if(l&&u){f=Math.max(f,y,l.depth+.25*h.xHeight),d=Math.max(d,h.sub2);var T=h.defaultRuleThickness,E=4*T;if(f-l.depth-(u.height-d)<E){d=E-(f-l.depth)+u.height;var A=.8*h.xHeight-(f-l.depth);A>0&&(f+=A,d-=A)}var S=[{type:"elem",elem:u,shift:d,marginRight:x,marginLeft:b},{type:"elem",elem:l,shift:-f,marginRight:x}];C=Be.makeVList({positionType:"individualShift",children:S},e)}else if(u){d=Math.max(d,h.sub1,u.height-.8*h.xHeight);var _=[{type:"elem",elem:u,marginLeft:b,marginRight:x}];C=Be.makeVList({positionType:"shift",positionData:d,children:_},e)}else if(l)f=Math.max(f,y,l.depth+.25*h.xHeight),C=Be.makeVList({positionType:"shift",positionData:-f,children:[{type:"elem",elem:l,marginRight:x}]},e);else throw new Error("supsub must have either sup or sub.");var I=A7(s,"right")||"mord";return Be.makeSpan([I],[s,Be.makeSpan(["msupsub"],[C])],e)},mathmlBuilder(t,e){var r=!1,n,i;t.base&&t.base.type==="horizBrace"&&(i=!!t.sup,i===t.base.isOver&&(r=!0,n=t.base.isOver)),t.base&&(t.base.type==="op"||t.base.type==="operatorname")&&(t.base.parentIsSupSub=!0);var a=[yn(t.base,e)];t.sub&&a.push(yn(t.sub,e)),t.sup&&a.push(yn(t.sup,e));var s;if(r)s=n?"mover":"munder";else if(t.sub)if(t.sup){var h=t.base;h&&h.type==="op"&&h.limits&&e.style===tr.DISPLAY||h&&h.type==="operatorname"&&h.alwaysHandleSupSub&&(e.style===tr.DISPLAY||h.limits)?s="munderover":s="msubsup"}else{var u=t.base;u&&u.type==="op"&&u.limits&&(e.style===tr.DISPLAY||u.alwaysHandleSupSub)||u&&u.type==="operatorname"&&u.alwaysHandleSupSub&&(u.limits||e.style===tr.DISPLAY)?s="munder":s="msub"}else{var l=t.base;l&&l.type==="op"&&l.limits&&(e.style===tr.DISPLAY||l.alwaysHandleSupSub)||l&&l.type==="operatorname"&&l.alwaysHandleSupSub&&(l.limits||e.style===tr.DISPLAY)?s="mover":s="msup"}return new dt.MathNode(s,a)}});rd({type:"atom",htmlBuilder(t,e){return Be.mathsym(t.text,t.mode,e,["m"+t.family])},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[Co(t.text,t.mode)]);if(t.family==="bin"){var n=$7(t,e);n==="bold-italic"&&r.setAttribute("mathvariant",n)}else t.family==="punct"?r.setAttribute("separator","true"):(t.family==="open"||t.family==="close")&&r.setAttribute("stretchy","false");return r}});CG={mi:"italic",mn:"normal",mtext:"normal"};rd({type:"mathord",htmlBuilder(t,e){return Be.makeOrd(t,e,"mathord")},mathmlBuilder(t,e){var r=new dt.MathNode("mi",[Co(t.text,t.mode,e)]),n=$7(t,e)||"italic";return n!==CG[r.type]&&r.setAttribute("mathvariant",n),r}});rd({type:"textord",htmlBuilder(t,e){return Be.makeOrd(t,e,"textord")},mathmlBuilder(t,e){var r=Co(t.text,t.mode,e),n=$7(t,e)||"normal",i;return t.mode==="text"?i=new dt.MathNode("mtext",[r]):/[0-9]/.test(t.text)?i=new dt.MathNode("mn",[r]):t.text==="\\prime"?i=new dt.MathNode("mo",[r]):i=new dt.MathNode("mi",[r]),n!==CG[i.type]&&i.setAttribute("mathvariant",n),i}});b7={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},w7={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};rd({type:"spacing",htmlBuilder(t,e){if(w7.hasOwnProperty(t.text)){var r=w7[t.text].className||"";if(t.mode==="text"){var n=Be.makeOrd(t,e,"textord");return n.classes.push(r),n}else return Be.makeSpan(["mspace",r],[Be.mathsym(t.text,t.mode,e)],e)}else{if(b7.hasOwnProperty(t.text))return Be.makeSpan(["mspace",b7[t.text]],[],e);throw new gt('Unknown type of space "'+t.text+'"')}},mathmlBuilder(t,e){var r;if(w7.hasOwnProperty(t.text))r=new dt.MathNode("mtext",[new dt.TextNode("\xA0")]);else{if(b7.hasOwnProperty(t.text))return new dt.MathNode("mspace");throw new gt('Unknown type of space "'+t.text+'"')}return r}});Dz=o(()=>{var t=new dt.MathNode("mtd",[]);return t.setAttribute("width","50%"),t},"pad");rd({type:"tag",mathmlBuilder(t,e){var r=new dt.MathNode("mtable",[new dt.MathNode("mtr",[Dz(),new dt.MathNode("mtd",[dh(t.body,e)]),Dz(),new dt.MathNode("mtd",[dh(t.tag,e)])])]);return r.setAttribute("width","100%"),r}});Lz={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},Rz={"\\textbf":"textbf","\\textmd":"textmd"},O4e={"\\textit":"textit","\\textup":"textup"},Nz=o((t,e)=>{var r=t.font;if(r){if(Lz[r])return e.withTextFontFamily(Lz[r]);if(Rz[r])return e.withTextFontWeight(Rz[r]);if(r==="\\emph")return e.fontShape==="textit"?e.withTextFontShape("textup"):e.withTextFontShape("textit")}else return e;return e.withTextFontShape(O4e[r])},"optionsWithFont");Nt({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(t,e){var{parser:r,funcName:n}=t,i=e[0];return{type:"text",mode:r.mode,body:di(i),font:n}},htmlBuilder(t,e){var r=Nz(t,e),n=Pi(t.body,r,!0);return Be.makeSpan(["mord","text"],n,r)},mathmlBuilder(t,e){var r=Nz(t,e);return dh(t.body,r)}});Nt({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(t,e){var{parser:r}=t;return{type:"underline",mode:r.mode,body:e[0]}},htmlBuilder(t,e){var r=Fr(t.body,e),n=Be.makeLineSpan("underline-line",e),i=e.fontMetrics().defaultRuleThickness,a=Be.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:i},{type:"elem",elem:n},{type:"kern",size:3*i},{type:"elem",elem:r}]},e);return Be.makeSpan(["mord","underline"],[a],e)},mathmlBuilder(t,e){var r=new dt.MathNode("mo",[new dt.TextNode("\u203E")]);r.setAttribute("stretchy","true");var n=new dt.MathNode("munder",[yn(t.body,e),r]);return n.setAttribute("accentunder","true"),n}});Nt({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(t,e){var{parser:r}=t;return{type:"vcenter",mode:r.mode,body:e[0]}},htmlBuilder(t,e){var r=Fr(t.body,e),n=e.fontMetrics().axisHeight,i=.5*(r.height-n-(r.depth+n));return Be.makeVList({positionType:"shift",positionData:i,children:[{type:"elem",elem:r}]},e)},mathmlBuilder(t,e){return new dt.MathNode("mpadded",[yn(t.body,e)],["vcenter"])}});Nt({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(t,e,r){throw new gt("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(t,e){for(var r=Mz(t),n=[],i=e.havingStyle(e.style.text()),a=0;a<r.length;a++){var s=r[a];s==="~"&&(s="\\textasciitilde"),n.push(Be.makeSymbol(s,"Typewriter-Regular",t.mode,i,["mord","texttt"]))}return Be.makeSpan(["mord","text"].concat(i.sizingClasses(e)),Be.tryCombineChars(n),i)},mathmlBuilder(t,e){var r=new dt.TextNode(Mz(t)),n=new dt.MathNode("mtext",[r]);return n.setAttribute("mathvariant","monospace"),n}});Mz=o(t=>t.body.replace(/ /g,t.star?"\u2423":"\xA0"),"makeVerb"),hh=jz,AG=`[ \r
+ ]`,P4e="\\\\[a-zA-Z@]+",B4e="\\\\[^\uD800-\uDFFF]",F4e="("+P4e+")"+AG+"*",$4e=`\\\\(
+|[ \r ]+
+?)[ \r ]*`,N7="[\u0300-\u036F]",z4e=new RegExp(N7+"+$"),G4e="("+AG+"+)|"+($4e+"|")+"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]"+(N7+"*")+"|[\uD800-\uDBFF][\uDC00-\uDFFF]"+(N7+"*")+"|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5"+("|"+F4e)+("|"+B4e+")"),y3=class{static{o(this,"Lexer")}constructor(e,r){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=r,this.tokenRegex=new RegExp(G4e,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,r){this.catcodes[e]=r}lex(){var e=this.input,r=this.tokenRegex.lastIndex;if(r===e.length)return new So("EOF",new Xs(this,r,r));var n=this.tokenRegex.exec(e);if(n===null||n.index!==r)throw new gt("Unexpected character: '"+e[r]+"'",new So(e[r],new Xs(this,r,r+1)));var i=n[6]||n[3]||(n[2]?"\\ ":" ");if(this.catcodes[i]===14){var a=e.indexOf(`
+`,this.tokenRegex.lastIndex);return a===-1?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=a+1,this.lex()}return new So(i,new Xs(this,r,this.tokenRegex.lastIndex))}},M7=class{static{o(this,"Namespace")}constructor(e,r){e===void 0&&(e={}),r===void 0&&(r={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=r,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(this.undefStack.length===0)throw new gt("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var r in e)e.hasOwnProperty(r)&&(e[r]==null?delete this.current[r]:this.current[r]=e[r])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,r,n){if(n===void 0&&(n=!1),n){for(var i=0;i<this.undefStack.length;i++)delete this.undefStack[i][e];this.undefStack.length>0&&(this.undefStack[this.undefStack.length-1][e]=r)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}r==null?delete this.current[e]:this.current[e]=r}},V4e=gG;fe("\\noexpand",function(t){var e=t.popToken();return t.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}});fe("\\expandafter",function(t){var e=t.popToken();return t.expandOnce(!0),{tokens:[e],numArgs:0}});fe("\\@firstoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[0],numArgs:0}});fe("\\@secondoftwo",function(t){var e=t.consumeArgs(2);return{tokens:e[1],numArgs:0}});fe("\\@ifnextchar",function(t){var e=t.consumeArgs(3);t.consumeSpaces();var r=t.future();return e[0].length===1&&e[0][0].text===r.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}});fe("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}");fe("\\TextOrMath",function(t){var e=t.consumeArgs(2);return t.mode==="text"?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});Iz={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};fe("\\char",function(t){var e=t.popToken(),r,n="";if(e.text==="'")r=8,e=t.popToken();else if(e.text==='"')r=16,e=t.popToken();else if(e.text==="`")if(e=t.popToken(),e.text[0]==="\\")n=e.text.charCodeAt(1);else{if(e.text==="EOF")throw new gt("\\char` missing argument");n=e.text.charCodeAt(0)}else r=10;if(r){if(n=Iz[e.text],n==null||n>=r)throw new gt("Invalid base-"+r+" digit "+e.text);for(var i;(i=Iz[t.future().text])!=null&&i<r;)n*=r,n+=i,t.popToken()}return"\\@char{"+n+"}"});j7=o((t,e,r)=>{var n=t.consumeArg().tokens;if(n.length!==1)throw new gt("\\newcommand's first argument must be a macro name");var i=n[0].text,a=t.isDefined(i);if(a&&!e)throw new gt("\\newcommand{"+i+"} attempting to redefine "+(i+"; use \\renewcommand"));if(!a&&!r)throw new gt("\\renewcommand{"+i+"} when command "+i+" does not yet exist; use \\newcommand");var s=0;if(n=t.consumeArg().tokens,n.length===1&&n[0].text==="["){for(var l="",u=t.expandNextToken();u.text!=="]"&&u.text!=="EOF";)l+=u.text,u=t.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new gt("Invalid number of arguments: "+l);s=parseInt(l),n=t.consumeArg().tokens}return t.macros.set(i,{tokens:n,numArgs:s}),""},"newcommand");fe("\\newcommand",t=>j7(t,!1,!0));fe("\\renewcommand",t=>j7(t,!0,!1));fe("\\providecommand",t=>j7(t,!0,!0));fe("\\message",t=>{var e=t.consumeArgs(1)[0];return console.log(e.reverse().map(r=>r.text).join("")),""});fe("\\errmessage",t=>{var e=t.consumeArgs(1)[0];return console.error(e.reverse().map(r=>r.text).join("")),""});fe("\\show",t=>{var e=t.popToken(),r=e.text;return console.log(e,t.macros.get(r),hh[r],An.math[r],An.text[r]),""});fe("\\bgroup","{");fe("\\egroup","}");fe("~","\\nobreakspace");fe("\\lq","`");fe("\\rq","'");fe("\\aa","\\r a");fe("\\AA","\\r A");fe("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xA9}");fe("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");fe("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xAE}");fe("\u212C","\\mathscr{B}");fe("\u2130","\\mathscr{E}");fe("\u2131","\\mathscr{F}");fe("\u210B","\\mathscr{H}");fe("\u2110","\\mathscr{I}");fe("\u2112","\\mathscr{L}");fe("\u2133","\\mathscr{M}");fe("\u211B","\\mathscr{R}");fe("\u212D","\\mathfrak{C}");fe("\u210C","\\mathfrak{H}");fe("\u2128","\\mathfrak{Z}");fe("\\Bbbk","\\Bbb{k}");fe("\xB7","\\cdotp");fe("\\llap","\\mathllap{\\textrm{#1}}");fe("\\rlap","\\mathrlap{\\textrm{#1}}");fe("\\clap","\\mathclap{\\textrm{#1}}");fe("\\mathstrut","\\vphantom{(}");fe("\\underbar","\\underline{\\text{#1}}");fe("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');fe("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}");fe("\\ne","\\neq");fe("\u2260","\\neq");fe("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}");fe("\u2209","\\notin");fe("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}");fe("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}");fe("\u225A","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}");fe("\u225B","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225B}}");fe("\u225D","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225D}}");fe("\u225E","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225E}}");fe("\u225F","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}");fe("\u27C2","\\perp");fe("\u203C","\\mathclose{!\\mkern-0.8mu!}");fe("\u220C","\\notni");fe("\u231C","\\ulcorner");fe("\u231D","\\urcorner");fe("\u231E","\\llcorner");fe("\u231F","\\lrcorner");fe("\xA9","\\copyright");fe("\xAE","\\textregistered");fe("\uFE0F","\\textregistered");fe("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}');fe("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}');fe("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}');fe("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}');fe("\\vdots","\\mathord{\\varvdots\\rule{0pt}{15pt}}");fe("\u22EE","\\vdots");fe("\\varGamma","\\mathit{\\Gamma}");fe("\\varDelta","\\mathit{\\Delta}");fe("\\varTheta","\\mathit{\\Theta}");fe("\\varLambda","\\mathit{\\Lambda}");fe("\\varXi","\\mathit{\\Xi}");fe("\\varPi","\\mathit{\\Pi}");fe("\\varSigma","\\mathit{\\Sigma}");fe("\\varUpsilon","\\mathit{\\Upsilon}");fe("\\varPhi","\\mathit{\\Phi}");fe("\\varPsi","\\mathit{\\Psi}");fe("\\varOmega","\\mathit{\\Omega}");fe("\\substack","\\begin{subarray}{c}#1\\end{subarray}");fe("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");fe("\\boxed","\\fbox{$\\displaystyle{#1}$}");fe("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;");fe("\\implies","\\DOTSB\\;\\Longrightarrow\\;");fe("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");Oz={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};fe("\\dots",function(t){var e="\\dotso",r=t.expandAfterFuture().text;return r in Oz?e=Oz[r]:(r.slice(0,4)==="\\not"||r in An.math&&Jt.contains(["bin","rel"],An.math[r].group))&&(e="\\dotsb"),e});K7={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};fe("\\dotso",function(t){var e=t.future().text;return e in K7?"\\ldots\\,":"\\ldots"});fe("\\dotsc",function(t){var e=t.future().text;return e in K7&&e!==","?"\\ldots\\,":"\\ldots"});fe("\\cdots",function(t){var e=t.future().text;return e in K7?"\\@cdots\\,":"\\@cdots"});fe("\\dotsb","\\cdots");fe("\\dotsm","\\cdots");fe("\\dotsi","\\!\\cdots");fe("\\dotsx","\\ldots\\,");fe("\\DOTSI","\\relax");fe("\\DOTSB","\\relax");fe("\\DOTSX","\\relax");fe("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");fe("\\,","\\tmspace+{3mu}{.1667em}");fe("\\thinspace","\\,");fe("\\>","\\mskip{4mu}");fe("\\:","\\tmspace+{4mu}{.2222em}");fe("\\medspace","\\:");fe("\\;","\\tmspace+{5mu}{.2777em}");fe("\\thickspace","\\;");fe("\\!","\\tmspace-{3mu}{.1667em}");fe("\\negthinspace","\\!");fe("\\negmedspace","\\tmspace-{4mu}{.2222em}");fe("\\negthickspace","\\tmspace-{5mu}{.277em}");fe("\\enspace","\\kern.5em ");fe("\\enskip","\\hskip.5em\\relax");fe("\\quad","\\hskip1em\\relax");fe("\\qquad","\\hskip2em\\relax");fe("\\tag","\\@ifstar\\tag@literal\\tag@paren");fe("\\tag@paren","\\tag@literal{({#1})}");fe("\\tag@literal",t=>{if(t.macros.get("\\df@tag"))throw new gt("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"});fe("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");fe("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");fe("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}");fe("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1");fe("\\newline","\\\\\\relax");fe("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");_G=kt(jl["Main-Regular"][84][1]-.7*jl["Main-Regular"][65][1]);fe("\\LaTeX","\\textrm{\\html@mathml{"+("L\\kern-.36em\\raisebox{"+_G+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{LaTeX}}");fe("\\KaTeX","\\textrm{\\html@mathml{"+("K\\kern-.17em\\raisebox{"+_G+"}{\\scriptstyle A}")+"\\kern-.15em\\TeX}{KaTeX}}");fe("\\hspace","\\@ifstar\\@hspacer\\@hspace");fe("\\@hspace","\\hskip #1\\relax");fe("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax");fe("\\ordinarycolon",":");fe("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}");fe("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}');fe("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}');fe("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}');fe("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}');fe("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}');fe("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}');fe("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}');fe("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}');fe("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}');fe("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}');fe("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}');fe("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}');fe("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}');fe("\u2237","\\dblcolon");fe("\u2239","\\eqcolon");fe("\u2254","\\coloneqq");fe("\u2255","\\eqqcolon");fe("\u2A74","\\Coloneqq");fe("\\ratio","\\vcentcolon");fe("\\coloncolon","\\dblcolon");fe("\\colonequals","\\coloneqq");fe("\\coloncolonequals","\\Coloneqq");fe("\\equalscolon","\\eqqcolon");fe("\\equalscoloncolon","\\Eqqcolon");fe("\\colonminus","\\coloneq");fe("\\coloncolonminus","\\Coloneq");fe("\\minuscolon","\\eqcolon");fe("\\minuscoloncolon","\\Eqcolon");fe("\\coloncolonapprox","\\Colonapprox");fe("\\coloncolonsim","\\Colonsim");fe("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");fe("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");fe("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");fe("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}");fe("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}");fe("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}");fe("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}");fe("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}");fe("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}");fe("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}");fe("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}");fe("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}");fe("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}");fe("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}");fe("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}");fe("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}");fe("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}");fe("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}");fe("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}");fe("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}");fe("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}");fe("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}");fe("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}");fe("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228A}");fe("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2ACB}");fe("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228B}");fe("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2ACC}");fe("\\imath","\\html@mathml{\\@imath}{\u0131}");fe("\\jmath","\\html@mathml{\\@jmath}{\u0237}");fe("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27E6}}");fe("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27E7}}");fe("\u27E6","\\llbracket");fe("\u27E7","\\rrbracket");fe("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}");fe("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}");fe("\u2983","\\lBrace");fe("\u2984","\\rBrace");fe("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29B5}}");fe("\u29B5","\\minuso");fe("\\darr","\\downarrow");fe("\\dArr","\\Downarrow");fe("\\Darr","\\Downarrow");fe("\\lang","\\langle");fe("\\rang","\\rangle");fe("\\uarr","\\uparrow");fe("\\uArr","\\Uparrow");fe("\\Uarr","\\Uparrow");fe("\\N","\\mathbb{N}");fe("\\R","\\mathbb{R}");fe("\\Z","\\mathbb{Z}");fe("\\alef","\\aleph");fe("\\alefsym","\\aleph");fe("\\Alpha","\\mathrm{A}");fe("\\Beta","\\mathrm{B}");fe("\\bull","\\bullet");fe("\\Chi","\\mathrm{X}");fe("\\clubs","\\clubsuit");fe("\\cnums","\\mathbb{C}");fe("\\Complex","\\mathbb{C}");fe("\\Dagger","\\ddagger");fe("\\diamonds","\\diamondsuit");fe("\\empty","\\emptyset");fe("\\Epsilon","\\mathrm{E}");fe("\\Eta","\\mathrm{H}");fe("\\exist","\\exists");fe("\\harr","\\leftrightarrow");fe("\\hArr","\\Leftrightarrow");fe("\\Harr","\\Leftrightarrow");fe("\\hearts","\\heartsuit");fe("\\image","\\Im");fe("\\infin","\\infty");fe("\\Iota","\\mathrm{I}");fe("\\isin","\\in");fe("\\Kappa","\\mathrm{K}");fe("\\larr","\\leftarrow");fe("\\lArr","\\Leftarrow");fe("\\Larr","\\Leftarrow");fe("\\lrarr","\\leftrightarrow");fe("\\lrArr","\\Leftrightarrow");fe("\\Lrarr","\\Leftrightarrow");fe("\\Mu","\\mathrm{M}");fe("\\natnums","\\mathbb{N}");fe("\\Nu","\\mathrm{N}");fe("\\Omicron","\\mathrm{O}");fe("\\plusmn","\\pm");fe("\\rarr","\\rightarrow");fe("\\rArr","\\Rightarrow");fe("\\Rarr","\\Rightarrow");fe("\\real","\\Re");fe("\\reals","\\mathbb{R}");fe("\\Reals","\\mathbb{R}");fe("\\Rho","\\mathrm{P}");fe("\\sdot","\\cdot");fe("\\sect","\\S");fe("\\spades","\\spadesuit");fe("\\sub","\\subset");fe("\\sube","\\subseteq");fe("\\supe","\\supseteq");fe("\\Tau","\\mathrm{T}");fe("\\thetasym","\\vartheta");fe("\\weierp","\\wp");fe("\\Zeta","\\mathrm{Z}");fe("\\argmin","\\DOTSB\\operatorname*{arg\\,min}");fe("\\argmax","\\DOTSB\\operatorname*{arg\\,max}");fe("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits");fe("\\bra","\\mathinner{\\langle{#1}|}");fe("\\ket","\\mathinner{|{#1}\\rangle}");fe("\\braket","\\mathinner{\\langle{#1}\\rangle}");fe("\\Bra","\\left\\langle#1\\right|");fe("\\Ket","\\left|#1\\right\\rangle");DG=o(t=>e=>{var r=e.consumeArg().tokens,n=e.consumeArg().tokens,i=e.consumeArg().tokens,a=e.consumeArg().tokens,s=e.macros.get("|"),l=e.macros.get("\\|");e.macros.beginGroup();var u=o(d=>p=>{t&&(p.macros.set("|",s),i.length&&p.macros.set("\\|",l));var m=d;if(!d&&i.length){var g=p.future();g.text==="|"&&(p.popToken(),m=!0)}return{tokens:m?i:n,numArgs:0}},"midMacro");e.macros.set("|",u(!1)),i.length&&e.macros.set("\\|",u(!0));var h=e.consumeArg().tokens,f=e.expandTokens([...a,...h,...r]);return e.macros.endGroup(),{tokens:f.reverse(),numArgs:0}},"braketHelper");fe("\\bra@ket",DG(!1));fe("\\bra@set",DG(!0));fe("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");fe("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");fe("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");fe("\\angln","{\\angl n}");fe("\\blue","\\textcolor{##6495ed}{#1}");fe("\\orange","\\textcolor{##ffa500}{#1}");fe("\\pink","\\textcolor{##ff00af}{#1}");fe("\\red","\\textcolor{##df0030}{#1}");fe("\\green","\\textcolor{##28ae7b}{#1}");fe("\\gray","\\textcolor{gray}{#1}");fe("\\purple","\\textcolor{##9d38bd}{#1}");fe("\\blueA","\\textcolor{##ccfaff}{#1}");fe("\\blueB","\\textcolor{##80f6ff}{#1}");fe("\\blueC","\\textcolor{##63d9ea}{#1}");fe("\\blueD","\\textcolor{##11accd}{#1}");fe("\\blueE","\\textcolor{##0c7f99}{#1}");fe("\\tealA","\\textcolor{##94fff5}{#1}");fe("\\tealB","\\textcolor{##26edd5}{#1}");fe("\\tealC","\\textcolor{##01d1c1}{#1}");fe("\\tealD","\\textcolor{##01a995}{#1}");fe("\\tealE","\\textcolor{##208170}{#1}");fe("\\greenA","\\textcolor{##b6ffb0}{#1}");fe("\\greenB","\\textcolor{##8af281}{#1}");fe("\\greenC","\\textcolor{##74cf70}{#1}");fe("\\greenD","\\textcolor{##1fab54}{#1}");fe("\\greenE","\\textcolor{##0d923f}{#1}");fe("\\goldA","\\textcolor{##ffd0a9}{#1}");fe("\\goldB","\\textcolor{##ffbb71}{#1}");fe("\\goldC","\\textcolor{##ff9c39}{#1}");fe("\\goldD","\\textcolor{##e07d10}{#1}");fe("\\goldE","\\textcolor{##a75a05}{#1}");fe("\\redA","\\textcolor{##fca9a9}{#1}");fe("\\redB","\\textcolor{##ff8482}{#1}");fe("\\redC","\\textcolor{##f9685d}{#1}");fe("\\redD","\\textcolor{##e84d39}{#1}");fe("\\redE","\\textcolor{##bc2612}{#1}");fe("\\maroonA","\\textcolor{##ffbde0}{#1}");fe("\\maroonB","\\textcolor{##ff92c6}{#1}");fe("\\maroonC","\\textcolor{##ed5fa6}{#1}");fe("\\maroonD","\\textcolor{##ca337c}{#1}");fe("\\maroonE","\\textcolor{##9e034e}{#1}");fe("\\purpleA","\\textcolor{##ddd7ff}{#1}");fe("\\purpleB","\\textcolor{##c6b9fc}{#1}");fe("\\purpleC","\\textcolor{##aa87ff}{#1}");fe("\\purpleD","\\textcolor{##7854ab}{#1}");fe("\\purpleE","\\textcolor{##543b78}{#1}");fe("\\mintA","\\textcolor{##f5f9e8}{#1}");fe("\\mintB","\\textcolor{##edf2df}{#1}");fe("\\mintC","\\textcolor{##e0e5cc}{#1}");fe("\\grayA","\\textcolor{##f6f7f7}{#1}");fe("\\grayB","\\textcolor{##f0f1f2}{#1}");fe("\\grayC","\\textcolor{##e3e5e6}{#1}");fe("\\grayD","\\textcolor{##d6d8da}{#1}");fe("\\grayE","\\textcolor{##babec2}{#1}");fe("\\grayF","\\textcolor{##888d93}{#1}");fe("\\grayG","\\textcolor{##626569}{#1}");fe("\\grayH","\\textcolor{##3b3e40}{#1}");fe("\\grayI","\\textcolor{##21242c}{#1}");fe("\\kaBlue","\\textcolor{##314453}{#1}");fe("\\kaGreen","\\textcolor{##71B307}{#1}");LG={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},I7=class{static{o(this,"MacroExpander")}constructor(e,r,n){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=r,this.expansionCount=0,this.feed(e),this.macros=new M7(V4e,r.macros),this.mode=n,this.stack=[]}feed(e){this.lexer=new y3(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return this.stack.length===0&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var r,n,i;if(e){if(this.consumeSpaces(),this.future().text!=="[")return null;r=this.popToken(),{tokens:i,end:n}=this.consumeArg(["]"])}else({tokens:i,start:r,end:n}=this.consumeArg());return this.pushToken(new So("EOF",n.loc)),this.pushTokens(i),r.range(n,"")}consumeSpaces(){for(;;){var e=this.future();if(e.text===" ")this.stack.pop();else break}}consumeArg(e){var r=[],n=e&&e.length>0;n||this.consumeSpaces();var i=this.future(),a,s=0,l=0;do{if(a=this.popToken(),r.push(a),a.text==="{")++s;else if(a.text==="}"){if(--s,s===-1)throw new gt("Extra }",a)}else if(a.text==="EOF")throw new gt("Unexpected end of input in a macro argument, expected '"+(e&&n?e[l]:"}")+"'",a);if(e&&n)if((s===0||s===1&&e[l]==="{")&&a.text===e[l]){if(++l,l===e.length){r.splice(-l,l);break}}else l=0}while(s!==0||n);return i.text==="{"&&r[r.length-1].text==="}"&&(r.pop(),r.shift()),r.reverse(),{tokens:r,start:i,end:a}}consumeArgs(e,r){if(r){if(r.length!==e+1)throw new gt("The length of delimiters doesn't match the number of args!");for(var n=r[0],i=0;i<n.length;i++){var a=this.popToken();if(n[i]!==a.text)throw new gt("Use of the macro doesn't match its definition",a)}}for(var s=[],l=0;l<e;l++)s.push(this.consumeArg(r&&r[l+1]).tokens);return s}countExpansion(e){if(this.expansionCount+=e,this.expansionCount>this.settings.maxExpand)throw new gt("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var r=this.popToken(),n=r.text,i=r.noexpand?null:this._getExpansion(n);if(i==null||e&&i.unexpandable){if(e&&i==null&&n[0]==="\\"&&!this.isDefined(n))throw new gt("Undefined control sequence: "+n);return this.pushToken(r),!1}this.countExpansion(1);var a=i.tokens,s=this.consumeArgs(i.numArgs,i.delimiters);if(i.numArgs){a=a.slice();for(var l=a.length-1;l>=0;--l){var u=a[l];if(u.text==="#"){if(l===0)throw new gt("Incomplete placeholder at end of macro body",u);if(u=a[--l],u.text==="#")a.splice(l+1,1);else if(/^[1-9]$/.test(u.text))a.splice(l,2,...s[+u.text-1]);else throw new gt("Not a valid argument number",u)}}}return this.pushTokens(a),a.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(this.expandOnce()===!1){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new So(e)]):void 0}expandTokens(e){var r=[],n=this.stack.length;for(this.pushTokens(e);this.stack.length>n;)if(this.expandOnce(!0)===!1){var i=this.stack.pop();i.treatAsRelax&&(i.noexpand=!1,i.treatAsRelax=!1),r.push(i)}return this.countExpansion(r.length),r}expandMacroAsText(e){var r=this.expandMacro(e);return r&&r.map(n=>n.text).join("")}_getExpansion(e){var r=this.macros.get(e);if(r==null)return r;if(e.length===1){var n=this.lexer.catcodes[e];if(n!=null&&n!==13)return}var i=typeof r=="function"?r(this):r;if(typeof i=="string"){var a=0;if(i.indexOf("#")!==-1)for(var s=i.replace(/##/g,"");s.indexOf("#"+(a+1))!==-1;)++a;for(var l=new y3(i,this.settings),u=[],h=l.lex();h.text!=="EOF";)u.push(h),h=l.lex();u.reverse();var f={tokens:u,numArgs:a};return f}return i}isDefined(e){return this.macros.has(e)||hh.hasOwnProperty(e)||An.math.hasOwnProperty(e)||An.text.hasOwnProperty(e)||LG.hasOwnProperty(e)}isExpandable(e){var r=this.macros.get(e);return r!=null?typeof r=="string"||typeof r=="function"||!r.unexpandable:hh.hasOwnProperty(e)&&!hh[e].primitive}},Pz=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,l3=Object.freeze({"\u208A":"+","\u208B":"-","\u208C":"=","\u208D":"(","\u208E":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1D62":"i","\u2C7C":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209A":"p","\u1D63":"r","\u209B":"s","\u209C":"t","\u1D64":"u","\u1D65":"v","\u2093":"x","\u1D66":"\u03B2","\u1D67":"\u03B3","\u1D68":"\u03C1","\u1D69":"\u03D5","\u1D6A":"\u03C7","\u207A":"+","\u207B":"-","\u207C":"=","\u207D":"(","\u207E":")","\u2070":"0","\xB9":"1","\xB2":"2","\xB3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1D2C":"A","\u1D2E":"B","\u1D30":"D","\u1D31":"E","\u1D33":"G","\u1D34":"H","\u1D35":"I","\u1D36":"J","\u1D37":"K","\u1D38":"L","\u1D39":"M","\u1D3A":"N","\u1D3C":"O","\u1D3E":"P","\u1D3F":"R","\u1D40":"T","\u1D41":"U","\u2C7D":"V","\u1D42":"W","\u1D43":"a","\u1D47":"b","\u1D9C":"c","\u1D48":"d","\u1D49":"e","\u1DA0":"f","\u1D4D":"g",\u02B0:"h","\u2071":"i",\u02B2:"j","\u1D4F":"k",\u02E1:"l","\u1D50":"m",\u207F:"n","\u1D52":"o","\u1D56":"p",\u02B3:"r",\u02E2:"s","\u1D57":"t","\u1D58":"u","\u1D5B":"v",\u02B7:"w",\u02E3:"x",\u02B8:"y","\u1DBB":"z","\u1D5D":"\u03B2","\u1D5E":"\u03B3","\u1D5F":"\u03B4","\u1D60":"\u03D5","\u1D61":"\u03C7","\u1DBF":"\u03B8"}),T7={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030C":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030A":{text:"\\r",math:"\\mathring"},"\u030B":{text:"\\H"},"\u0327":{text:"\\c"}},Bz={\u00E1:"a\u0301",\u00E0:"a\u0300",\u00E4:"a\u0308",\u01DF:"a\u0308\u0304",\u00E3:"a\u0303",\u0101:"a\u0304",\u0103:"a\u0306",\u1EAF:"a\u0306\u0301",\u1EB1:"a\u0306\u0300",\u1EB5:"a\u0306\u0303",\u01CE:"a\u030C",\u00E2:"a\u0302",\u1EA5:"a\u0302\u0301",\u1EA7:"a\u0302\u0300",\u1EAB:"a\u0302\u0303",\u0227:"a\u0307",\u01E1:"a\u0307\u0304",\u00E5:"a\u030A",\u01FB:"a\u030A\u0301",\u1E03:"b\u0307",\u0107:"c\u0301",\u1E09:"c\u0327\u0301",\u010D:"c\u030C",\u0109:"c\u0302",\u010B:"c\u0307",\u00E7:"c\u0327",\u010F:"d\u030C",\u1E0B:"d\u0307",\u1E11:"d\u0327",\u00E9:"e\u0301",\u00E8:"e\u0300",\u00EB:"e\u0308",\u1EBD:"e\u0303",\u0113:"e\u0304",\u1E17:"e\u0304\u0301",\u1E15:"e\u0304\u0300",\u0115:"e\u0306",\u1E1D:"e\u0327\u0306",\u011B:"e\u030C",\u00EA:"e\u0302",\u1EBF:"e\u0302\u0301",\u1EC1:"e\u0302\u0300",\u1EC5:"e\u0302\u0303",\u0117:"e\u0307",\u0229:"e\u0327",\u1E1F:"f\u0307",\u01F5:"g\u0301",\u1E21:"g\u0304",\u011F:"g\u0306",\u01E7:"g\u030C",\u011D:"g\u0302",\u0121:"g\u0307",\u0123:"g\u0327",\u1E27:"h\u0308",\u021F:"h\u030C",\u0125:"h\u0302",\u1E23:"h\u0307",\u1E29:"h\u0327",\u00ED:"i\u0301",\u00EC:"i\u0300",\u00EF:"i\u0308",\u1E2F:"i\u0308\u0301",\u0129:"i\u0303",\u012B:"i\u0304",\u012D:"i\u0306",\u01D0:"i\u030C",\u00EE:"i\u0302",\u01F0:"j\u030C",\u0135:"j\u0302",\u1E31:"k\u0301",\u01E9:"k\u030C",\u0137:"k\u0327",\u013A:"l\u0301",\u013E:"l\u030C",\u013C:"l\u0327",\u1E3F:"m\u0301",\u1E41:"m\u0307",\u0144:"n\u0301",\u01F9:"n\u0300",\u00F1:"n\u0303",\u0148:"n\u030C",\u1E45:"n\u0307",\u0146:"n\u0327",\u00F3:"o\u0301",\u00F2:"o\u0300",\u00F6:"o\u0308",\u022B:"o\u0308\u0304",\u00F5:"o\u0303",\u1E4D:"o\u0303\u0301",\u1E4F:"o\u0303\u0308",\u022D:"o\u0303\u0304",\u014D:"o\u0304",\u1E53:"o\u0304\u0301",\u1E51:"o\u0304\u0300",\u014F:"o\u0306",\u01D2:"o\u030C",\u00F4:"o\u0302",\u1ED1:"o\u0302\u0301",\u1ED3:"o\u0302\u0300",\u1ED7:"o\u0302\u0303",\u022F:"o\u0307",\u0231:"o\u0307\u0304",\u0151:"o\u030B",\u1E55:"p\u0301",\u1E57:"p\u0307",\u0155:"r\u0301",\u0159:"r\u030C",\u1E59:"r\u0307",\u0157:"r\u0327",\u015B:"s\u0301",\u1E65:"s\u0301\u0307",\u0161:"s\u030C",\u1E67:"s\u030C\u0307",\u015D:"s\u0302",\u1E61:"s\u0307",\u015F:"s\u0327",\u1E97:"t\u0308",\u0165:"t\u030C",\u1E6B:"t\u0307",\u0163:"t\u0327",\u00FA:"u\u0301",\u00F9:"u\u0300",\u00FC:"u\u0308",\u01D8:"u\u0308\u0301",\u01DC:"u\u0308\u0300",\u01D6:"u\u0308\u0304",\u01DA:"u\u0308\u030C",\u0169:"u\u0303",\u1E79:"u\u0303\u0301",\u016B:"u\u0304",\u1E7B:"u\u0304\u0308",\u016D:"u\u0306",\u01D4:"u\u030C",\u00FB:"u\u0302",\u016F:"u\u030A",\u0171:"u\u030B",\u1E7D:"v\u0303",\u1E83:"w\u0301",\u1E81:"w\u0300",\u1E85:"w\u0308",\u0175:"w\u0302",\u1E87:"w\u0307",\u1E98:"w\u030A",\u1E8D:"x\u0308",\u1E8B:"x\u0307",\u00FD:"y\u0301",\u1EF3:"y\u0300",\u00FF:"y\u0308",\u1EF9:"y\u0303",\u0233:"y\u0304",\u0177:"y\u0302",\u1E8F:"y\u0307",\u1E99:"y\u030A",\u017A:"z\u0301",\u017E:"z\u030C",\u1E91:"z\u0302",\u017C:"z\u0307",\u00C1:"A\u0301",\u00C0:"A\u0300",\u00C4:"A\u0308",\u01DE:"A\u0308\u0304",\u00C3:"A\u0303",\u0100:"A\u0304",\u0102:"A\u0306",\u1EAE:"A\u0306\u0301",\u1EB0:"A\u0306\u0300",\u1EB4:"A\u0306\u0303",\u01CD:"A\u030C",\u00C2:"A\u0302",\u1EA4:"A\u0302\u0301",\u1EA6:"A\u0302\u0300",\u1EAA:"A\u0302\u0303",\u0226:"A\u0307",\u01E0:"A\u0307\u0304",\u00C5:"A\u030A",\u01FA:"A\u030A\u0301",\u1E02:"B\u0307",\u0106:"C\u0301",\u1E08:"C\u0327\u0301",\u010C:"C\u030C",\u0108:"C\u0302",\u010A:"C\u0307",\u00C7:"C\u0327",\u010E:"D\u030C",\u1E0A:"D\u0307",\u1E10:"D\u0327",\u00C9:"E\u0301",\u00C8:"E\u0300",\u00CB:"E\u0308",\u1EBC:"E\u0303",\u0112:"E\u0304",\u1E16:"E\u0304\u0301",\u1E14:"E\u0304\u0300",\u0114:"E\u0306",\u1E1C:"E\u0327\u0306",\u011A:"E\u030C",\u00CA:"E\u0302",\u1EBE:"E\u0302\u0301",\u1EC0:"E\u0302\u0300",\u1EC4:"E\u0302\u0303",\u0116:"E\u0307",\u0228:"E\u0327",\u1E1E:"F\u0307",\u01F4:"G\u0301",\u1E20:"G\u0304",\u011E:"G\u0306",\u01E6:"G\u030C",\u011C:"G\u0302",\u0120:"G\u0307",\u0122:"G\u0327",\u1E26:"H\u0308",\u021E:"H\u030C",\u0124:"H\u0302",\u1E22:"H\u0307",\u1E28:"H\u0327",\u00CD:"I\u0301",\u00CC:"I\u0300",\u00CF:"I\u0308",\u1E2E:"I\u0308\u0301",\u0128:"I\u0303",\u012A:"I\u0304",\u012C:"I\u0306",\u01CF:"I\u030C",\u00CE:"I\u0302",\u0130:"I\u0307",\u0134:"J\u0302",\u1E30:"K\u0301",\u01E8:"K\u030C",\u0136:"K\u0327",\u0139:"L\u0301",\u013D:"L\u030C",\u013B:"L\u0327",\u1E3E:"M\u0301",\u1E40:"M\u0307",\u0143:"N\u0301",\u01F8:"N\u0300",\u00D1:"N\u0303",\u0147:"N\u030C",\u1E44:"N\u0307",\u0145:"N\u0327",\u00D3:"O\u0301",\u00D2:"O\u0300",\u00D6:"O\u0308",\u022A:"O\u0308\u0304",\u00D5:"O\u0303",\u1E4C:"O\u0303\u0301",\u1E4E:"O\u0303\u0308",\u022C:"O\u0303\u0304",\u014C:"O\u0304",\u1E52:"O\u0304\u0301",\u1E50:"O\u0304\u0300",\u014E:"O\u0306",\u01D1:"O\u030C",\u00D4:"O\u0302",\u1ED0:"O\u0302\u0301",\u1ED2:"O\u0302\u0300",\u1ED6:"O\u0302\u0303",\u022E:"O\u0307",\u0230:"O\u0307\u0304",\u0150:"O\u030B",\u1E54:"P\u0301",\u1E56:"P\u0307",\u0154:"R\u0301",\u0158:"R\u030C",\u1E58:"R\u0307",\u0156:"R\u0327",\u015A:"S\u0301",\u1E64:"S\u0301\u0307",\u0160:"S\u030C",\u1E66:"S\u030C\u0307",\u015C:"S\u0302",\u1E60:"S\u0307",\u015E:"S\u0327",\u0164:"T\u030C",\u1E6A:"T\u0307",\u0162:"T\u0327",\u00DA:"U\u0301",\u00D9:"U\u0300",\u00DC:"U\u0308",\u01D7:"U\u0308\u0301",\u01DB:"U\u0308\u0300",\u01D5:"U\u0308\u0304",\u01D9:"U\u0308\u030C",\u0168:"U\u0303",\u1E78:"U\u0303\u0301",\u016A:"U\u0304",\u1E7A:"U\u0304\u0308",\u016C:"U\u0306",\u01D3:"U\u030C",\u00DB:"U\u0302",\u016E:"U\u030A",\u0170:"U\u030B",\u1E7C:"V\u0303",\u1E82:"W\u0301",\u1E80:"W\u0300",\u1E84:"W\u0308",\u0174:"W\u0302",\u1E86:"W\u0307",\u1E8C:"X\u0308",\u1E8A:"X\u0307",\u00DD:"Y\u0301",\u1EF2:"Y\u0300",\u0178:"Y\u0308",\u1EF8:"Y\u0303",\u0232:"Y\u0304",\u0176:"Y\u0302",\u1E8E:"Y\u0307",\u0179:"Z\u0301",\u017D:"Z\u030C",\u1E90:"Z\u0302",\u017B:"Z\u0307",\u03AC:"\u03B1\u0301",\u1F70:"\u03B1\u0300",\u1FB1:"\u03B1\u0304",\u1FB0:"\u03B1\u0306",\u03AD:"\u03B5\u0301",\u1F72:"\u03B5\u0300",\u03AE:"\u03B7\u0301",\u1F74:"\u03B7\u0300",\u03AF:"\u03B9\u0301",\u1F76:"\u03B9\u0300",\u03CA:"\u03B9\u0308",\u0390:"\u03B9\u0308\u0301",\u1FD2:"\u03B9\u0308\u0300",\u1FD1:"\u03B9\u0304",\u1FD0:"\u03B9\u0306",\u03CC:"\u03BF\u0301",\u1F78:"\u03BF\u0300",\u03CD:"\u03C5\u0301",\u1F7A:"\u03C5\u0300",\u03CB:"\u03C5\u0308",\u03B0:"\u03C5\u0308\u0301",\u1FE2:"\u03C5\u0308\u0300",\u1FE1:"\u03C5\u0304",\u1FE0:"\u03C5\u0306",\u03CE:"\u03C9\u0301",\u1F7C:"\u03C9\u0300",\u038E:"\u03A5\u0301",\u1FEA:"\u03A5\u0300",\u03AB:"\u03A5\u0308",\u1FE9:"\u03A5\u0304",\u1FE8:"\u03A5\u0306",\u038F:"\u03A9\u0301",\u1FFA:"\u03A9\u0300"},v3=class t{static{o(this,"Parser")}constructor(e,r){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new I7(e,r,this.mode),this.settings=r,this.leftrightDepth=0}expect(e,r){if(r===void 0&&(r=!0),this.fetch().text!==e)throw new gt("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());r&&this.consume()}consume(){this.nextToken=null}fetch(){return this.nextToken==null&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var r=this.nextToken;this.consume(),this.gullet.pushToken(new So("}")),this.gullet.pushTokens(e);var n=this.parseExpression(!1);return this.expect("}"),this.nextToken=r,n}parseExpression(e,r){for(var n=[];;){this.mode==="math"&&this.consumeSpaces();var i=this.fetch();if(t.endOfExpression.indexOf(i.text)!==-1||r&&i.text===r||e&&hh[i.text]&&hh[i.text].infix)break;var a=this.parseAtom(r);if(a){if(a.type==="internal")continue}else break;n.push(a)}return this.mode==="text"&&this.formLigatures(n),this.handleInfixNodes(n)}handleInfixNodes(e){for(var r=-1,n,i=0;i<e.length;i++)if(e[i].type==="infix"){if(r!==-1)throw new gt("only one infix operator per group",e[i].token);r=i,n=e[i].replaceWith}if(r!==-1&&n){var a,s,l=e.slice(0,r),u=e.slice(r+1);l.length===1&&l[0].type==="ordgroup"?a=l[0]:a={type:"ordgroup",mode:this.mode,body:l},u.length===1&&u[0].type==="ordgroup"?s=u[0]:s={type:"ordgroup",mode:this.mode,body:u};var h;return n==="\\\\abovefrac"?h=this.callFunction(n,[a,e[r],s],[]):h=this.callFunction(n,[a,s],[]),[h]}else return e}handleSupSubscript(e){var r=this.fetch(),n=r.text;this.consume(),this.consumeSpaces();var i=this.parseGroup(e);if(!i)throw new gt("Expected group after '"+n+"'",r);return i}formatUnsupportedCmd(e){for(var r=[],n=0;n<e.length;n++)r.push({type:"textord",mode:"text",text:e[n]});var i={type:"text",mode:this.mode,body:r},a={type:"color",mode:this.mode,color:this.settings.errorColor,body:[i]};return a}parseAtom(e){var r=this.parseGroup("atom",e);if(this.mode==="text")return r;for(var n,i;;){this.consumeSpaces();var a=this.fetch();if(a.text==="\\limits"||a.text==="\\nolimits"){if(r&&r.type==="op"){var s=a.text==="\\limits";r.limits=s,r.alwaysHandleSupSub=!0}else if(r&&r.type==="operatorname")r.alwaysHandleSupSub&&(r.limits=a.text==="\\limits");else throw new gt("Limit controls must follow a math operator",a);this.consume()}else if(a.text==="^"){if(n)throw new gt("Double superscript",a);n=this.handleSupSubscript("superscript")}else if(a.text==="_"){if(i)throw new gt("Double subscript",a);i=this.handleSupSubscript("subscript")}else if(a.text==="'"){if(n)throw new gt("Double superscript",a);var l={type:"textord",mode:this.mode,text:"\\prime"},u=[l];for(this.consume();this.fetch().text==="'";)u.push(l),this.consume();this.fetch().text==="^"&&u.push(this.handleSupSubscript("superscript")),n={type:"ordgroup",mode:this.mode,body:u}}else if(l3[a.text]){var h=Pz.test(a.text),f=[];for(f.push(new So(l3[a.text])),this.consume();;){var d=this.fetch().text;if(!l3[d]||Pz.test(d)!==h)break;f.unshift(new So(l3[d])),this.consume()}var p=this.subparse(f);h?i={type:"ordgroup",mode:"math",body:p}:n={type:"ordgroup",mode:"math",body:p}}else break}return n||i?{type:"supsub",mode:this.mode,base:r,sup:n,sub:i}:r}parseFunction(e,r){var n=this.fetch(),i=n.text,a=hh[i];if(!a)return null;if(this.consume(),r&&r!=="atom"&&!a.allowedInArgument)throw new gt("Got function '"+i+"' with no arguments"+(r?" as "+r:""),n);if(this.mode==="text"&&!a.allowedInText)throw new gt("Can't use function '"+i+"' in text mode",n);if(this.mode==="math"&&a.allowedInMath===!1)throw new gt("Can't use function '"+i+"' in math mode",n);var{args:s,optArgs:l}=this.parseArguments(i,a);return this.callFunction(i,s,l,n,e)}callFunction(e,r,n,i,a){var s={funcName:e,parser:this,token:i,breakOnTokenText:a},l=hh[e];if(l&&l.handler)return l.handler(s,r,n);throw new gt("No function handler for "+e)}parseArguments(e,r){var n=r.numArgs+r.numOptionalArgs;if(n===0)return{args:[],optArgs:[]};for(var i=[],a=[],s=0;s<n;s++){var l=r.argTypes&&r.argTypes[s],u=s<r.numOptionalArgs;(r.primitive&&l==null||r.type==="sqrt"&&s===1&&a[0]==null)&&(l="primitive");var h=this.parseGroupOfType("argument to '"+e+"'",l,u);if(u)a.push(h);else if(h!=null)i.push(h);else throw new gt("Null argument, please report this as a bug")}return{args:i,optArgs:a}}parseGroupOfType(e,r,n){switch(r){case"color":return this.parseColorGroup(n);case"size":return this.parseSizeGroup(n);case"url":return this.parseUrlGroup(n);case"math":case"text":return this.parseArgumentGroup(n,r);case"hbox":{var i=this.parseArgumentGroup(n,"text");return i!=null?{type:"styling",mode:i.mode,body:[i],style:"text"}:null}case"raw":{var a=this.parseStringGroup("raw",n);return a!=null?{type:"raw",mode:"text",string:a.text}:null}case"primitive":{if(n)throw new gt("A primitive argument cannot be optional");var s=this.parseGroup(e);if(s==null)throw new gt("Expected group as "+e,this.fetch());return s}case"original":case null:case void 0:return this.parseArgumentGroup(n);default:throw new gt("Unknown group type as "+e,this.fetch())}}consumeSpaces(){for(;this.fetch().text===" ";)this.consume()}parseStringGroup(e,r){var n=this.gullet.scanArgument(r);if(n==null)return null;for(var i="",a;(a=this.fetch()).text!=="EOF";)i+=a.text,this.consume();return this.consume(),n.text=i,n}parseRegexGroup(e,r){for(var n=this.fetch(),i=n,a="",s;(s=this.fetch()).text!=="EOF"&&e.test(a+s.text);)i=s,a+=i.text,this.consume();if(a==="")throw new gt("Invalid "+r+": '"+n.text+"'",n);return n.range(i,a)}parseColorGroup(e){var r=this.parseStringGroup("color",e);if(r==null)return null;var n=/^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(r.text);if(!n)throw new gt("Invalid color: '"+r.text+"'",r);var i=n[0];return/^[0-9a-f]{6}$/i.test(i)&&(i="#"+i),{type:"color-token",mode:this.mode,color:i}}parseSizeGroup(e){var r,n=!1;if(this.gullet.consumeSpaces(),!e&&this.gullet.future().text!=="{"?r=this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/,"size"):r=this.parseStringGroup("size",e),!r)return null;!e&&r.text.length===0&&(r.text="0pt",n=!0);var i=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(r.text);if(!i)throw new gt("Invalid size: '"+r.text+"'",r);var a={number:+(i[1]+i[2]),unit:i[3]};if(!zz(a))throw new gt("Invalid unit: '"+a.unit+"'",r);return{type:"size",mode:this.mode,value:a,isBlank:n}}parseUrlGroup(e){this.gullet.lexer.setCatcode("%",13),this.gullet.lexer.setCatcode("~",12);var r=this.parseStringGroup("url",e);if(this.gullet.lexer.setCatcode("%",14),this.gullet.lexer.setCatcode("~",13),r==null)return null;var n=r.text.replace(/\\([#$%&~_^{}])/g,"$1");return{type:"url",mode:this.mode,url:n}}parseArgumentGroup(e,r){var n=this.gullet.scanArgument(e);if(n==null)return null;var i=this.mode;r&&this.switchMode(r),this.gullet.beginGroup();var a=this.parseExpression(!1,"EOF");this.expect("EOF"),this.gullet.endGroup();var s={type:"ordgroup",mode:this.mode,loc:n.loc,body:a};return r&&this.switchMode(i),s}parseGroup(e,r){var n=this.fetch(),i=n.text,a;if(i==="{"||i==="\\begingroup"){this.consume();var s=i==="{"?"}":"\\endgroup";this.gullet.beginGroup();var l=this.parseExpression(!1,s),u=this.fetch();this.expect(s),this.gullet.endGroup(),a={type:"ordgroup",mode:this.mode,loc:Xs.range(n,u),body:l,semisimple:i==="\\begingroup"||void 0}}else if(a=this.parseFunction(r,e)||this.parseSymbol(),a==null&&i[0]==="\\"&&!LG.hasOwnProperty(i)){if(this.settings.throwOnError)throw new gt("Undefined control sequence: "+i,n);a=this.formatUnsupportedCmd(i),this.consume()}return a}formLigatures(e){for(var r=e.length-1,n=0;n<r;++n){var i=e[n],a=i.text;a==="-"&&e[n+1].text==="-"&&(n+1<r&&e[n+2].text==="-"?(e.splice(n,3,{type:"textord",mode:"text",loc:Xs.range(i,e[n+2]),text:"---"}),r-=2):(e.splice(n,2,{type:"textord",mode:"text",loc:Xs.range(i,e[n+1]),text:"--"}),r-=1)),(a==="'"||a==="`")&&e[n+1].text===a&&(e.splice(n,2,{type:"textord",mode:"text",loc:Xs.range(i,e[n+1]),text:a+a}),r-=1)}}parseSymbol(){var e=this.fetch(),r=e.text;if(/^\\verb[^a-zA-Z]/.test(r)){this.consume();var n=r.slice(5),i=n.charAt(0)==="*";if(i&&(n=n.slice(1)),n.length<2||n.charAt(0)!==n.slice(-1))throw new gt(`\\verb assertion failed --
+ please report what input caused this bug`);return n=n.slice(1,-1),{type:"verb",mode:"text",body:n,star:i}}Bz.hasOwnProperty(r[0])&&!An[this.mode][r[0]]&&(this.settings.strict&&this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Accented Unicode text character "'+r[0]+'" used in math mode',e),r=Bz[r[0]]+r.slice(1));var a=z4e.exec(r);a&&(r=r.substring(0,a.index),r==="i"?r="\u0131":r==="j"&&(r="\u0237"));var s;if(An[this.mode][r]){this.settings.strict&&this.mode==="math"&&C7.indexOf(r)>=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+r[0]+'" used in math mode',e);var l=An[this.mode][r].group,u=Xs.range(e),h;if(Mbe.hasOwnProperty(l)){var f=l;h={type:"atom",mode:this.mode,family:f,loc:u,text:r}}else h={type:l,mode:this.mode,loc:u,text:r};s=h}else if(r.charCodeAt(0)>=128)this.settings.strict&&($z(r.charCodeAt(0))?this.mode==="math"&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+r[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+r[0]+'"'+(" ("+r.charCodeAt(0)+")"),e)),s={type:"textord",mode:"text",loc:Xs.range(e),text:r};else return null;if(this.consume(),a)for(var d=0;d<a[0].length;d++){var p=a[0][d];if(!T7[p])throw new gt("Unknown accent ' "+p+"'",e);var m=T7[p][this.mode]||T7[p].text;if(!m)throw new gt("Accent "+p+" unsupported in "+this.mode+" mode",e);s={type:"accent",mode:this.mode,loc:Xs.range(e),label:m,isStretchy:!1,isShifty:!0,base:s}}return s}};v3.endOfExpression=["}","\\endgroup","\\end","\\right","&"];Q7=o(function(e,r){if(!(typeof e=="string"||e instanceof String))throw new TypeError("KaTeX can only parse string typed expression");var n=new v3(e,r);delete n.gullet.macros.current["\\df@tag"];var i=n.parse();if(delete n.gullet.macros.current["\\current@color"],delete n.gullet.macros.current["\\color"],n.gullet.macros.get("\\df@tag")){if(!r.displayMode)throw new gt("\\tag works only in display equations");i=[{type:"tag",mode:"text",body:i,tag:n.subparse([new So("\\df@tag")])}]}return i},"parseTree"),RG=o(function(e,r,n){r.textContent="";var i=Z7(e,n).toNode();r.appendChild(i)},"render");typeof document<"u"&&document.compatMode!=="CSS1Compat"&&(typeof console<"u"&&console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your website has a suitable doctype."),RG=o(function(){throw new gt("KaTeX doesn't work in quirks mode.")},"render"));U4e=o(function(e,r){var n=Z7(e,r).toMarkup();return n},"renderToString"),H4e=o(function(e,r){var n=new zy(r);return Q7(e,n)},"generateParseTree"),NG=o(function(e,r,n){if(n.throwOnError||!(e instanceof gt))throw e;var i=Be.makeSpan(["katex-error"],[new Ts(r)]);return i.setAttribute("title",e.toString()),i.setAttribute("style","color:"+n.errorColor),i},"renderError"),Z7=o(function(e,r){var n=new zy(r);try{var i=Q7(e,n);return t4e(i,e,n)}catch(a){return NG(a,e,n)}},"renderToDomTree"),W4e=o(function(e,r){var n=new zy(r);try{var i=Q7(e,n);return r4e(i,e,n)}catch(a){return NG(a,e,n)}},"renderToHTMLTree"),q4e={version:"0.16.11",render:RG,renderToString:U4e,ParseError:gt,SETTINGS_SCHEMA:c3,__parse:H4e,__renderToDomTree:Z7,__renderToHTMLTree:W4e,__setFontMetrics:Abe,__defineSymbol:G,__defineFunction:Nt,__defineMacro:fe,__domTree:{Span:td,Anchor:Vy,SymbolNode:Ts,SvgNode:ll,PathNode:Kl,LineNode:Uy}}});function j4e(){let t="data-temp-href-target";ch.addHook("beforeSanitizeAttributes",e=>{e instanceof Element&&e.tagName==="A"&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")??"")}),ch.addHook("afterSanitizeAttributes",e=>{e instanceof Element&&e.tagName==="A"&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)??""),e.removeAttribute(t),e.getAttribute("target")==="_blank"&&e.setAttribute("rel","noopener"))})}var nd,Y4e,X4e,BG,OG,Tr,K4e,Q4e,Z4e,J4e,FG,e3e,fr,t3e,r3e,ec,J7,n3e,i3e,PG,eA,pi,id,mh,Ze,gr=N(()=>{"use strict";u7();nd=/<br\s*\/?>/gi,Y4e=o(t=>t?FG(t).replace(/\\n/g,"#br#").split("#br#"):[""],"getRows"),X4e=(()=>{let t=!1;return()=>{t||(j4e(),t=!0)}})();o(j4e,"setupDompurifyHooks");BG=o(t=>(X4e(),ch.sanitize(t)),"removeScript"),OG=o((t,e)=>{if(e.flowchart?.htmlLabels!==!1){let r=e.securityLevel;r==="antiscript"||r==="strict"?t=BG(t):r!=="loose"&&(t=FG(t),t=t.replace(/</g,"&lt;").replace(/>/g,"&gt;"),t=t.replace(/=/g,"&equals;"),t=J4e(t))}return t},"sanitizeMore"),Tr=o((t,e)=>t&&(e.dompurifyConfig?t=ch.sanitize(OG(t,e),e.dompurifyConfig).toString():t=ch.sanitize(OG(t,e),{FORBID_TAGS:["style"]}).toString(),t),"sanitizeText"),K4e=o((t,e)=>typeof t=="string"?Tr(t,e):t.flat().map(r=>Tr(r,e)),"sanitizeTextOrArray"),Q4e=o(t=>nd.test(t),"hasBreaks"),Z4e=o(t=>t.split(nd),"splitBreaks"),J4e=o(t=>t.replace(/#br#/g,"<br/>"),"placeholderToBreak"),FG=o(t=>t.replace(nd,"#br#"),"breakToPlaceholder"),e3e=o(t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},"getUrl"),fr=o(t=>!(t===!1||["false","null","0"].includes(String(t).trim().toLowerCase())),"evaluate"),t3e=o(function(...t){let e=t.filter(r=>!isNaN(r));return Math.max(...e)},"getMax"),r3e=o(function(...t){let e=t.filter(r=>!isNaN(r));return Math.min(...e)},"getMin"),ec=o(function(t){let e=t.split(/(,)/),r=[];for(let n=0;n<e.length;n++){let i=e[n];if(i===","&&n>0&&n+1<e.length){let a=e[n-1],s=e[n+1];n3e(a,s)&&(i=a+","+s,n++,r.pop())}r.push(i3e(i))}return r.join("")},"parseGenericTypes"),J7=o((t,e)=>Math.max(0,t.split(e).length-1),"countOccurrence"),n3e=o((t,e)=>{let r=J7(t,"~"),n=J7(e,"~");return r===1&&n===1},"shouldCombineSets"),i3e=o(t=>{let e=J7(t,"~"),r=!1;if(e<=1)return t;e%2!==0&&t.startsWith("~")&&(t=t.substring(1),r=!0);let n=[...t],i=n.indexOf("~"),a=n.lastIndexOf("~");for(;i!==-1&&a!==-1&&i!==a;)n[i]="<",n[a]=">",i=n.indexOf("~"),a=n.lastIndexOf("~");return r&&n.unshift("~"),n.join("")},"processSet"),PG=o(()=>window.MathMLElement!==void 0,"isMathMLSupported"),eA=/\$\$(.*)\$\$/g,pi=o(t=>(t.match(eA)?.length??0)>0,"hasKatex"),id=o(async(t,e)=>{t=await mh(t,e);let r=document.createElement("div");r.innerHTML=t,r.id="katex-temp",r.style.visibility="hidden",r.style.position="absolute",r.style.top="0",document.querySelector("body")?.insertAdjacentElement("beforeend",r);let i={width:r.clientWidth,height:r.clientHeight};return r.remove(),i},"calculateMathMLDimensions"),mh=o(async(t,e)=>{if(!pi(t))return t;if(!(PG()||e.legacyMathML||e.forceLegacyMathML))return t.replace(eA,"MathML is unsupported in this environment.");let{default:r}=await Promise.resolve().then(()=>(IG(),MG)),n=e.forceLegacyMathML||!PG()&&e.legacyMathML?"htmlAndMathml":"mathml";return t.split(nd).map(i=>pi(i)?`<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">${i}</div>`:`<div>${i}</div>`).join("").replace(eA,(i,a)=>r.renderToString(a,{throwOnError:!0,displayMode:!0,output:n}).replace(/\n/g," ").replace(/<annotation.*<\/annotation>/g,""))},"renderKatex"),Ze={getRows:Y4e,sanitizeText:Tr,sanitizeTextOrArray:K4e,hasBreaks:Q4e,splitBreaks:Z4e,lineBreakRegex:nd,removeScript:BG,getUrl:e3e,evaluate:fr,getMax:t3e,getMin:r3e}});var a3e,s3e,vn,Ao,Ei=N(()=>{"use strict";vt();a3e=o(function(t,e){for(let r of e)t.attr(r[0],r[1])},"d3Attrs"),s3e=o(function(t,e,r){let n=new Map;return r?(n.set("width","100%"),n.set("style",`max-width: ${e}px;`)):(n.set("height",t),n.set("width",e)),n},"calculateSvgSizeAttrs"),vn=o(function(t,e,r,n){let i=s3e(e,r,n);a3e(t,i)},"configureSvgSize"),Ao=o(function(t,e,r,n){let i=e.node().getBBox(),a=i.width,s=i.height;Y.info(`SVG bounds: ${a}x${s}`,i);let l=0,u=0;Y.info(`Graph bounds: ${l}x${u}`,t),l=a+r*2,u=s+r*2,Y.info(`Calculated bounds: ${l}x${u}`),vn(e,u,l,n);let h=`${i.x-r} ${i.y-r} ${i.width+2*r} ${i.height+2*r}`;e.attr("viewBox",h)},"setupGraphViewbox")});var S3,o3e,$G,zG,tA=N(()=>{"use strict";vt();S3={},o3e=o((t,e,r)=>{let n="";return t in S3&&S3[t]?n=S3[t](r):Y.warn(`No theme found for ${t}`),` & {
+ font-family: ${r.fontFamily};
+ font-size: ${r.fontSize};
+ fill: ${r.textColor}
+ }
+ @keyframes edge-animation-frame {
+ from {
+ stroke-dashoffset: 0;
+ }
+ }
+ @keyframes dash {
+ to {
+ stroke-dashoffset: 0;
+ }
+ }
+ & .edge-animation-slow {
+ stroke-dasharray: 9,5 !important;
+ stroke-dashoffset: 900;
+ animation: dash 50s linear infinite;
+ stroke-linecap: round;
+ }
+ & .edge-animation-fast {
+ stroke-dasharray: 9,5 !important;
+ stroke-dashoffset: 900;
+ animation: dash 20s linear infinite;
+ stroke-linecap: round;
+ }
+ /* Classes common for multiple diagrams */
+
+ & .error-icon {
+ fill: ${r.errorBkgColor};
+ }
+ & .error-text {
+ fill: ${r.errorTextColor};
+ stroke: ${r.errorTextColor};
+ }
+
+ & .edge-thickness-normal {
+ stroke-width: 1px;
+ }
+ & .edge-thickness-thick {
+ stroke-width: 3.5px
+ }
+ & .edge-pattern-solid {
+ stroke-dasharray: 0;
+ }
+ & .edge-thickness-invisible {
+ stroke-width: 0;
+ fill: none;
+ }
+ & .edge-pattern-dashed{
+ stroke-dasharray: 3;
+ }
+ .edge-pattern-dotted {
+ stroke-dasharray: 2;
+ }
+
+ & .marker {
+ fill: ${r.lineColor};
+ stroke: ${r.lineColor};
+ }
+ & .marker.cross {
+ stroke: ${r.lineColor};
+ }
+
+ & svg {
+ font-family: ${r.fontFamily};
+ font-size: ${r.fontSize};
+ }
+ & p {
+ margin: 0
+ }
+
+ ${n}
+
+ ${e}
+`},"getStyles"),$G=o((t,e)=>{e!==void 0&&(S3[t]=e)},"addStylesForDiagram"),zG=o3e});var qy={};hr(qy,{clear:()=>Ar,getAccDescription:()=>Mr,getAccTitle:()=>Rr,getDiagramTitle:()=>Ir,setAccDescription:()=>Nr,setAccTitle:()=>Lr,setDiagramTitle:()=>$r});var rA,nA,iA,aA,Ar,Lr,Rr,Nr,Mr,$r,Ir,mi=N(()=>{"use strict";gr();ji();rA="",nA="",iA="",aA=o(t=>Tr(t,cr()),"sanitizeText"),Ar=o(()=>{rA="",iA="",nA=""},"clear"),Lr=o(t=>{rA=aA(t).replace(/^\s+/g,"")},"setAccTitle"),Rr=o(()=>rA,"getAccTitle"),Nr=o(t=>{iA=aA(t).replace(/\n\s+/g,`
+`)},"setAccDescription"),Mr=o(()=>iA,"getAccDescription"),$r=o(t=>{nA=aA(t)},"setDiagramTitle"),Ir=o(()=>nA,"getDiagramTitle")});var GG,l3e,me,Yy,A3,Xy,oA,c3e,C3,ad,jy,sA,zt=N(()=>{"use strict";Xf();vt();ji();gr();Ei();tA();mi();GG=Y,l3e=wy,me=cr,Yy=X4,A3=lh,Xy=o(t=>Tr(t,me()),"sanitizeText"),oA=Ao,c3e=o(()=>qy,"getCommonDb"),C3={},ad=o((t,e,r)=>{C3[t]&&GG.warn(`Diagram with id ${t} already registered. Overwriting.`),C3[t]=e,r&&FC(t,r),$G(t,e.styles),e.injectUtils?.(GG,l3e,me,Xy,oA,c3e(),()=>{})},"registerDiagram"),jy=o(t=>{if(t in C3)return C3[t];throw new sA(t)},"getDiagram"),sA=class extends Error{static{o(this,"DiagramNotFoundError")}constructor(e){super(`Diagram ${e} not found.`)}}});var ul,gh,Ja,cl,tc,Ky,lA,cA,_3,D3,VG,u3e,h3e,f3e,d3e,p3e,m3e,g3e,y3e,v3e,x3e,b3e,w3e,T3e,k3e,E3e,S3e,C3e,UG,A3e,_3e,HG,D3e,L3e,R3e,N3e,yh,M3e,I3e,O3e,P3e,B3e,Qy,uA=N(()=>{"use strict";zt();gr();mi();ul=[],gh=[""],Ja="global",cl="",tc=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],Ky=[],lA="",cA=!1,_3=4,D3=2,u3e=o(function(){return VG},"getC4Type"),h3e=o(function(t){VG=Tr(t,me())},"setC4Type"),f3e=o(function(t,e,r,n,i,a,s,l,u){if(t==null||e===void 0||e===null||r===void 0||r===null||n===void 0||n===null)return;let h={},f=Ky.find(d=>d.from===e&&d.to===r);if(f?h=f:Ky.push(h),h.type=t,h.from=e,h.to=r,h.label={text:n},i==null)h.techn={text:""};else if(typeof i=="object"){let[d,p]=Object.entries(i)[0];h[d]={text:p}}else h.techn={text:i};if(a==null)h.descr={text:""};else if(typeof a=="object"){let[d,p]=Object.entries(a)[0];h[d]={text:p}}else h.descr={text:a};if(typeof s=="object"){let[d,p]=Object.entries(s)[0];h[d]=p}else h.sprite=s;if(typeof l=="object"){let[d,p]=Object.entries(l)[0];h[d]=p}else h.tags=l;if(typeof u=="object"){let[d,p]=Object.entries(u)[0];h[d]=p}else h.link=u;h.wrap=yh()},"addRel"),d3e=o(function(t,e,r,n,i,a,s){if(e===null||r===null)return;let l={},u=ul.find(h=>h.alias===e);if(u&&e===u.alias?l=u:(l.alias=e,ul.push(l)),r==null?l.label={text:""}:l.label={text:r},n==null)l.descr={text:""};else if(typeof n=="object"){let[h,f]=Object.entries(n)[0];l[h]={text:f}}else l.descr={text:n};if(typeof i=="object"){let[h,f]=Object.entries(i)[0];l[h]=f}else l.sprite=i;if(typeof a=="object"){let[h,f]=Object.entries(a)[0];l[h]=f}else l.tags=a;if(typeof s=="object"){let[h,f]=Object.entries(s)[0];l[h]=f}else l.link=s;l.typeC4Shape={text:t},l.parentBoundary=Ja,l.wrap=yh()},"addPersonOrSystem"),p3e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ul.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ul.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.techn={text:""};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.techn={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof a=="object"){let[f,d]=Object.entries(a)[0];u[f]=d}else u.sprite=a;if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.wrap=yh(),u.typeC4Shape={text:t},u.parentBoundary=Ja},"addContainer"),m3e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=ul.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,ul.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.techn={text:""};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.techn={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof a=="object"){let[f,d]=Object.entries(a)[0];u[f]=d}else u.sprite=a;if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.wrap=yh(),u.typeC4Shape={text:t},u.parentBoundary=Ja},"addComponent"),g3e=o(function(t,e,r,n,i){if(t===null||e===null)return;let a={},s=tc.find(l=>l.alias===t);if(s&&t===s.alias?a=s:(a.alias=t,tc.push(a)),e==null?a.label={text:""}:a.label={text:e},r==null)a.type={text:"system"};else if(typeof r=="object"){let[l,u]=Object.entries(r)[0];a[l]={text:u}}else a.type={text:r};if(typeof n=="object"){let[l,u]=Object.entries(n)[0];a[l]=u}else a.tags=n;if(typeof i=="object"){let[l,u]=Object.entries(i)[0];a[l]=u}else a.link=i;a.parentBoundary=Ja,a.wrap=yh(),cl=Ja,Ja=t,gh.push(cl)},"addPersonOrSystemBoundary"),y3e=o(function(t,e,r,n,i){if(t===null||e===null)return;let a={},s=tc.find(l=>l.alias===t);if(s&&t===s.alias?a=s:(a.alias=t,tc.push(a)),e==null?a.label={text:""}:a.label={text:e},r==null)a.type={text:"container"};else if(typeof r=="object"){let[l,u]=Object.entries(r)[0];a[l]={text:u}}else a.type={text:r};if(typeof n=="object"){let[l,u]=Object.entries(n)[0];a[l]=u}else a.tags=n;if(typeof i=="object"){let[l,u]=Object.entries(i)[0];a[l]=u}else a.link=i;a.parentBoundary=Ja,a.wrap=yh(),cl=Ja,Ja=t,gh.push(cl)},"addContainerBoundary"),v3e=o(function(t,e,r,n,i,a,s,l){if(e===null||r===null)return;let u={},h=tc.find(f=>f.alias===e);if(h&&e===h.alias?u=h:(u.alias=e,tc.push(u)),r==null?u.label={text:""}:u.label={text:r},n==null)u.type={text:"node"};else if(typeof n=="object"){let[f,d]=Object.entries(n)[0];u[f]={text:d}}else u.type={text:n};if(i==null)u.descr={text:""};else if(typeof i=="object"){let[f,d]=Object.entries(i)[0];u[f]={text:d}}else u.descr={text:i};if(typeof s=="object"){let[f,d]=Object.entries(s)[0];u[f]=d}else u.tags=s;if(typeof l=="object"){let[f,d]=Object.entries(l)[0];u[f]=d}else u.link=l;u.nodeType=t,u.parentBoundary=Ja,u.wrap=yh(),cl=Ja,Ja=e,gh.push(cl)},"addDeploymentNode"),x3e=o(function(){Ja=cl,gh.pop(),cl=gh.pop(),gh.push(cl)},"popBoundaryParseStack"),b3e=o(function(t,e,r,n,i,a,s,l,u,h,f){let d=ul.find(p=>p.alias===e);if(!(d===void 0&&(d=tc.find(p=>p.alias===e),d===void 0))){if(r!=null)if(typeof r=="object"){let[p,m]=Object.entries(r)[0];d[p]=m}else d.bgColor=r;if(n!=null)if(typeof n=="object"){let[p,m]=Object.entries(n)[0];d[p]=m}else d.fontColor=n;if(i!=null)if(typeof i=="object"){let[p,m]=Object.entries(i)[0];d[p]=m}else d.borderColor=i;if(a!=null)if(typeof a=="object"){let[p,m]=Object.entries(a)[0];d[p]=m}else d.shadowing=a;if(s!=null)if(typeof s=="object"){let[p,m]=Object.entries(s)[0];d[p]=m}else d.shape=s;if(l!=null)if(typeof l=="object"){let[p,m]=Object.entries(l)[0];d[p]=m}else d.sprite=l;if(u!=null)if(typeof u=="object"){let[p,m]=Object.entries(u)[0];d[p]=m}else d.techn=u;if(h!=null)if(typeof h=="object"){let[p,m]=Object.entries(h)[0];d[p]=m}else d.legendText=h;if(f!=null)if(typeof f=="object"){let[p,m]=Object.entries(f)[0];d[p]=m}else d.legendSprite=f}},"updateElStyle"),w3e=o(function(t,e,r,n,i,a,s){let l=Ky.find(u=>u.from===e&&u.to===r);if(l!==void 0){if(n!=null)if(typeof n=="object"){let[u,h]=Object.entries(n)[0];l[u]=h}else l.textColor=n;if(i!=null)if(typeof i=="object"){let[u,h]=Object.entries(i)[0];l[u]=h}else l.lineColor=i;if(a!=null)if(typeof a=="object"){let[u,h]=Object.entries(a)[0];l[u]=parseInt(h)}else l.offsetX=parseInt(a);if(s!=null)if(typeof s=="object"){let[u,h]=Object.entries(s)[0];l[u]=parseInt(h)}else l.offsetY=parseInt(s)}},"updateRelStyle"),T3e=o(function(t,e,r){let n=_3,i=D3;if(typeof e=="object"){let a=Object.values(e)[0];n=parseInt(a)}else n=parseInt(e);if(typeof r=="object"){let a=Object.values(r)[0];i=parseInt(a)}else i=parseInt(r);n>=1&&(_3=n),i>=1&&(D3=i)},"updateLayoutConfig"),k3e=o(function(){return _3},"getC4ShapeInRow"),E3e=o(function(){return D3},"getC4BoundaryInRow"),S3e=o(function(){return Ja},"getCurrentBoundaryParse"),C3e=o(function(){return cl},"getParentBoundaryParse"),UG=o(function(t){return t==null?ul:ul.filter(e=>e.parentBoundary===t)},"getC4ShapeArray"),A3e=o(function(t){return ul.find(e=>e.alias===t)},"getC4Shape"),_3e=o(function(t){return Object.keys(UG(t))},"getC4ShapeKeys"),HG=o(function(t){return t==null?tc:tc.filter(e=>e.parentBoundary===t)},"getBoundaries"),D3e=HG,L3e=o(function(){return Ky},"getRels"),R3e=o(function(){return lA},"getTitle"),N3e=o(function(t){cA=t},"setWrap"),yh=o(function(){return cA},"autoWrap"),M3e=o(function(){ul=[],tc=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],cl="",Ja="global",gh=[""],Ky=[],gh=[""],lA="",cA=!1,_3=4,D3=2},"clear"),I3e={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},O3e={FILLED:0,OPEN:1},P3e={LEFTOF:0,RIGHTOF:1,OVER:2},B3e=o(function(t){lA=Tr(t,me())},"setTitle"),Qy={addPersonOrSystem:d3e,addPersonOrSystemBoundary:g3e,addContainer:p3e,addContainerBoundary:y3e,addComponent:m3e,addDeploymentNode:v3e,popBoundaryParseStack:x3e,addRel:f3e,updateElStyle:b3e,updateRelStyle:w3e,updateLayoutConfig:T3e,autoWrap:yh,setWrap:N3e,getC4ShapeArray:UG,getC4Shape:A3e,getC4ShapeKeys:_3e,getBoundaries:HG,getBoundarys:D3e,getCurrentBoundaryParse:S3e,getParentBoundaryParse:C3e,getRels:L3e,getTitle:R3e,getC4Type:u3e,getC4ShapeInRow:k3e,getC4BoundaryInRow:E3e,setAccTitle:Lr,getAccTitle:Rr,getAccDescription:Mr,setAccDescription:Nr,getConfig:o(()=>me().c4,"getConfig"),clear:M3e,LINETYPE:I3e,ARROWTYPE:O3e,PLACEMENT:P3e,setTitle:B3e,setC4Type:h3e}});function sd(t,e){return t==null||e==null?NaN:t<e?-1:t>e?1:t>=e?0:NaN}var hA=N(()=>{"use strict";o(sd,"ascending")});function fA(t,e){return t==null||e==null?NaN:e<t?-1:e>t?1:e>=t?0:NaN}var WG=N(()=>{"use strict";o(fA,"descending")});function od(t){let e,r,n;t.length!==2?(e=sd,r=o((l,u)=>sd(t(l),u),"compare2"),n=o((l,u)=>t(l)-u,"delta")):(e=t===sd||t===fA?t:F3e,r=t,n=t);function i(l,u,h=0,f=l.length){if(h<f){if(e(u,u)!==0)return f;do{let d=h+f>>>1;r(l[d],u)<0?h=d+1:f=d}while(h<f)}return h}o(i,"left");function a(l,u,h=0,f=l.length){if(h<f){if(e(u,u)!==0)return f;do{let d=h+f>>>1;r(l[d],u)<=0?h=d+1:f=d}while(h<f)}return h}o(a,"right");function s(l,u,h=0,f=l.length){let d=i(l,u,h,f-1);return d>h&&n(l[d-1],u)>-n(l[d],u)?d-1:d}return o(s,"center"),{left:i,center:s,right:a}}function F3e(){return 0}var dA=N(()=>{"use strict";hA();WG();o(od,"bisector");o(F3e,"zero")});function pA(t){return t===null?NaN:+t}var qG=N(()=>{"use strict";o(pA,"number")});var YG,XG,$3e,z3e,mA,jG=N(()=>{"use strict";hA();dA();qG();YG=od(sd),XG=YG.right,$3e=YG.left,z3e=od(pA).center,mA=XG});function KG({_intern:t,_key:e},r){let n=e(r);return t.has(n)?t.get(n):r}function G3e({_intern:t,_key:e},r){let n=e(r);return t.has(n)?t.get(n):(t.set(n,r),r)}function V3e({_intern:t,_key:e},r){let n=e(r);return t.has(n)&&(r=t.get(n),t.delete(n)),r}function U3e(t){return t!==null&&typeof t=="object"?t.valueOf():t}var g0,QG=N(()=>{"use strict";g0=class extends Map{static{o(this,"InternMap")}constructor(e,r=U3e){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(let[n,i]of e)this.set(n,i)}get(e){return super.get(KG(this,e))}has(e){return super.has(KG(this,e))}set(e,r){return super.set(G3e(this,e),r)}delete(e){return super.delete(V3e(this,e))}};o(KG,"intern_get");o(G3e,"intern_set");o(V3e,"intern_delete");o(U3e,"keyof")});function L3(t,e,r){let n=(e-t)/Math.max(0,r),i=Math.floor(Math.log10(n)),a=n/Math.pow(10,i),s=a>=H3e?10:a>=W3e?5:a>=q3e?2:1,l,u,h;return i<0?(h=Math.pow(10,-i)/s,l=Math.round(t*h),u=Math.round(e*h),l/h<t&&++l,u/h>e&&--u,h=-h):(h=Math.pow(10,i)*s,l=Math.round(t/h),u=Math.round(e/h),l*h<t&&++l,u*h>e&&--u),u<l&&.5<=r&&r<2?L3(t,e,r*2):[l,u,h]}function R3(t,e,r){if(e=+e,t=+t,r=+r,!(r>0))return[];if(t===e)return[t];let n=e<t,[i,a,s]=n?L3(e,t,r):L3(t,e,r);if(!(a>=i))return[];let l=a-i+1,u=new Array(l);if(n)if(s<0)for(let h=0;h<l;++h)u[h]=(a-h)/-s;else for(let h=0;h<l;++h)u[h]=(a-h)*s;else if(s<0)for(let h=0;h<l;++h)u[h]=(i+h)/-s;else for(let h=0;h<l;++h)u[h]=(i+h)*s;return u}function Zy(t,e,r){return e=+e,t=+t,r=+r,L3(t,e,r)[2]}function y0(t,e,r){e=+e,t=+t,r=+r;let n=e<t,i=n?Zy(e,t,r):Zy(t,e,r);return(n?-1:1)*(i<0?1/-i:i)}var H3e,W3e,q3e,ZG=N(()=>{"use strict";H3e=Math.sqrt(50),W3e=Math.sqrt(10),q3e=Math.sqrt(2);o(L3,"tickSpec");o(R3,"ticks");o(Zy,"tickIncrement");o(y0,"tickStep")});function N3(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r<n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r<i||r===void 0&&i>=i)&&(r=i)}return r}var JG=N(()=>{"use strict";o(N3,"max")});function M3(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}var eV=N(()=>{"use strict";o(M3,"min")});function I3(t,e,r){t=+t,e=+e,r=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((e-t)/r))|0,a=new Array(i);++n<i;)a[n]=t+n*r;return a}var tV=N(()=>{"use strict";o(I3,"range")});var vh=N(()=>{"use strict";jG();dA();JG();eV();tV();ZG();QG()});function gA(t){return t}var rV=N(()=>{"use strict";o(gA,"default")});function Y3e(t){return"translate("+t+",0)"}function X3e(t){return"translate(0,"+t+")"}function j3e(t){return e=>+t(e)}function K3e(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function Q3e(){return!this.__axis}function iV(t,e){var r=[],n=null,i=null,a=6,s=6,l=3,u=typeof window<"u"&&window.devicePixelRatio>1?0:.5,h=t===P3||t===O3?-1:1,f=t===O3||t===yA?"x":"y",d=t===P3||t===vA?Y3e:X3e;function p(m){var g=n??(e.ticks?e.ticks.apply(e,r):e.domain()),y=i??(e.tickFormat?e.tickFormat.apply(e,r):gA),v=Math.max(a,0)+l,x=e.range(),b=+x[0]+u,w=+x[x.length-1]+u,C=(e.bandwidth?K3e:j3e)(e.copy(),u),T=m.selection?m.selection():m,E=T.selectAll(".domain").data([null]),A=T.selectAll(".tick").data(g,e).order(),S=A.exit(),_=A.enter().append("g").attr("class","tick"),I=A.select("line"),D=A.select("text");E=E.merge(E.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),A=A.merge(_),I=I.merge(_.append("line").attr("stroke","currentColor").attr(f+"2",h*a)),D=D.merge(_.append("text").attr("fill","currentColor").attr(f,h*v).attr("dy",t===P3?"0em":t===vA?"0.71em":"0.32em")),m!==T&&(E=E.transition(m),A=A.transition(m),I=I.transition(m),D=D.transition(m),S=S.transition(m).attr("opacity",nV).attr("transform",function(k){return isFinite(k=C(k))?d(k+u):this.getAttribute("transform")}),_.attr("opacity",nV).attr("transform",function(k){var L=this.parentNode.__axis;return d((L&&isFinite(L=L(k))?L:C(k))+u)})),S.remove(),E.attr("d",t===O3||t===yA?s?"M"+h*s+","+b+"H"+u+"V"+w+"H"+h*s:"M"+u+","+b+"V"+w:s?"M"+b+","+h*s+"V"+u+"H"+w+"V"+h*s:"M"+b+","+u+"H"+w),A.attr("opacity",1).attr("transform",function(k){return d(C(k)+u)}),I.attr(f+"2",h*a),D.attr(f,h*v).text(y),T.filter(Q3e).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===yA?"start":t===O3?"end":"middle"),T.each(function(){this.__axis=C})}return o(p,"axis"),p.scale=function(m){return arguments.length?(e=m,p):e},p.ticks=function(){return r=Array.from(arguments),p},p.tickArguments=function(m){return arguments.length?(r=m==null?[]:Array.from(m),p):r.slice()},p.tickValues=function(m){return arguments.length?(n=m==null?null:Array.from(m),p):n&&n.slice()},p.tickFormat=function(m){return arguments.length?(i=m,p):i},p.tickSize=function(m){return arguments.length?(a=s=+m,p):a},p.tickSizeInner=function(m){return arguments.length?(a=+m,p):a},p.tickSizeOuter=function(m){return arguments.length?(s=+m,p):s},p.tickPadding=function(m){return arguments.length?(l=+m,p):l},p.offset=function(m){return arguments.length?(u=+m,p):u},p}function xA(t){return iV(P3,t)}function bA(t){return iV(vA,t)}var P3,yA,vA,O3,nV,aV=N(()=>{"use strict";rV();P3=1,yA=2,vA=3,O3=4,nV=1e-6;o(Y3e,"translateX");o(X3e,"translateY");o(j3e,"number");o(K3e,"center");o(Q3e,"entering");o(iV,"axis");o(xA,"axisTop");o(bA,"axisBottom")});var sV=N(()=>{"use strict";aV()});function lV(){for(var t=0,e=arguments.length,r={},n;t<e;++t){if(!(n=arguments[t]+"")||n in r||/[\s.]/.test(n))throw new Error("illegal type: "+n);r[n]=[]}return new B3(r)}function B3(t){this._=t}function J3e(t,e){return t.trim().split(/^|\s+/).map(function(r){var n="",i=r.indexOf(".");if(i>=0&&(n=r.slice(i+1),r=r.slice(0,i)),r&&!e.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}function e5e(t,e){for(var r=0,n=t.length,i;r<n;++r)if((i=t[r]).name===e)return i.value}function oV(t,e,r){for(var n=0,i=t.length;n<i;++n)if(t[n].name===e){t[n]=Z3e,t=t.slice(0,n).concat(t.slice(n+1));break}return r!=null&&t.push({name:e,value:r}),t}var Z3e,wA,cV=N(()=>{"use strict";Z3e={value:o(()=>{},"value")};o(lV,"dispatch");o(B3,"Dispatch");o(J3e,"parseTypenames");B3.prototype=lV.prototype={constructor:B3,on:o(function(t,e){var r=this._,n=J3e(t+"",r),i,a=-1,s=n.length;if(arguments.length<2){for(;++a<s;)if((i=(t=n[a]).type)&&(i=e5e(r[i],t.name)))return i;return}if(e!=null&&typeof e!="function")throw new Error("invalid callback: "+e);for(;++a<s;)if(i=(t=n[a]).type)r[i]=oV(r[i],t.name,e);else if(e==null)for(i in r)r[i]=oV(r[i],t.name,null);return this},"on"),copy:o(function(){var t={},e=this._;for(var r in e)t[r]=e[r].slice();return new B3(t)},"copy"),call:o(function(t,e){if((i=arguments.length-2)>0)for(var r=new Array(i),n=0,i,a;n<i;++n)r[n]=arguments[n+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(a=this._[t],n=0,i=a.length;n<i;++n)a[n].value.apply(e,r)},"call"),apply:o(function(t,e,r){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var n=this._[t],i=0,a=n.length;i<a;++i)n[i].value.apply(e,r)},"apply")};o(e5e,"get");o(oV,"set");wA=lV});var TA=N(()=>{"use strict";cV()});var F3,kA,EA=N(()=>{"use strict";F3="http://www.w3.org/1999/xhtml",kA={svg:"http://www.w3.org/2000/svg",xhtml:F3,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"}});function rc(t){var e=t+="",r=e.indexOf(":");return r>=0&&(e=t.slice(0,r))!=="xmlns"&&(t=t.slice(r+1)),kA.hasOwnProperty(e)?{space:kA[e],local:t}:t}var $3=N(()=>{"use strict";EA();o(rc,"default")});function t5e(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===F3&&e.documentElement.namespaceURI===F3?e.createElement(t):e.createElementNS(r,t)}}function r5e(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Jy(t){var e=rc(t);return(e.local?r5e:t5e)(e)}var SA=N(()=>{"use strict";$3();EA();o(t5e,"creatorInherit");o(r5e,"creatorFixed");o(Jy,"default")});function n5e(){}function xh(t){return t==null?n5e:function(){return this.querySelector(t)}}var z3=N(()=>{"use strict";o(n5e,"none");o(xh,"default")});function CA(t){typeof t!="function"&&(t=xh(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i<r;++i)for(var a=e[i],s=a.length,l=n[i]=new Array(s),u,h,f=0;f<s;++f)(u=a[f])&&(h=t.call(u,u.__data__,f,a))&&("__data__"in u&&(h.__data__=u.__data__),l[f]=h);return new oi(n,this._parents)}var uV=N(()=>{"use strict";hl();z3();o(CA,"default")});function AA(t){return t==null?[]:Array.isArray(t)?t:Array.from(t)}var hV=N(()=>{"use strict";o(AA,"array")});function i5e(){return[]}function v0(t){return t==null?i5e:function(){return this.querySelectorAll(t)}}var _A=N(()=>{"use strict";o(i5e,"empty");o(v0,"default")});function a5e(t){return function(){return AA(t.apply(this,arguments))}}function DA(t){typeof t=="function"?t=a5e(t):t=v0(t);for(var e=this._groups,r=e.length,n=[],i=[],a=0;a<r;++a)for(var s=e[a],l=s.length,u,h=0;h<l;++h)(u=s[h])&&(n.push(t.call(u,u.__data__,h,s)),i.push(u));return new oi(n,i)}var fV=N(()=>{"use strict";hl();hV();_A();o(a5e,"arrayAll");o(DA,"default")});function x0(t){return function(){return this.matches(t)}}function G3(t){return function(e){return e.matches(t)}}var ev=N(()=>{"use strict";o(x0,"default");o(G3,"childMatcher")});function o5e(t){return function(){return s5e.call(this.children,t)}}function l5e(){return this.firstElementChild}function LA(t){return this.select(t==null?l5e:o5e(typeof t=="function"?t:G3(t)))}var s5e,dV=N(()=>{"use strict";ev();s5e=Array.prototype.find;o(o5e,"childFind");o(l5e,"childFirst");o(LA,"default")});function u5e(){return Array.from(this.children)}function h5e(t){return function(){return c5e.call(this.children,t)}}function RA(t){return this.selectAll(t==null?u5e:h5e(typeof t=="function"?t:G3(t)))}var c5e,pV=N(()=>{"use strict";ev();c5e=Array.prototype.filter;o(u5e,"children");o(h5e,"childrenFilter");o(RA,"default")});function NA(t){typeof t!="function"&&(t=x0(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i<r;++i)for(var a=e[i],s=a.length,l=n[i]=[],u,h=0;h<s;++h)(u=a[h])&&t.call(u,u.__data__,h,a)&&l.push(u);return new oi(n,this._parents)}var mV=N(()=>{"use strict";hl();ev();o(NA,"default")});function tv(t){return new Array(t.length)}var MA=N(()=>{"use strict";o(tv,"default")});function IA(){return new oi(this._enter||this._groups.map(tv),this._parents)}function rv(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}var OA=N(()=>{"use strict";MA();hl();o(IA,"default");o(rv,"EnterNode");rv.prototype={constructor:rv,appendChild:o(function(t){return this._parent.insertBefore(t,this._next)},"appendChild"),insertBefore:o(function(t,e){return this._parent.insertBefore(t,e)},"insertBefore"),querySelector:o(function(t){return this._parent.querySelector(t)},"querySelector"),querySelectorAll:o(function(t){return this._parent.querySelectorAll(t)},"querySelectorAll")}});function PA(t){return function(){return t}}var gV=N(()=>{"use strict";o(PA,"default")});function f5e(t,e,r,n,i,a){for(var s=0,l,u=e.length,h=a.length;s<h;++s)(l=e[s])?(l.__data__=a[s],n[s]=l):r[s]=new rv(t,a[s]);for(;s<u;++s)(l=e[s])&&(i[s]=l)}function d5e(t,e,r,n,i,a,s){var l,u,h=new Map,f=e.length,d=a.length,p=new Array(f),m;for(l=0;l<f;++l)(u=e[l])&&(p[l]=m=s.call(u,u.__data__,l,e)+"",h.has(m)?i[l]=u:h.set(m,u));for(l=0;l<d;++l)m=s.call(t,a[l],l,a)+"",(u=h.get(m))?(n[l]=u,u.__data__=a[l],h.delete(m)):r[l]=new rv(t,a[l]);for(l=0;l<f;++l)(u=e[l])&&h.get(p[l])===u&&(i[l]=u)}function p5e(t){return t.__data__}function BA(t,e){if(!arguments.length)return Array.from(this,p5e);var r=e?d5e:f5e,n=this._parents,i=this._groups;typeof t!="function"&&(t=PA(t));for(var a=i.length,s=new Array(a),l=new Array(a),u=new Array(a),h=0;h<a;++h){var f=n[h],d=i[h],p=d.length,m=m5e(t.call(f,f&&f.__data__,h,n)),g=m.length,y=l[h]=new Array(g),v=s[h]=new Array(g),x=u[h]=new Array(p);r(f,d,y,v,x,m,e);for(var b=0,w=0,C,T;b<g;++b)if(C=y[b]){for(b>=w&&(w=b+1);!(T=v[w])&&++w<g;);C._next=T||null}}return s=new oi(s,n),s._enter=l,s._exit=u,s}function m5e(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}var yV=N(()=>{"use strict";hl();OA();gV();o(f5e,"bindIndex");o(d5e,"bindKey");o(p5e,"datum");o(BA,"default");o(m5e,"arraylike")});function FA(){return new oi(this._exit||this._groups.map(tv),this._parents)}var vV=N(()=>{"use strict";MA();hl();o(FA,"default")});function $A(t,e,r){var n=this.enter(),i=this,a=this.exit();return typeof t=="function"?(n=t(n),n&&(n=n.selection())):n=n.append(t+""),e!=null&&(i=e(i),i&&(i=i.selection())),r==null?a.remove():r(a),n&&i?n.merge(i).order():i}var xV=N(()=>{"use strict";o($A,"default")});function zA(t){for(var e=t.selection?t.selection():t,r=this._groups,n=e._groups,i=r.length,a=n.length,s=Math.min(i,a),l=new Array(i),u=0;u<s;++u)for(var h=r[u],f=n[u],d=h.length,p=l[u]=new Array(d),m,g=0;g<d;++g)(m=h[g]||f[g])&&(p[g]=m);for(;u<i;++u)l[u]=r[u];return new oi(l,this._parents)}var bV=N(()=>{"use strict";hl();o(zA,"default")});function GA(){for(var t=this._groups,e=-1,r=t.length;++e<r;)for(var n=t[e],i=n.length-1,a=n[i],s;--i>=0;)(s=n[i])&&(a&&s.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(s,a),a=s);return this}var wV=N(()=>{"use strict";o(GA,"default")});function VA(t){t||(t=g5e);function e(d,p){return d&&p?t(d.__data__,p.__data__):!d-!p}o(e,"compareNode");for(var r=this._groups,n=r.length,i=new Array(n),a=0;a<n;++a){for(var s=r[a],l=s.length,u=i[a]=new Array(l),h,f=0;f<l;++f)(h=s[f])&&(u[f]=h);u.sort(e)}return new oi(i,this._parents).order()}function g5e(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}var TV=N(()=>{"use strict";hl();o(VA,"default");o(g5e,"ascending")});function UA(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}var kV=N(()=>{"use strict";o(UA,"default")});function HA(){return Array.from(this)}var EV=N(()=>{"use strict";o(HA,"default")});function WA(){for(var t=this._groups,e=0,r=t.length;e<r;++e)for(var n=t[e],i=0,a=n.length;i<a;++i){var s=n[i];if(s)return s}return null}var SV=N(()=>{"use strict";o(WA,"default")});function qA(){let t=0;for(let e of this)++t;return t}var CV=N(()=>{"use strict";o(qA,"default")});function YA(){return!this.node()}var AV=N(()=>{"use strict";o(YA,"default")});function XA(t){for(var e=this._groups,r=0,n=e.length;r<n;++r)for(var i=e[r],a=0,s=i.length,l;a<s;++a)(l=i[a])&&t.call(l,l.__data__,a,i);return this}var _V=N(()=>{"use strict";o(XA,"default")});function y5e(t){return function(){this.removeAttribute(t)}}function v5e(t){return function(){this.removeAttributeNS(t.space,t.local)}}function x5e(t,e){return function(){this.setAttribute(t,e)}}function b5e(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function w5e(t,e){return function(){var r=e.apply(this,arguments);r==null?this.removeAttribute(t):this.setAttribute(t,r)}}function T5e(t,e){return function(){var r=e.apply(this,arguments);r==null?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,r)}}function jA(t,e){var r=rc(t);if(arguments.length<2){var n=this.node();return r.local?n.getAttributeNS(r.space,r.local):n.getAttribute(r)}return this.each((e==null?r.local?v5e:y5e:typeof e=="function"?r.local?T5e:w5e:r.local?b5e:x5e)(r,e))}var DV=N(()=>{"use strict";$3();o(y5e,"attrRemove");o(v5e,"attrRemoveNS");o(x5e,"attrConstant");o(b5e,"attrConstantNS");o(w5e,"attrFunction");o(T5e,"attrFunctionNS");o(jA,"default")});function nv(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}var KA=N(()=>{"use strict";o(nv,"default")});function k5e(t){return function(){this.style.removeProperty(t)}}function E5e(t,e,r){return function(){this.style.setProperty(t,e,r)}}function S5e(t,e,r){return function(){var n=e.apply(this,arguments);n==null?this.style.removeProperty(t):this.style.setProperty(t,n,r)}}function QA(t,e,r){return arguments.length>1?this.each((e==null?k5e:typeof e=="function"?S5e:E5e)(t,e,r??"")):bh(this.node(),t)}function bh(t,e){return t.style.getPropertyValue(e)||nv(t).getComputedStyle(t,null).getPropertyValue(e)}var ZA=N(()=>{"use strict";KA();o(k5e,"styleRemove");o(E5e,"styleConstant");o(S5e,"styleFunction");o(QA,"default");o(bh,"styleValue")});function C5e(t){return function(){delete this[t]}}function A5e(t,e){return function(){this[t]=e}}function _5e(t,e){return function(){var r=e.apply(this,arguments);r==null?delete this[t]:this[t]=r}}function JA(t,e){return arguments.length>1?this.each((e==null?C5e:typeof e=="function"?_5e:A5e)(t,e)):this.node()[t]}var LV=N(()=>{"use strict";o(C5e,"propertyRemove");o(A5e,"propertyConstant");o(_5e,"propertyFunction");o(JA,"default")});function RV(t){return t.trim().split(/^|\s+/)}function e8(t){return t.classList||new NV(t)}function NV(t){this._node=t,this._names=RV(t.getAttribute("class")||"")}function MV(t,e){for(var r=e8(t),n=-1,i=e.length;++n<i;)r.add(e[n])}function IV(t,e){for(var r=e8(t),n=-1,i=e.length;++n<i;)r.remove(e[n])}function D5e(t){return function(){MV(this,t)}}function L5e(t){return function(){IV(this,t)}}function R5e(t,e){return function(){(e.apply(this,arguments)?MV:IV)(this,t)}}function t8(t,e){var r=RV(t+"");if(arguments.length<2){for(var n=e8(this.node()),i=-1,a=r.length;++i<a;)if(!n.contains(r[i]))return!1;return!0}return this.each((typeof e=="function"?R5e:e?D5e:L5e)(r,e))}var OV=N(()=>{"use strict";o(RV,"classArray");o(e8,"classList");o(NV,"ClassList");NV.prototype={add:o(function(t){var e=this._names.indexOf(t);e<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},"add"),remove:o(function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},"remove"),contains:o(function(t){return this._names.indexOf(t)>=0},"contains")};o(MV,"classedAdd");o(IV,"classedRemove");o(D5e,"classedTrue");o(L5e,"classedFalse");o(R5e,"classedFunction");o(t8,"default")});function N5e(){this.textContent=""}function M5e(t){return function(){this.textContent=t}}function I5e(t){return function(){var e=t.apply(this,arguments);this.textContent=e??""}}function r8(t){return arguments.length?this.each(t==null?N5e:(typeof t=="function"?I5e:M5e)(t)):this.node().textContent}var PV=N(()=>{"use strict";o(N5e,"textRemove");o(M5e,"textConstant");o(I5e,"textFunction");o(r8,"default")});function O5e(){this.innerHTML=""}function P5e(t){return function(){this.innerHTML=t}}function B5e(t){return function(){var e=t.apply(this,arguments);this.innerHTML=e??""}}function n8(t){return arguments.length?this.each(t==null?O5e:(typeof t=="function"?B5e:P5e)(t)):this.node().innerHTML}var BV=N(()=>{"use strict";o(O5e,"htmlRemove");o(P5e,"htmlConstant");o(B5e,"htmlFunction");o(n8,"default")});function F5e(){this.nextSibling&&this.parentNode.appendChild(this)}function i8(){return this.each(F5e)}var FV=N(()=>{"use strict";o(F5e,"raise");o(i8,"default")});function $5e(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function a8(){return this.each($5e)}var $V=N(()=>{"use strict";o($5e,"lower");o(a8,"default")});function s8(t){var e=typeof t=="function"?t:Jy(t);return this.select(function(){return this.appendChild(e.apply(this,arguments))})}var zV=N(()=>{"use strict";SA();o(s8,"default")});function z5e(){return null}function o8(t,e){var r=typeof t=="function"?t:Jy(t),n=e==null?z5e:typeof e=="function"?e:xh(e);return this.select(function(){return this.insertBefore(r.apply(this,arguments),n.apply(this,arguments)||null)})}var GV=N(()=>{"use strict";SA();z3();o(z5e,"constantNull");o(o8,"default")});function G5e(){var t=this.parentNode;t&&t.removeChild(this)}function l8(){return this.each(G5e)}var VV=N(()=>{"use strict";o(G5e,"remove");o(l8,"default")});function V5e(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function U5e(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function c8(t){return this.select(t?U5e:V5e)}var UV=N(()=>{"use strict";o(V5e,"selection_cloneShallow");o(U5e,"selection_cloneDeep");o(c8,"default")});function u8(t){return arguments.length?this.property("__data__",t):this.node().__data__}var HV=N(()=>{"use strict";o(u8,"default")});function H5e(t){return function(e){t.call(this,e,this.__data__)}}function W5e(t){return t.trim().split(/^|\s+/).map(function(e){var r="",n=e.indexOf(".");return n>=0&&(r=e.slice(n+1),e=e.slice(0,n)),{type:e,name:r}})}function q5e(t){return function(){var e=this.__on;if(e){for(var r=0,n=-1,i=e.length,a;r<i;++r)a=e[r],(!t.type||a.type===t.type)&&a.name===t.name?this.removeEventListener(a.type,a.listener,a.options):e[++n]=a;++n?e.length=n:delete this.__on}}}function Y5e(t,e,r){return function(){var n=this.__on,i,a=H5e(e);if(n){for(var s=0,l=n.length;s<l;++s)if((i=n[s]).type===t.type&&i.name===t.name){this.removeEventListener(i.type,i.listener,i.options),this.addEventListener(i.type,i.listener=a,i.options=r),i.value=e;return}}this.addEventListener(t.type,a,r),i={type:t.type,name:t.name,value:e,listener:a,options:r},n?n.push(i):this.__on=[i]}}function h8(t,e,r){var n=W5e(t+""),i,a=n.length,s;if(arguments.length<2){var l=this.node().__on;if(l){for(var u=0,h=l.length,f;u<h;++u)for(i=0,f=l[u];i<a;++i)if((s=n[i]).type===f.type&&s.name===f.name)return f.value}return}for(l=e?Y5e:q5e,i=0;i<a;++i)this.each(l(n[i],e,r));return this}var WV=N(()=>{"use strict";o(H5e,"contextListener");o(W5e,"parseTypenames");o(q5e,"onRemove");o(Y5e,"onAdd");o(h8,"default")});function qV(t,e,r){var n=nv(t),i=n.CustomEvent;typeof i=="function"?i=new i(e,r):(i=n.document.createEvent("Event"),r?(i.initEvent(e,r.bubbles,r.cancelable),i.detail=r.detail):i.initEvent(e,!1,!1)),t.dispatchEvent(i)}function X5e(t,e){return function(){return qV(this,t,e)}}function j5e(t,e){return function(){return qV(this,t,e.apply(this,arguments))}}function f8(t,e){return this.each((typeof e=="function"?j5e:X5e)(t,e))}var YV=N(()=>{"use strict";KA();o(qV,"dispatchEvent");o(X5e,"dispatchConstant");o(j5e,"dispatchFunction");o(f8,"default")});function*d8(){for(var t=this._groups,e=0,r=t.length;e<r;++e)for(var n=t[e],i=0,a=n.length,s;i<a;++i)(s=n[i])&&(yield s)}var XV=N(()=>{"use strict";o(d8,"default")});function oi(t,e){this._groups=t,this._parents=e}function jV(){return new oi([[document.documentElement]],p8)}function K5e(){return this}var p8,hu,hl=N(()=>{"use strict";uV();fV();dV();pV();mV();yV();OA();vV();xV();bV();wV();TV();kV();EV();SV();CV();AV();_V();DV();ZA();LV();OV();PV();BV();FV();$V();zV();GV();VV();UV();HV();WV();YV();XV();p8=[null];o(oi,"Selection");o(jV,"selection");o(K5e,"selection_selection");oi.prototype=jV.prototype={constructor:oi,select:CA,selectAll:DA,selectChild:LA,selectChildren:RA,filter:NA,data:BA,enter:IA,exit:FA,join:$A,merge:zA,selection:K5e,order:GA,sort:VA,call:UA,nodes:HA,node:WA,size:qA,empty:YA,each:XA,attr:jA,style:QA,property:JA,classed:t8,text:r8,html:n8,raise:i8,lower:a8,append:s8,insert:o8,remove:l8,clone:c8,datum:u8,on:h8,dispatch:f8,[Symbol.iterator]:d8};hu=jV});function Ge(t){return typeof t=="string"?new oi([[document.querySelector(t)]],[document.documentElement]):new oi([[t]],p8)}var KV=N(()=>{"use strict";hl();o(Ge,"default")});var fl=N(()=>{"use strict";ev();$3();KV();hl();z3();_A();ZA()});var QV=N(()=>{"use strict"});function wh(t,e,r){t.prototype=e.prototype=r,r.constructor=t}function b0(t,e){var r=Object.create(t.prototype);for(var n in e)r[n]=e[n];return r}var m8=N(()=>{"use strict";o(wh,"default");o(b0,"extend")});function Th(){}function JV(){return this.rgb().formatHex()}function iwe(){return this.rgb().formatHex8()}function awe(){return sU(this).formatHsl()}function eU(){return this.rgb().formatRgb()}function pl(t){var e,r;return t=(t+"").trim().toLowerCase(),(e=Q5e.exec(t))?(r=e[1].length,e=parseInt(e[1],16),r===6?tU(e):r===3?new ua(e>>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):r===8?V3(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):r===4?V3(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=Z5e.exec(t))?new ua(e[1],e[2],e[3],1):(e=J5e.exec(t))?new ua(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=ewe.exec(t))?V3(e[1],e[2],e[3],e[4]):(e=twe.exec(t))?V3(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=rwe.exec(t))?iU(e[1],e[2]/100,e[3]/100,1):(e=nwe.exec(t))?iU(e[1],e[2]/100,e[3]/100,e[4]):ZV.hasOwnProperty(t)?tU(ZV[t]):t==="transparent"?new ua(NaN,NaN,NaN,0):null}function tU(t){return new ua(t>>16&255,t>>8&255,t&255,1)}function V3(t,e,r,n){return n<=0&&(t=e=r=NaN),new ua(t,e,r,n)}function y8(t){return t instanceof Th||(t=pl(t)),t?(t=t.rgb(),new ua(t.r,t.g,t.b,t.opacity)):new ua}function T0(t,e,r,n){return arguments.length===1?y8(t):new ua(t,e,r,n??1)}function ua(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function rU(){return`#${ld(this.r)}${ld(this.g)}${ld(this.b)}`}function swe(){return`#${ld(this.r)}${ld(this.g)}${ld(this.b)}${ld((isNaN(this.opacity)?1:this.opacity)*255)}`}function nU(){let t=W3(this.opacity);return`${t===1?"rgb(":"rgba("}${cd(this.r)}, ${cd(this.g)}, ${cd(this.b)}${t===1?")":`, ${t})`}`}function W3(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function cd(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ld(t){return t=cd(t),(t<16?"0":"")+t.toString(16)}function iU(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new dl(t,e,r,n)}function sU(t){if(t instanceof dl)return new dl(t.h,t.s,t.l,t.opacity);if(t instanceof Th||(t=pl(t)),!t)return new dl;if(t instanceof dl)return t;t=t.rgb();var e=t.r/255,r=t.g/255,n=t.b/255,i=Math.min(e,r,n),a=Math.max(e,r,n),s=NaN,l=a-i,u=(a+i)/2;return l?(e===a?s=(r-n)/l+(r<n)*6:r===a?s=(n-e)/l+2:s=(e-r)/l+4,l/=u<.5?a+i:2-a-i,s*=60):l=u>0&&u<1?0:s,new dl(s,l,u,t.opacity)}function oU(t,e,r,n){return arguments.length===1?sU(t):new dl(t,e,r,n??1)}function dl(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function aU(t){return t=(t||0)%360,t<0?t+360:t}function U3(t){return Math.max(0,Math.min(1,t||0))}function g8(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}var iv,H3,w0,av,nc,Q5e,Z5e,J5e,ewe,twe,rwe,nwe,ZV,v8=N(()=>{"use strict";m8();o(Th,"Color");iv=.7,H3=1/iv,w0="\\s*([+-]?\\d+)\\s*",av="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",nc="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",Q5e=/^#([0-9a-f]{3,8})$/,Z5e=new RegExp(`^rgb\\(${w0},${w0},${w0}\\)$`),J5e=new RegExp(`^rgb\\(${nc},${nc},${nc}\\)$`),ewe=new RegExp(`^rgba\\(${w0},${w0},${w0},${av}\\)$`),twe=new RegExp(`^rgba\\(${nc},${nc},${nc},${av}\\)$`),rwe=new RegExp(`^hsl\\(${av},${nc},${nc}\\)$`),nwe=new RegExp(`^hsla\\(${av},${nc},${nc},${av}\\)$`),ZV={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};wh(Th,pl,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:JV,formatHex:JV,formatHex8:iwe,formatHsl:awe,formatRgb:eU,toString:eU});o(JV,"color_formatHex");o(iwe,"color_formatHex8");o(awe,"color_formatHsl");o(eU,"color_formatRgb");o(pl,"color");o(tU,"rgbn");o(V3,"rgba");o(y8,"rgbConvert");o(T0,"rgb");o(ua,"Rgb");wh(ua,T0,b0(Th,{brighter(t){return t=t==null?H3:Math.pow(H3,t),new ua(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?iv:Math.pow(iv,t),new ua(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new ua(cd(this.r),cd(this.g),cd(this.b),W3(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:rU,formatHex:rU,formatHex8:swe,formatRgb:nU,toString:nU}));o(rU,"rgb_formatHex");o(swe,"rgb_formatHex8");o(nU,"rgb_formatRgb");o(W3,"clampa");o(cd,"clampi");o(ld,"hex");o(iU,"hsla");o(sU,"hslConvert");o(oU,"hsl");o(dl,"Hsl");wh(dl,oU,b0(Th,{brighter(t){return t=t==null?H3:Math.pow(H3,t),new dl(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?iv:Math.pow(iv,t),new dl(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new ua(g8(t>=240?t-240:t+120,i,n),g8(t,i,n),g8(t<120?t+240:t-120,i,n),this.opacity)},clamp(){return new dl(aU(this.h),U3(this.s),U3(this.l),W3(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let t=W3(this.opacity);return`${t===1?"hsl(":"hsla("}${aU(this.h)}, ${U3(this.s)*100}%, ${U3(this.l)*100}%${t===1?")":`, ${t})`}`}}));o(aU,"clamph");o(U3,"clampt");o(g8,"hsl2rgb")});var lU,cU,uU=N(()=>{"use strict";lU=Math.PI/180,cU=180/Math.PI});function gU(t){if(t instanceof ic)return new ic(t.l,t.a,t.b,t.opacity);if(t instanceof fu)return yU(t);t instanceof ua||(t=y8(t));var e=T8(t.r),r=T8(t.g),n=T8(t.b),i=x8((.2225045*e+.7168786*r+.0606169*n)/fU),a,s;return e===r&&r===n?a=s=i:(a=x8((.4360747*e+.3850649*r+.1430804*n)/hU),s=x8((.0139322*e+.0971045*r+.7141733*n)/dU)),new ic(116*i-16,500*(a-i),200*(i-s),t.opacity)}function k8(t,e,r,n){return arguments.length===1?gU(t):new ic(t,e,r,n??1)}function ic(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}function x8(t){return t>owe?Math.pow(t,1/3):t/mU+pU}function b8(t){return t>k0?t*t*t:mU*(t-pU)}function w8(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function T8(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function lwe(t){if(t instanceof fu)return new fu(t.h,t.c,t.l,t.opacity);if(t instanceof ic||(t=gU(t)),t.a===0&&t.b===0)return new fu(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*cU;return new fu(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function sv(t,e,r,n){return arguments.length===1?lwe(t):new fu(t,e,r,n??1)}function fu(t,e,r,n){this.h=+t,this.c=+e,this.l=+r,this.opacity=+n}function yU(t){if(isNaN(t.h))return new ic(t.l,0,0,t.opacity);var e=t.h*lU;return new ic(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}var q3,hU,fU,dU,pU,k0,mU,owe,vU=N(()=>{"use strict";m8();v8();uU();q3=18,hU=.96422,fU=1,dU=.82521,pU=4/29,k0=6/29,mU=3*k0*k0,owe=k0*k0*k0;o(gU,"labConvert");o(k8,"lab");o(ic,"Lab");wh(ic,k8,b0(Th,{brighter(t){return new ic(this.l+q3*(t??1),this.a,this.b,this.opacity)},darker(t){return new ic(this.l-q3*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return e=hU*b8(e),t=fU*b8(t),r=dU*b8(r),new ua(w8(3.1338561*e-1.6168667*t-.4906146*r),w8(-.9787684*e+1.9161415*t+.033454*r),w8(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}}));o(x8,"xyz2lab");o(b8,"lab2xyz");o(w8,"lrgb2rgb");o(T8,"rgb2lrgb");o(lwe,"hclConvert");o(sv,"hcl");o(fu,"Hcl");o(yU,"hcl2lab");wh(fu,sv,b0(Th,{brighter(t){return new fu(this.h,this.c,this.l+q3*(t??1),this.opacity)},darker(t){return new fu(this.h,this.c,this.l-q3*(t??1),this.opacity)},rgb(){return yU(this).rgb()}}))});var E0=N(()=>{"use strict";v8();vU()});function E8(t,e,r,n,i){var a=t*t,s=a*t;return((1-3*t+3*a-s)*e+(4-6*a+3*s)*r+(1+3*t+3*a-3*s)*n+s*i)/6}function S8(t){var e=t.length-1;return function(r){var n=r<=0?r=0:r>=1?(r=1,e-1):Math.floor(r*e),i=t[n],a=t[n+1],s=n>0?t[n-1]:2*i-a,l=n<e-1?t[n+2]:2*a-i;return E8((r-n/e)*e,s,i,a,l)}}var C8=N(()=>{"use strict";o(E8,"basis");o(S8,"default")});function A8(t){var e=t.length;return function(r){var n=Math.floor(((r%=1)<0?++r:r)*e),i=t[(n+e-1)%e],a=t[n%e],s=t[(n+1)%e],l=t[(n+2)%e];return E8((r-n/e)*e,i,a,s,l)}}var xU=N(()=>{"use strict";C8();o(A8,"default")});var S0,_8=N(()=>{"use strict";S0=o(t=>()=>t,"default")});function bU(t,e){return function(r){return t+r*e}}function cwe(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}function wU(t,e){var r=e-t;return r?bU(t,r>180||r<-180?r-360*Math.round(r/360):r):S0(isNaN(t)?e:t)}function TU(t){return(t=+t)==1?du:function(e,r){return r-e?cwe(e,r,t):S0(isNaN(e)?r:e)}}function du(t,e){var r=e-t;return r?bU(t,r):S0(isNaN(t)?e:t)}var D8=N(()=>{"use strict";_8();o(bU,"linear");o(cwe,"exponential");o(wU,"hue");o(TU,"gamma");o(du,"nogamma")});function kU(t){return function(e){var r=e.length,n=new Array(r),i=new Array(r),a=new Array(r),s,l;for(s=0;s<r;++s)l=T0(e[s]),n[s]=l.r||0,i[s]=l.g||0,a[s]=l.b||0;return n=t(n),i=t(i),a=t(a),l.opacity=1,function(u){return l.r=n(u),l.g=i(u),l.b=a(u),l+""}}}var ud,uwe,hwe,L8=N(()=>{"use strict";E0();C8();xU();D8();ud=o(function t(e){var r=TU(e);function n(i,a){var s=r((i=T0(i)).r,(a=T0(a)).r),l=r(i.g,a.g),u=r(i.b,a.b),h=du(i.opacity,a.opacity);return function(f){return i.r=s(f),i.g=l(f),i.b=u(f),i.opacity=h(f),i+""}}return o(n,"rgb"),n.gamma=t,n},"rgbGamma")(1);o(kU,"rgbSpline");uwe=kU(S8),hwe=kU(A8)});function R8(t,e){e||(e=[]);var r=t?Math.min(e.length,t.length):0,n=e.slice(),i;return function(a){for(i=0;i<r;++i)n[i]=t[i]*(1-a)+e[i]*a;return n}}function EU(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}var SU=N(()=>{"use strict";o(R8,"default");o(EU,"isNumberArray")});function CU(t,e){var r=e?e.length:0,n=t?Math.min(r,t.length):0,i=new Array(n),a=new Array(r),s;for(s=0;s<n;++s)i[s]=kh(t[s],e[s]);for(;s<r;++s)a[s]=e[s];return function(l){for(s=0;s<n;++s)a[s]=i[s](l);return a}}var AU=N(()=>{"use strict";Y3();o(CU,"genericArray")});function N8(t,e){var r=new Date;return t=+t,e=+e,function(n){return r.setTime(t*(1-n)+e*n),r}}var _U=N(()=>{"use strict";o(N8,"default")});function Ki(t,e){return t=+t,e=+e,function(r){return t*(1-r)+e*r}}var ov=N(()=>{"use strict";o(Ki,"default")});function M8(t,e){var r={},n={},i;(t===null||typeof t!="object")&&(t={}),(e===null||typeof e!="object")&&(e={});for(i in e)i in t?r[i]=kh(t[i],e[i]):n[i]=e[i];return function(a){for(i in r)n[i]=r[i](a);return n}}var DU=N(()=>{"use strict";Y3();o(M8,"default")});function fwe(t){return function(){return t}}function dwe(t){return function(e){return t(e)+""}}function C0(t,e){var r=O8.lastIndex=I8.lastIndex=0,n,i,a,s=-1,l=[],u=[];for(t=t+"",e=e+"";(n=O8.exec(t))&&(i=I8.exec(e));)(a=i.index)>r&&(a=e.slice(r,a),l[s]?l[s]+=a:l[++s]=a),(n=n[0])===(i=i[0])?l[s]?l[s]+=i:l[++s]=i:(l[++s]=null,u.push({i:s,x:Ki(n,i)})),r=I8.lastIndex;return r<e.length&&(a=e.slice(r),l[s]?l[s]+=a:l[++s]=a),l.length<2?u[0]?dwe(u[0].x):fwe(e):(e=u.length,function(h){for(var f=0,d;f<e;++f)l[(d=u[f]).i]=d.x(h);return l.join("")})}var O8,I8,P8=N(()=>{"use strict";ov();O8=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,I8=new RegExp(O8.source,"g");o(fwe,"zero");o(dwe,"one");o(C0,"default")});function kh(t,e){var r=typeof e,n;return e==null||r==="boolean"?S0(e):(r==="number"?Ki:r==="string"?(n=pl(e))?(e=n,ud):C0:e instanceof pl?ud:e instanceof Date?N8:EU(e)?R8:Array.isArray(e)?CU:typeof e.valueOf!="function"&&typeof e.toString!="function"||isNaN(e)?M8:Ki)(t,e)}var Y3=N(()=>{"use strict";E0();L8();AU();_U();ov();DU();P8();_8();SU();o(kh,"default")});function X3(t,e){return t=+t,e=+e,function(r){return Math.round(t*(1-r)+e*r)}}var LU=N(()=>{"use strict";o(X3,"default")});function K3(t,e,r,n,i,a){var s,l,u;return(s=Math.sqrt(t*t+e*e))&&(t/=s,e/=s),(u=t*r+e*n)&&(r-=t*u,n-=e*u),(l=Math.sqrt(r*r+n*n))&&(r/=l,n/=l,u/=l),t*n<e*r&&(t=-t,e=-e,u=-u,s=-s),{translateX:i,translateY:a,rotate:Math.atan2(e,t)*RU,skewX:Math.atan(u)*RU,scaleX:s,scaleY:l}}var RU,j3,NU=N(()=>{"use strict";RU=180/Math.PI,j3={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};o(K3,"default")});function MU(t){let e=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?j3:K3(e.a,e.b,e.c,e.d,e.e,e.f)}function IU(t){return t==null?j3:(Q3||(Q3=document.createElementNS("http://www.w3.org/2000/svg","g")),Q3.setAttribute("transform",t),(t=Q3.transform.baseVal.consolidate())?(t=t.matrix,K3(t.a,t.b,t.c,t.d,t.e,t.f)):j3)}var Q3,OU=N(()=>{"use strict";NU();o(MU,"parseCss");o(IU,"parseSvg")});function PU(t,e,r,n){function i(h){return h.length?h.pop()+" ":""}o(i,"pop");function a(h,f,d,p,m,g){if(h!==d||f!==p){var y=m.push("translate(",null,e,null,r);g.push({i:y-4,x:Ki(h,d)},{i:y-2,x:Ki(f,p)})}else(d||p)&&m.push("translate("+d+e+p+r)}o(a,"translate");function s(h,f,d,p){h!==f?(h-f>180?f+=360:f-h>180&&(h+=360),p.push({i:d.push(i(d)+"rotate(",null,n)-2,x:Ki(h,f)})):f&&d.push(i(d)+"rotate("+f+n)}o(s,"rotate");function l(h,f,d,p){h!==f?p.push({i:d.push(i(d)+"skewX(",null,n)-2,x:Ki(h,f)}):f&&d.push(i(d)+"skewX("+f+n)}o(l,"skewX");function u(h,f,d,p,m,g){if(h!==d||f!==p){var y=m.push(i(m)+"scale(",null,",",null,")");g.push({i:y-4,x:Ki(h,d)},{i:y-2,x:Ki(f,p)})}else(d!==1||p!==1)&&m.push(i(m)+"scale("+d+","+p+")")}return o(u,"scale"),function(h,f){var d=[],p=[];return h=t(h),f=t(f),a(h.translateX,h.translateY,f.translateX,f.translateY,d,p),s(h.rotate,f.rotate,d,p),l(h.skewX,f.skewX,d,p),u(h.scaleX,h.scaleY,f.scaleX,f.scaleY,d,p),h=f=null,function(m){for(var g=-1,y=p.length,v;++g<y;)d[(v=p[g]).i]=v.x(m);return d.join("")}}}var B8,F8,BU=N(()=>{"use strict";ov();OU();o(PU,"interpolateTransform");B8=PU(MU,"px, ","px)","deg)"),F8=PU(IU,", ",")",")")});function FU(t){return function(e,r){var n=t((e=sv(e)).h,(r=sv(r)).h),i=du(e.c,r.c),a=du(e.l,r.l),s=du(e.opacity,r.opacity);return function(l){return e.h=n(l),e.c=i(l),e.l=a(l),e.opacity=s(l),e+""}}}var $8,pwe,$U=N(()=>{"use strict";E0();D8();o(FU,"hcl");$8=FU(wU),pwe=FU(du)});var A0=N(()=>{"use strict";Y3();ov();LU();P8();BU();L8();$U()});function dv(){return hd||(VU(mwe),hd=hv.now()+e5)}function mwe(){hd=0}function fv(){this._call=this._time=this._next=null}function t5(t,e,r){var n=new fv;return n.restart(t,e,r),n}function UU(){dv(),++_0;for(var t=Z3,e;t;)(e=hd-t._time)>=0&&t._call.call(void 0,e),t=t._next;--_0}function zU(){hd=(J3=hv.now())+e5,_0=cv=0;try{UU()}finally{_0=0,ywe(),hd=0}}function gwe(){var t=hv.now(),e=t-J3;e>GU&&(e5-=e,J3=t)}function ywe(){for(var t,e=Z3,r,n=1/0;e;)e._call?(n>e._time&&(n=e._time),t=e,e=e._next):(r=e._next,e._next=null,e=t?t._next=r:Z3=r);uv=t,z8(n)}function z8(t){if(!_0){cv&&(cv=clearTimeout(cv));var e=t-hd;e>24?(t<1/0&&(cv=setTimeout(zU,t-hv.now()-e5)),lv&&(lv=clearInterval(lv))):(lv||(J3=hv.now(),lv=setInterval(gwe,GU)),_0=1,VU(zU))}}var _0,cv,lv,GU,Z3,uv,J3,hd,e5,hv,VU,G8=N(()=>{"use strict";_0=0,cv=0,lv=0,GU=1e3,J3=0,hd=0,e5=0,hv=typeof performance=="object"&&performance.now?performance:Date,VU=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};o(dv,"now");o(mwe,"clearNow");o(fv,"Timer");fv.prototype=t5.prototype={constructor:fv,restart:o(function(t,e,r){if(typeof t!="function")throw new TypeError("callback is not a function");r=(r==null?dv():+r)+(e==null?0:+e),!this._next&&uv!==this&&(uv?uv._next=this:Z3=this,uv=this),this._call=t,this._time=r,z8()},"restart"),stop:o(function(){this._call&&(this._call=null,this._time=1/0,z8())},"stop")};o(t5,"timer");o(UU,"timerFlush");o(zU,"wake");o(gwe,"poke");o(ywe,"nap");o(z8,"sleep")});function pv(t,e,r){var n=new fv;return e=e==null?0:+e,n.restart(i=>{n.stop(),t(i+e)},e,r),n}var HU=N(()=>{"use strict";G8();o(pv,"default")});var r5=N(()=>{"use strict";G8();HU()});function pu(t,e,r,n,i,a){var s=t.__transition;if(!s)t.__transition={};else if(r in s)return;bwe(t,r,{name:e,index:n,group:i,on:vwe,tween:xwe,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:YU})}function gv(t,e){var r=Bi(t,e);if(r.state>YU)throw new Error("too late; already scheduled");return r}function ha(t,e){var r=Bi(t,e);if(r.state>n5)throw new Error("too late; already running");return r}function Bi(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function bwe(t,e,r){var n=t.__transition,i;n[e]=r,r.timer=t5(a,0,r.time);function a(h){r.state=WU,r.timer.restart(s,r.delay,r.time),r.delay<=h&&s(h-r.delay)}o(a,"schedule");function s(h){var f,d,p,m;if(r.state!==WU)return u();for(f in n)if(m=n[f],m.name===r.name){if(m.state===n5)return pv(s);m.state===qU?(m.state=mv,m.timer.stop(),m.on.call("interrupt",t,t.__data__,m.index,m.group),delete n[f]):+f<e&&(m.state=mv,m.timer.stop(),m.on.call("cancel",t,t.__data__,m.index,m.group),delete n[f])}if(pv(function(){r.state===n5&&(r.state=qU,r.timer.restart(l,r.delay,r.time),l(h))}),r.state=i5,r.on.call("start",t,t.__data__,r.index,r.group),r.state===i5){for(r.state=n5,i=new Array(p=r.tween.length),f=0,d=-1;f<p;++f)(m=r.tween[f].value.call(t,t.__data__,r.index,r.group))&&(i[++d]=m);i.length=d+1}}o(s,"start");function l(h){for(var f=h<r.duration?r.ease.call(null,h/r.duration):(r.timer.restart(u),r.state=a5,1),d=-1,p=i.length;++d<p;)i[d].call(t,f);r.state===a5&&(r.on.call("end",t,t.__data__,r.index,r.group),u())}o(l,"tick");function u(){r.state=mv,r.timer.stop(),delete n[e];for(var h in n)return;delete t.__transition}o(u,"stop")}var vwe,xwe,YU,WU,i5,n5,qU,a5,mv,Es=N(()=>{"use strict";TA();r5();vwe=wA("start","end","cancel","interrupt"),xwe=[],YU=0,WU=1,i5=2,n5=3,qU=4,a5=5,mv=6;o(pu,"default");o(gv,"init");o(ha,"set");o(Bi,"get");o(bwe,"create")});function yv(t,e){var r=t.__transition,n,i,a=!0,s;if(r){e=e==null?null:e+"";for(s in r){if((n=r[s]).name!==e){a=!1;continue}i=n.state>i5&&n.state<a5,n.state=mv,n.timer.stop(),n.on.call(i?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete r[s]}a&&delete t.__transition}}var XU=N(()=>{"use strict";Es();o(yv,"default")});function V8(t){return this.each(function(){yv(this,t)})}var jU=N(()=>{"use strict";XU();o(V8,"default")});function wwe(t,e){var r,n;return function(){var i=ha(this,t),a=i.tween;if(a!==r){n=r=a;for(var s=0,l=n.length;s<l;++s)if(n[s].name===e){n=n.slice(),n.splice(s,1);break}}i.tween=n}}function Twe(t,e,r){var n,i;if(typeof r!="function")throw new Error;return function(){var a=ha(this,t),s=a.tween;if(s!==n){i=(n=s).slice();for(var l={name:e,value:r},u=0,h=i.length;u<h;++u)if(i[u].name===e){i[u]=l;break}u===h&&i.push(l)}a.tween=i}}function U8(t,e){var r=this._id;if(t+="",arguments.length<2){for(var n=Bi(this.node(),r).tween,i=0,a=n.length,s;i<a;++i)if((s=n[i]).name===t)return s.value;return null}return this.each((e==null?wwe:Twe)(r,t,e))}function D0(t,e,r){var n=t._id;return t.each(function(){var i=ha(this,n);(i.value||(i.value={}))[e]=r.apply(this,arguments)}),function(i){return Bi(i,n).value[e]}}var vv=N(()=>{"use strict";Es();o(wwe,"tweenRemove");o(Twe,"tweenFunction");o(U8,"default");o(D0,"tweenValue")});function xv(t,e){var r;return(typeof e=="number"?Ki:e instanceof pl?ud:(r=pl(e))?(e=r,ud):C0)(t,e)}var H8=N(()=>{"use strict";E0();A0();o(xv,"default")});function kwe(t){return function(){this.removeAttribute(t)}}function Ewe(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Swe(t,e,r){var n,i=r+"",a;return function(){var s=this.getAttribute(t);return s===i?null:s===n?a:a=e(n=s,r)}}function Cwe(t,e,r){var n,i=r+"",a;return function(){var s=this.getAttributeNS(t.space,t.local);return s===i?null:s===n?a:a=e(n=s,r)}}function Awe(t,e,r){var n,i,a;return function(){var s,l=r(this),u;return l==null?void this.removeAttribute(t):(s=this.getAttribute(t),u=l+"",s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l)))}}function _we(t,e,r){var n,i,a;return function(){var s,l=r(this),u;return l==null?void this.removeAttributeNS(t.space,t.local):(s=this.getAttributeNS(t.space,t.local),u=l+"",s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l)))}}function W8(t,e){var r=rc(t),n=r==="transform"?F8:xv;return this.attrTween(t,typeof e=="function"?(r.local?_we:Awe)(r,n,D0(this,"attr."+t,e)):e==null?(r.local?Ewe:kwe)(r):(r.local?Cwe:Swe)(r,n,e))}var KU=N(()=>{"use strict";A0();fl();vv();H8();o(kwe,"attrRemove");o(Ewe,"attrRemoveNS");o(Swe,"attrConstant");o(Cwe,"attrConstantNS");o(Awe,"attrFunction");o(_we,"attrFunctionNS");o(W8,"default")});function Dwe(t,e){return function(r){this.setAttribute(t,e.call(this,r))}}function Lwe(t,e){return function(r){this.setAttributeNS(t.space,t.local,e.call(this,r))}}function Rwe(t,e){var r,n;function i(){var a=e.apply(this,arguments);return a!==n&&(r=(n=a)&&Lwe(t,a)),r}return o(i,"tween"),i._value=e,i}function Nwe(t,e){var r,n;function i(){var a=e.apply(this,arguments);return a!==n&&(r=(n=a)&&Dwe(t,a)),r}return o(i,"tween"),i._value=e,i}function q8(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if(e==null)return this.tween(r,null);if(typeof e!="function")throw new Error;var n=rc(t);return this.tween(r,(n.local?Rwe:Nwe)(n,e))}var QU=N(()=>{"use strict";fl();o(Dwe,"attrInterpolate");o(Lwe,"attrInterpolateNS");o(Rwe,"attrTweenNS");o(Nwe,"attrTween");o(q8,"default")});function Mwe(t,e){return function(){gv(this,t).delay=+e.apply(this,arguments)}}function Iwe(t,e){return e=+e,function(){gv(this,t).delay=e}}function Y8(t){var e=this._id;return arguments.length?this.each((typeof t=="function"?Mwe:Iwe)(e,t)):Bi(this.node(),e).delay}var ZU=N(()=>{"use strict";Es();o(Mwe,"delayFunction");o(Iwe,"delayConstant");o(Y8,"default")});function Owe(t,e){return function(){ha(this,t).duration=+e.apply(this,arguments)}}function Pwe(t,e){return e=+e,function(){ha(this,t).duration=e}}function X8(t){var e=this._id;return arguments.length?this.each((typeof t=="function"?Owe:Pwe)(e,t)):Bi(this.node(),e).duration}var JU=N(()=>{"use strict";Es();o(Owe,"durationFunction");o(Pwe,"durationConstant");o(X8,"default")});function Bwe(t,e){if(typeof e!="function")throw new Error;return function(){ha(this,t).ease=e}}function j8(t){var e=this._id;return arguments.length?this.each(Bwe(e,t)):Bi(this.node(),e).ease}var eH=N(()=>{"use strict";Es();o(Bwe,"easeConstant");o(j8,"default")});function Fwe(t,e){return function(){var r=e.apply(this,arguments);if(typeof r!="function")throw new Error;ha(this,t).ease=r}}function K8(t){if(typeof t!="function")throw new Error;return this.each(Fwe(this._id,t))}var tH=N(()=>{"use strict";Es();o(Fwe,"easeVarying");o(K8,"default")});function Q8(t){typeof t!="function"&&(t=x0(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i<r;++i)for(var a=e[i],s=a.length,l=n[i]=[],u,h=0;h<s;++h)(u=a[h])&&t.call(u,u.__data__,h,a)&&l.push(u);return new es(n,this._parents,this._name,this._id)}var rH=N(()=>{"use strict";fl();fd();o(Q8,"default")});function Z8(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,r=t._groups,n=e.length,i=r.length,a=Math.min(n,i),s=new Array(n),l=0;l<a;++l)for(var u=e[l],h=r[l],f=u.length,d=s[l]=new Array(f),p,m=0;m<f;++m)(p=u[m]||h[m])&&(d[m]=p);for(;l<n;++l)s[l]=e[l];return new es(s,this._parents,this._name,this._id)}var nH=N(()=>{"use strict";fd();o(Z8,"default")});function $we(t){return(t+"").trim().split(/^|\s+/).every(function(e){var r=e.indexOf(".");return r>=0&&(e=e.slice(0,r)),!e||e==="start"})}function zwe(t,e,r){var n,i,a=$we(e)?gv:ha;return function(){var s=a(this,t),l=s.on;l!==n&&(i=(n=l).copy()).on(e,r),s.on=i}}function J8(t,e){var r=this._id;return arguments.length<2?Bi(this.node(),r).on.on(t):this.each(zwe(r,t,e))}var iH=N(()=>{"use strict";Es();o($we,"start");o(zwe,"onFunction");o(J8,"default")});function Gwe(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}function e_(){return this.on("end.remove",Gwe(this._id))}var aH=N(()=>{"use strict";o(Gwe,"removeFunction");o(e_,"default")});function t_(t){var e=this._name,r=this._id;typeof t!="function"&&(t=xh(t));for(var n=this._groups,i=n.length,a=new Array(i),s=0;s<i;++s)for(var l=n[s],u=l.length,h=a[s]=new Array(u),f,d,p=0;p<u;++p)(f=l[p])&&(d=t.call(f,f.__data__,p,l))&&("__data__"in f&&(d.__data__=f.__data__),h[p]=d,pu(h[p],e,r,p,h,Bi(f,r)));return new es(a,this._parents,e,r)}var sH=N(()=>{"use strict";fl();fd();Es();o(t_,"default")});function r_(t){var e=this._name,r=this._id;typeof t!="function"&&(t=v0(t));for(var n=this._groups,i=n.length,a=[],s=[],l=0;l<i;++l)for(var u=n[l],h=u.length,f,d=0;d<h;++d)if(f=u[d]){for(var p=t.call(f,f.__data__,d,u),m,g=Bi(f,r),y=0,v=p.length;y<v;++y)(m=p[y])&&pu(m,e,r,y,p,g);a.push(p),s.push(f)}return new es(a,s,e,r)}var oH=N(()=>{"use strict";fl();fd();Es();o(r_,"default")});function n_(){return new Vwe(this._groups,this._parents)}var Vwe,lH=N(()=>{"use strict";fl();Vwe=hu.prototype.constructor;o(n_,"default")});function Uwe(t,e){var r,n,i;return function(){var a=bh(this,t),s=(this.style.removeProperty(t),bh(this,t));return a===s?null:a===r&&s===n?i:i=e(r=a,n=s)}}function cH(t){return function(){this.style.removeProperty(t)}}function Hwe(t,e,r){var n,i=r+"",a;return function(){var s=bh(this,t);return s===i?null:s===n?a:a=e(n=s,r)}}function Wwe(t,e,r){var n,i,a;return function(){var s=bh(this,t),l=r(this),u=l+"";return l==null&&(u=l=(this.style.removeProperty(t),bh(this,t))),s===u?null:s===n&&u===i?a:(i=u,a=e(n=s,l))}}function qwe(t,e){var r,n,i,a="style."+e,s="end."+a,l;return function(){var u=ha(this,t),h=u.on,f=u.value[a]==null?l||(l=cH(e)):void 0;(h!==r||i!==f)&&(n=(r=h).copy()).on(s,i=f),u.on=n}}function i_(t,e,r){var n=(t+="")=="transform"?B8:xv;return e==null?this.styleTween(t,Uwe(t,n)).on("end.style."+t,cH(t)):typeof e=="function"?this.styleTween(t,Wwe(t,n,D0(this,"style."+t,e))).each(qwe(this._id,t)):this.styleTween(t,Hwe(t,n,e),r).on("end.style."+t,null)}var uH=N(()=>{"use strict";A0();fl();Es();vv();H8();o(Uwe,"styleNull");o(cH,"styleRemove");o(Hwe,"styleConstant");o(Wwe,"styleFunction");o(qwe,"styleMaybeRemove");o(i_,"default")});function Ywe(t,e,r){return function(n){this.style.setProperty(t,e.call(this,n),r)}}function Xwe(t,e,r){var n,i;function a(){var s=e.apply(this,arguments);return s!==i&&(n=(i=s)&&Ywe(t,s,r)),n}return o(a,"tween"),a._value=e,a}function a_(t,e,r){var n="style."+(t+="");if(arguments.length<2)return(n=this.tween(n))&&n._value;if(e==null)return this.tween(n,null);if(typeof e!="function")throw new Error;return this.tween(n,Xwe(t,e,r??""))}var hH=N(()=>{"use strict";o(Ywe,"styleInterpolate");o(Xwe,"styleTween");o(a_,"default")});function jwe(t){return function(){this.textContent=t}}function Kwe(t){return function(){var e=t(this);this.textContent=e??""}}function s_(t){return this.tween("text",typeof t=="function"?Kwe(D0(this,"text",t)):jwe(t==null?"":t+""))}var fH=N(()=>{"use strict";vv();o(jwe,"textConstant");o(Kwe,"textFunction");o(s_,"default")});function Qwe(t){return function(e){this.textContent=t.call(this,e)}}function Zwe(t){var e,r;function n(){var i=t.apply(this,arguments);return i!==r&&(e=(r=i)&&Qwe(i)),e}return o(n,"tween"),n._value=t,n}function o_(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(t==null)return this.tween(e,null);if(typeof t!="function")throw new Error;return this.tween(e,Zwe(t))}var dH=N(()=>{"use strict";o(Qwe,"textInterpolate");o(Zwe,"textTween");o(o_,"default")});function l_(){for(var t=this._name,e=this._id,r=s5(),n=this._groups,i=n.length,a=0;a<i;++a)for(var s=n[a],l=s.length,u,h=0;h<l;++h)if(u=s[h]){var f=Bi(u,e);pu(u,t,r,h,s,{time:f.time+f.delay+f.duration,delay:0,duration:f.duration,ease:f.ease})}return new es(n,this._parents,t,r)}var pH=N(()=>{"use strict";fd();Es();o(l_,"default")});function c_(){var t,e,r=this,n=r._id,i=r.size();return new Promise(function(a,s){var l={value:s},u={value:o(function(){--i===0&&a()},"value")};r.each(function(){var h=ha(this,n),f=h.on;f!==t&&(e=(t=f).copy(),e._.cancel.push(l),e._.interrupt.push(l),e._.end.push(u)),h.on=e}),i===0&&a()})}var mH=N(()=>{"use strict";Es();o(c_,"default")});function es(t,e,r,n){this._groups=t,this._parents=e,this._name=r,this._id=n}function gH(t){return hu().transition(t)}function s5(){return++Jwe}var Jwe,mu,fd=N(()=>{"use strict";fl();KU();QU();ZU();JU();eH();tH();rH();nH();iH();aH();sH();oH();lH();uH();hH();fH();dH();pH();vv();mH();Jwe=0;o(es,"Transition");o(gH,"transition");o(s5,"newId");mu=hu.prototype;es.prototype=gH.prototype={constructor:es,select:t_,selectAll:r_,selectChild:mu.selectChild,selectChildren:mu.selectChildren,filter:Q8,merge:Z8,selection:n_,transition:l_,call:mu.call,nodes:mu.nodes,node:mu.node,size:mu.size,empty:mu.empty,each:mu.each,on:J8,attr:W8,attrTween:q8,style:i_,styleTween:a_,text:s_,textTween:o_,remove:e_,tween:U8,delay:Y8,duration:X8,ease:j8,easeVarying:K8,end:c_,[Symbol.iterator]:mu[Symbol.iterator]}});function o5(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}var yH=N(()=>{"use strict";o(o5,"cubicInOut")});var u_=N(()=>{"use strict";yH()});function tTe(t,e){for(var r;!(r=t.__transition)||!(r=r[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return r}function h_(t){var e,r;t instanceof es?(e=t._id,t=t._name):(e=s5(),(r=eTe).time=dv(),t=t==null?null:t+"");for(var n=this._groups,i=n.length,a=0;a<i;++a)for(var s=n[a],l=s.length,u,h=0;h<l;++h)(u=s[h])&&pu(u,t,e,h,s,r||tTe(u,e));return new es(n,this._parents,t,e)}var eTe,vH=N(()=>{"use strict";fd();Es();u_();r5();eTe={time:null,delay:0,duration:250,ease:o5};o(tTe,"inherit");o(h_,"default")});var xH=N(()=>{"use strict";fl();jU();vH();hu.prototype.interrupt=V8;hu.prototype.transition=h_});var l5=N(()=>{"use strict";xH()});var bH=N(()=>{"use strict"});var wH=N(()=>{"use strict"});var TH=N(()=>{"use strict"});function kH(t){return[+t[0],+t[1]]}function rTe(t){return[kH(t[0]),kH(t[1])]}function f_(t){return{type:t}}var Z0t,J0t,emt,tmt,rmt,nmt,EH=N(()=>{"use strict";l5();bH();wH();TH();({abs:Z0t,max:J0t,min:emt}=Math);o(kH,"number1");o(rTe,"number2");tmt={name:"x",handles:["w","e"].map(f_),input:o(function(t,e){return t==null?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},"input"),output:o(function(t){return t&&[t[0][0],t[1][0]]},"output")},rmt={name:"y",handles:["n","s"].map(f_),input:o(function(t,e){return t==null?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},"input"),output:o(function(t){return t&&[t[0][1],t[1][1]]},"output")},nmt={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(f_),input:o(function(t){return t==null?null:rTe(t)},"input"),output:o(function(t){return t},"output")};o(f_,"type")});var SH=N(()=>{"use strict";EH()});function CH(t){this._+=t[0];for(let e=1,r=t.length;e<r;++e)this._+=arguments[e]+t[e]}function iTe(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return CH;let r=10**e;return function(n){this._+=n[0];for(let i=1,a=n.length;i<a;++i)this._+=Math.round(arguments[i]*r)/r+n[i]}}function AH(){return new pd}var d_,p_,dd,nTe,pd,_H=N(()=>{"use strict";d_=Math.PI,p_=2*d_,dd=1e-6,nTe=p_-dd;o(CH,"append");o(iTe,"appendRound");pd=class{static{o(this,"Path")}constructor(e){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=e==null?CH:iTe(e)}moveTo(e,r){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(e,r){this._append`L${this._x1=+e},${this._y1=+r}`}quadraticCurveTo(e,r,n,i){this._append`Q${+e},${+r},${this._x1=+n},${this._y1=+i}`}bezierCurveTo(e,r,n,i,a,s){this._append`C${+e},${+r},${+n},${+i},${this._x1=+a},${this._y1=+s}`}arcTo(e,r,n,i,a){if(e=+e,r=+r,n=+n,i=+i,a=+a,a<0)throw new Error(`negative radius: ${a}`);let s=this._x1,l=this._y1,u=n-e,h=i-r,f=s-e,d=l-r,p=f*f+d*d;if(this._x1===null)this._append`M${this._x1=e},${this._y1=r}`;else if(p>dd)if(!(Math.abs(d*u-h*f)>dd)||!a)this._append`L${this._x1=e},${this._y1=r}`;else{let m=n-s,g=i-l,y=u*u+h*h,v=m*m+g*g,x=Math.sqrt(y),b=Math.sqrt(p),w=a*Math.tan((d_-Math.acos((y+p-v)/(2*x*b)))/2),C=w/b,T=w/x;Math.abs(C-1)>dd&&this._append`L${e+C*f},${r+C*d}`,this._append`A${a},${a},0,0,${+(d*m>f*g)},${this._x1=e+T*u},${this._y1=r+T*h}`}}arc(e,r,n,i,a,s){if(e=+e,r=+r,n=+n,s=!!s,n<0)throw new Error(`negative radius: ${n}`);let l=n*Math.cos(i),u=n*Math.sin(i),h=e+l,f=r+u,d=1^s,p=s?i-a:a-i;this._x1===null?this._append`M${h},${f}`:(Math.abs(this._x1-h)>dd||Math.abs(this._y1-f)>dd)&&this._append`L${h},${f}`,n&&(p<0&&(p=p%p_+p_),p>nTe?this._append`A${n},${n},0,1,${d},${e-l},${r-u}A${n},${n},0,1,${d},${this._x1=h},${this._y1=f}`:p>dd&&this._append`A${n},${n},0,${+(p>=d_)},${d},${this._x1=e+n*Math.cos(a)},${this._y1=r+n*Math.sin(a)}`)}rect(e,r,n,i){this._append`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}h${n=+n}v${+i}h${-n}Z`}toString(){return this._}};o(AH,"path");AH.prototype=pd.prototype});var m_=N(()=>{"use strict";_H()});var DH=N(()=>{"use strict"});var LH=N(()=>{"use strict"});var RH=N(()=>{"use strict"});var NH=N(()=>{"use strict"});var MH=N(()=>{"use strict"});var IH=N(()=>{"use strict"});var OH=N(()=>{"use strict"});function g_(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function md(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}var bv=N(()=>{"use strict";o(g_,"default");o(md,"formatDecimalParts")});function ml(t){return t=md(Math.abs(t)),t?t[1]:NaN}var wv=N(()=>{"use strict";bv();o(ml,"default")});function y_(t,e){return function(r,n){for(var i=r.length,a=[],s=0,l=t[0],u=0;i>0&&l>0&&(u+l+1>n&&(l=Math.max(1,n-u)),a.push(r.substring(i-=l,i+l)),!((u+=l+1)>n));)l=t[s=(s+1)%t.length];return a.reverse().join(e)}}var PH=N(()=>{"use strict";o(y_,"default")});function v_(t){return function(e){return e.replace(/[0-9]/g,function(r){return t[+r]})}}var BH=N(()=>{"use strict";o(v_,"default")});function Eh(t){if(!(e=aTe.exec(t)))throw new Error("invalid format: "+t);var e;return new c5({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function c5(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+""}var aTe,x_=N(()=>{"use strict";aTe=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;o(Eh,"formatSpecifier");Eh.prototype=c5.prototype;o(c5,"FormatSpecifier");c5.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type}});function b_(t){e:for(var e=t.length,r=1,n=-1,i;r<e;++r)switch(t[r]){case".":n=i=r;break;case"0":n===0&&(n=r),i=r;break;default:if(!+t[r])break e;n>0&&(n=0);break}return n>0?t.slice(0,n)+t.slice(i+1):t}var FH=N(()=>{"use strict";o(b_,"default")});function T_(t,e){var r=md(t,e);if(!r)return t+"";var n=r[0],i=r[1],a=i-(w_=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=n.length;return a===s?n:a>s?n+new Array(a-s+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+md(t,Math.max(0,e+a-1))[0]}var w_,k_=N(()=>{"use strict";bv();o(T_,"default")});function u5(t,e){var r=md(t,e);if(!r)return t+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}var $H=N(()=>{"use strict";bv();o(u5,"default")});var E_,zH=N(()=>{"use strict";bv();k_();$H();E_={"%":o((t,e)=>(t*100).toFixed(e),"%"),b:o(t=>Math.round(t).toString(2),"b"),c:o(t=>t+"","c"),d:g_,e:o((t,e)=>t.toExponential(e),"e"),f:o((t,e)=>t.toFixed(e),"f"),g:o((t,e)=>t.toPrecision(e),"g"),o:o(t=>Math.round(t).toString(8),"o"),p:o((t,e)=>u5(t*100,e),"p"),r:u5,s:T_,X:o(t=>Math.round(t).toString(16).toUpperCase(),"X"),x:o(t=>Math.round(t).toString(16),"x")}});function h5(t){return t}var GH=N(()=>{"use strict";o(h5,"default")});function S_(t){var e=t.grouping===void 0||t.thousands===void 0?h5:y_(VH.call(t.grouping,Number),t.thousands+""),r=t.currency===void 0?"":t.currency[0]+"",n=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?h5:v_(VH.call(t.numerals,String)),s=t.percent===void 0?"%":t.percent+"",l=t.minus===void 0?"\u2212":t.minus+"",u=t.nan===void 0?"NaN":t.nan+"";function h(d){d=Eh(d);var p=d.fill,m=d.align,g=d.sign,y=d.symbol,v=d.zero,x=d.width,b=d.comma,w=d.precision,C=d.trim,T=d.type;T==="n"?(b=!0,T="g"):E_[T]||(w===void 0&&(w=12),C=!0,T="g"),(v||p==="0"&&m==="=")&&(v=!0,p="0",m="=");var E=y==="$"?r:y==="#"&&/[boxX]/.test(T)?"0"+T.toLowerCase():"",A=y==="$"?n:/[%p]/.test(T)?s:"",S=E_[T],_=/[defgprs%]/.test(T);w=w===void 0?6:/[gprs]/.test(T)?Math.max(1,Math.min(21,w)):Math.max(0,Math.min(20,w));function I(D){var k=E,L=A,R,O,M;if(T==="c")L=S(D)+L,D="";else{D=+D;var B=D<0||1/D<0;if(D=isNaN(D)?u:S(Math.abs(D),w),C&&(D=b_(D)),B&&+D==0&&g!=="+"&&(B=!1),k=(B?g==="("?g:l:g==="-"||g==="("?"":g)+k,L=(T==="s"?UH[8+w_/3]:"")+L+(B&&g==="("?")":""),_){for(R=-1,O=D.length;++R<O;)if(M=D.charCodeAt(R),48>M||M>57){L=(M===46?i+D.slice(R+1):D.slice(R))+L,D=D.slice(0,R);break}}}b&&!v&&(D=e(D,1/0));var F=k.length+D.length+L.length,P=F<x?new Array(x-F+1).join(p):"";switch(b&&v&&(D=e(P+D,P.length?x-L.length:1/0),P=""),m){case"<":D=k+D+L+P;break;case"=":D=k+P+D+L;break;case"^":D=P.slice(0,F=P.length>>1)+k+D+L+P.slice(F);break;default:D=P+k+D+L;break}return a(D)}return o(I,"format"),I.toString=function(){return d+""},I}o(h,"newFormat");function f(d,p){var m=h((d=Eh(d),d.type="f",d)),g=Math.max(-8,Math.min(8,Math.floor(ml(p)/3)))*3,y=Math.pow(10,-g),v=UH[8+g/3];return function(x){return m(y*x)+v}}return o(f,"formatPrefix"),{format:h,formatPrefix:f}}var VH,UH,HH=N(()=>{"use strict";wv();PH();BH();x_();FH();zH();k_();GH();VH=Array.prototype.map,UH=["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"];o(S_,"default")});function C_(t){return f5=S_(t),d5=f5.format,p5=f5.formatPrefix,f5}var f5,d5,p5,WH=N(()=>{"use strict";HH();C_({thousands:",",grouping:[3],currency:["$",""]});o(C_,"defaultLocale")});function m5(t){return Math.max(0,-ml(Math.abs(t)))}var qH=N(()=>{"use strict";wv();o(m5,"default")});function g5(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(ml(e)/3)))*3-ml(Math.abs(t)))}var YH=N(()=>{"use strict";wv();o(g5,"default")});function y5(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,ml(e)-ml(t))+1}var XH=N(()=>{"use strict";wv();o(y5,"default")});var A_=N(()=>{"use strict";WH();x_();qH();YH();XH()});var jH=N(()=>{"use strict"});var KH=N(()=>{"use strict"});var QH=N(()=>{"use strict"});var ZH=N(()=>{"use strict"});function Sh(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}var Tv=N(()=>{"use strict";o(Sh,"initRange")});function gu(){var t=new g0,e=[],r=[],n=__;function i(a){let s=t.get(a);if(s===void 0){if(n!==__)return n;t.set(a,s=e.push(a)-1)}return r[s%r.length]}return o(i,"scale"),i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new g0;for(let s of a)t.has(s)||t.set(s,e.push(s)-1);return i},i.range=function(a){return arguments.length?(r=Array.from(a),i):r.slice()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return gu(e,r).unknown(n)},Sh.apply(i,arguments),i}var __,D_=N(()=>{"use strict";vh();Tv();__=Symbol("implicit");o(gu,"ordinal")});function L0(){var t=gu().unknown(void 0),e=t.domain,r=t.range,n=0,i=1,a,s,l=!1,u=0,h=0,f=.5;delete t.unknown;function d(){var p=e().length,m=i<n,g=m?i:n,y=m?n:i;a=(y-g)/Math.max(1,p-u+h*2),l&&(a=Math.floor(a)),g+=(y-g-a*(p-u))*f,s=a*(1-u),l&&(g=Math.round(g),s=Math.round(s));var v=I3(p).map(function(x){return g+a*x});return r(m?v.reverse():v)}return o(d,"rescale"),t.domain=function(p){return arguments.length?(e(p),d()):e()},t.range=function(p){return arguments.length?([n,i]=p,n=+n,i=+i,d()):[n,i]},t.rangeRound=function(p){return[n,i]=p,n=+n,i=+i,l=!0,d()},t.bandwidth=function(){return s},t.step=function(){return a},t.round=function(p){return arguments.length?(l=!!p,d()):l},t.padding=function(p){return arguments.length?(u=Math.min(1,h=+p),d()):u},t.paddingInner=function(p){return arguments.length?(u=Math.min(1,p),d()):u},t.paddingOuter=function(p){return arguments.length?(h=+p,d()):h},t.align=function(p){return arguments.length?(f=Math.max(0,Math.min(1,p)),d()):f},t.copy=function(){return L0(e(),[n,i]).round(l).paddingInner(u).paddingOuter(h).align(f)},Sh.apply(d(),arguments)}var JH=N(()=>{"use strict";vh();Tv();D_();o(L0,"band")});function L_(t){return function(){return t}}var eW=N(()=>{"use strict";o(L_,"constants")});function R_(t){return+t}var tW=N(()=>{"use strict";o(R_,"number")});function R0(t){return t}function N_(t,e){return(e-=t=+t)?function(r){return(r-t)/e}:L_(isNaN(e)?NaN:.5)}function sTe(t,e){var r;return t>e&&(r=t,t=e,e=r),function(n){return Math.max(t,Math.min(e,n))}}function oTe(t,e,r){var n=t[0],i=t[1],a=e[0],s=e[1];return i<n?(n=N_(i,n),a=r(s,a)):(n=N_(n,i),a=r(a,s)),function(l){return a(n(l))}}function lTe(t,e,r){var n=Math.min(t.length,e.length)-1,i=new Array(n),a=new Array(n),s=-1;for(t[n]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++s<n;)i[s]=N_(t[s],t[s+1]),a[s]=r(e[s],e[s+1]);return function(l){var u=mA(t,l,1,n)-1;return a[u](i[u](l))}}function v5(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function cTe(){var t=rW,e=rW,r=kh,n,i,a,s=R0,l,u,h;function f(){var p=Math.min(t.length,e.length);return s!==R0&&(s=sTe(t[0],t[p-1])),l=p>2?lTe:oTe,u=h=null,d}o(f,"rescale");function d(p){return p==null||isNaN(p=+p)?a:(u||(u=l(t.map(n),e,r)))(n(s(p)))}return o(d,"scale"),d.invert=function(p){return s(i((h||(h=l(e,t.map(n),Ki)))(p)))},d.domain=function(p){return arguments.length?(t=Array.from(p,R_),f()):t.slice()},d.range=function(p){return arguments.length?(e=Array.from(p),f()):e.slice()},d.rangeRound=function(p){return e=Array.from(p),r=X3,f()},d.clamp=function(p){return arguments.length?(s=p?!0:R0,f()):s!==R0},d.interpolate=function(p){return arguments.length?(r=p,f()):r},d.unknown=function(p){return arguments.length?(a=p,d):a},function(p,m){return n=p,i=m,f()}}function kv(){return cTe()(R0,R0)}var rW,M_=N(()=>{"use strict";vh();A0();eW();tW();rW=[0,1];o(R0,"identity");o(N_,"normalize");o(sTe,"clamper");o(oTe,"bimap");o(lTe,"polymap");o(v5,"copy");o(cTe,"transformer");o(kv,"continuous")});function I_(t,e,r,n){var i=y0(t,e,r),a;switch(n=Eh(n??",f"),n.type){case"s":{var s=Math.max(Math.abs(t),Math.abs(e));return n.precision==null&&!isNaN(a=g5(i,s))&&(n.precision=a),p5(n,s)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=y5(i,Math.max(Math.abs(t),Math.abs(e))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=m5(i))&&(n.precision=a-(n.type==="%")*2);break}}return d5(n)}var nW=N(()=>{"use strict";vh();A_();o(I_,"tickFormat")});function uTe(t){var e=t.domain;return t.ticks=function(r){var n=e();return R3(n[0],n[n.length-1],r??10)},t.tickFormat=function(r,n){var i=e();return I_(i[0],i[i.length-1],r??10,n)},t.nice=function(r){r==null&&(r=10);var n=e(),i=0,a=n.length-1,s=n[i],l=n[a],u,h,f=10;for(l<s&&(h=s,s=l,l=h,h=i,i=a,a=h);f-- >0;){if(h=Zy(s,l,r),h===u)return n[i]=s,n[a]=l,e(n);if(h>0)s=Math.floor(s/h)*h,l=Math.ceil(l/h)*h;else if(h<0)s=Math.ceil(s*h)/h,l=Math.floor(l*h)/h;else break;u=h}return t},t}function gl(){var t=kv();return t.copy=function(){return v5(t,gl())},Sh.apply(t,arguments),uTe(t)}var iW=N(()=>{"use strict";vh();M_();Tv();nW();o(uTe,"linearish");o(gl,"linear")});function O_(t,e){t=t.slice();var r=0,n=t.length-1,i=t[r],a=t[n],s;return a<i&&(s=r,r=n,n=s,s=i,i=a,a=s),t[r]=e.floor(i),t[n]=e.ceil(a),t}var aW=N(()=>{"use strict";o(O_,"nice")});function xn(t,e,r,n){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return o(i,"interval"),i.floor=a=>(t(a=new Date(+a)),a),i.ceil=a=>(t(a=new Date(a-1)),e(a,1),t(a),a),i.round=a=>{let s=i(a),l=i.ceil(a);return a-s<l-a?s:l},i.offset=(a,s)=>(e(a=new Date(+a),s==null?1:Math.floor(s)),a),i.range=(a,s,l)=>{let u=[];if(a=i.ceil(a),l=l==null?1:Math.floor(l),!(a<s)||!(l>0))return u;let h;do u.push(h=new Date(+a)),e(a,l),t(a);while(h<a&&a<s);return u},i.filter=a=>xn(s=>{if(s>=s)for(;t(s),!a(s);)s.setTime(s-1)},(s,l)=>{if(s>=s)if(l<0)for(;++l<=0;)for(;e(s,-1),!a(s););else for(;--l>=0;)for(;e(s,1),!a(s););}),r&&(i.count=(a,s)=>(P_.setTime(+a),B_.setTime(+s),t(P_),t(B_),Math.floor(r(P_,B_))),i.every=a=>(a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?s=>n(s)%a===0:s=>i.count(0,s)%a===0):i)),i}var P_,B_,yu=N(()=>{"use strict";P_=new Date,B_=new Date;o(xn,"timeInterval")});var ac,sW,F_=N(()=>{"use strict";yu();ac=xn(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);ac.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?xn(e=>{e.setTime(Math.floor(e/t)*t)},(e,r)=>{e.setTime(+e+r*t)},(e,r)=>(r-e)/t):ac);sW=ac.range});var Ks,oW,$_=N(()=>{"use strict";yu();Ks=xn(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*1e3)},(t,e)=>(e-t)/1e3,t=>t.getUTCSeconds()),oW=Ks.range});var vu,hTe,x5,fTe,z_=N(()=>{"use strict";yu();vu=xn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*1e3)},(t,e)=>{t.setTime(+t+e*6e4)},(t,e)=>(e-t)/6e4,t=>t.getMinutes()),hTe=vu.range,x5=xn(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*6e4)},(t,e)=>(e-t)/6e4,t=>t.getUTCMinutes()),fTe=x5.range});var xu,dTe,b5,pTe,G_=N(()=>{"use strict";yu();xu=xn(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*1e3-t.getMinutes()*6e4)},(t,e)=>{t.setTime(+t+e*36e5)},(t,e)=>(e-t)/36e5,t=>t.getHours()),dTe=xu.range,b5=xn(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*36e5)},(t,e)=>(e-t)/36e5,t=>t.getUTCHours()),pTe=b5.range});var _o,mTe,Sv,gTe,w5,yTe,V_=N(()=>{"use strict";yu();_o=xn(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5,t=>t.getDate()-1),mTe=_o.range,Sv=xn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>t.getUTCDate()-1),gTe=Sv.range,w5=xn(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/864e5,t=>Math.floor(t/864e5)),yTe=w5.range});function vd(t){return xn(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,r)=>{e.setDate(e.getDate()+r*7)},(e,r)=>(r-e-(r.getTimezoneOffset()-e.getTimezoneOffset())*6e4)/6048e5)}function xd(t){return xn(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCDate(e.getUTCDate()+r*7)},(e,r)=>(r-e)/6048e5)}var yl,Ch,T5,k5,oc,E5,S5,cW,vTe,xTe,bTe,wTe,TTe,kTe,bd,N0,uW,hW,Ah,fW,dW,pW,ETe,STe,CTe,ATe,_Te,DTe,U_=N(()=>{"use strict";yu();o(vd,"timeWeekday");yl=vd(0),Ch=vd(1),T5=vd(2),k5=vd(3),oc=vd(4),E5=vd(5),S5=vd(6),cW=yl.range,vTe=Ch.range,xTe=T5.range,bTe=k5.range,wTe=oc.range,TTe=E5.range,kTe=S5.range;o(xd,"utcWeekday");bd=xd(0),N0=xd(1),uW=xd(2),hW=xd(3),Ah=xd(4),fW=xd(5),dW=xd(6),pW=bd.range,ETe=N0.range,STe=uW.range,CTe=hW.range,ATe=Ah.range,_Te=fW.range,DTe=dW.range});var bu,LTe,C5,RTe,H_=N(()=>{"use strict";yu();bu=xn(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth()),LTe=bu.range,C5=xn(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth()),RTe=C5.range});var Qs,NTe,vl,MTe,W_=N(()=>{"use strict";yu();Qs=xn(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());Qs.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:xn(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,r)=>{e.setFullYear(e.getFullYear()+r*t)});NTe=Qs.range,vl=xn(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());vl.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:xn(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)});MTe=vl.range});function gW(t,e,r,n,i,a){let s=[[Ks,1,1e3],[Ks,5,5*1e3],[Ks,15,15*1e3],[Ks,30,30*1e3],[a,1,6e4],[a,5,5*6e4],[a,15,15*6e4],[a,30,30*6e4],[i,1,36e5],[i,3,3*36e5],[i,6,6*36e5],[i,12,12*36e5],[n,1,864e5],[n,2,2*864e5],[r,1,6048e5],[e,1,2592e6],[e,3,3*2592e6],[t,1,31536e6]];function l(h,f,d){let p=f<h;p&&([h,f]=[f,h]);let m=d&&typeof d.range=="function"?d:u(h,f,d),g=m?m.range(h,+f+1):[];return p?g.reverse():g}o(l,"ticks");function u(h,f,d){let p=Math.abs(f-h)/d,m=od(([,,v])=>v).right(s,p);if(m===s.length)return t.every(y0(h/31536e6,f/31536e6,d));if(m===0)return ac.every(Math.max(y0(h,f,d),1));let[g,y]=s[p/s[m-1][2]<s[m][2]/p?m-1:m];return g.every(y)}return o(u,"tickInterval"),[l,u]}var OTe,PTe,q_,Y_,yW=N(()=>{"use strict";vh();F_();$_();z_();G_();V_();U_();H_();W_();o(gW,"ticker");[OTe,PTe]=gW(vl,C5,bd,w5,b5,x5),[q_,Y_]=gW(Qs,bu,yl,_o,xu,vu)});var A5=N(()=>{"use strict";F_();$_();z_();G_();V_();U_();H_();W_();yW()});function X_(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function j_(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Cv(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}function K_(t){var e=t.dateTime,r=t.date,n=t.time,i=t.periods,a=t.days,s=t.shortDays,l=t.months,u=t.shortMonths,h=Av(i),f=_v(i),d=Av(a),p=_v(a),m=Av(s),g=_v(s),y=Av(l),v=_v(l),x=Av(u),b=_v(u),w={a:B,A:F,b:P,B:z,c:null,d:kW,e:kW,f:ake,g:mke,G:yke,H:rke,I:nke,j:ike,L:_W,m:ske,M:oke,p:$,q:H,Q:CW,s:AW,S:lke,u:cke,U:uke,V:hke,w:fke,W:dke,x:null,X:null,y:pke,Y:gke,Z:vke,"%":SW},C={a:Q,A:j,b:ie,B:ne,c:null,d:EW,e:EW,f:Tke,g:Nke,G:Ike,H:xke,I:bke,j:wke,L:LW,m:kke,M:Eke,p:le,q:he,Q:CW,s:AW,S:Ske,u:Cke,U:Ake,V:_ke,w:Dke,W:Lke,x:null,X:null,y:Rke,Y:Mke,Z:Oke,"%":SW},T={a:I,A:D,b:k,B:L,c:R,d:wW,e:wW,f:ZTe,g:bW,G:xW,H:TW,I:TW,j:XTe,L:QTe,m:YTe,M:jTe,p:_,q:qTe,Q:eke,s:tke,S:KTe,u:GTe,U:VTe,V:UTe,w:zTe,W:HTe,x:O,X:M,y:bW,Y:xW,Z:WTe,"%":JTe};w.x=E(r,w),w.X=E(n,w),w.c=E(e,w),C.x=E(r,C),C.X=E(n,C),C.c=E(e,C);function E(K,X){return function(te){var J=[],se=-1,ue=0,Z=K.length,Se,ce,ae;for(te instanceof Date||(te=new Date(+te));++se<Z;)K.charCodeAt(se)===37&&(J.push(K.slice(ue,se)),(ce=vW[Se=K.charAt(++se)])!=null?Se=K.charAt(++se):ce=Se==="e"?" ":"0",(ae=X[Se])&&(Se=ae(te,ce)),J.push(Se),ue=se+1);return J.push(K.slice(ue,se)),J.join("")}}o(E,"newFormat");function A(K,X){return function(te){var J=Cv(1900,void 0,1),se=S(J,K,te+="",0),ue,Z;if(se!=te.length)return null;if("Q"in J)return new Date(J.Q);if("s"in J)return new Date(J.s*1e3+("L"in J?J.L:0));if(X&&!("Z"in J)&&(J.Z=0),"p"in J&&(J.H=J.H%12+J.p*12),J.m===void 0&&(J.m="q"in J?J.q:0),"V"in J){if(J.V<1||J.V>53)return null;"w"in J||(J.w=1),"Z"in J?(ue=j_(Cv(J.y,0,1)),Z=ue.getUTCDay(),ue=Z>4||Z===0?N0.ceil(ue):N0(ue),ue=Sv.offset(ue,(J.V-1)*7),J.y=ue.getUTCFullYear(),J.m=ue.getUTCMonth(),J.d=ue.getUTCDate()+(J.w+6)%7):(ue=X_(Cv(J.y,0,1)),Z=ue.getDay(),ue=Z>4||Z===0?Ch.ceil(ue):Ch(ue),ue=_o.offset(ue,(J.V-1)*7),J.y=ue.getFullYear(),J.m=ue.getMonth(),J.d=ue.getDate()+(J.w+6)%7)}else("W"in J||"U"in J)&&("w"in J||(J.w="u"in J?J.u%7:"W"in J?1:0),Z="Z"in J?j_(Cv(J.y,0,1)).getUTCDay():X_(Cv(J.y,0,1)).getDay(),J.m=0,J.d="W"in J?(J.w+6)%7+J.W*7-(Z+5)%7:J.w+J.U*7-(Z+6)%7);return"Z"in J?(J.H+=J.Z/100|0,J.M+=J.Z%100,j_(J)):X_(J)}}o(A,"newParse");function S(K,X,te,J){for(var se=0,ue=X.length,Z=te.length,Se,ce;se<ue;){if(J>=Z)return-1;if(Se=X.charCodeAt(se++),Se===37){if(Se=X.charAt(se++),ce=T[Se in vW?X.charAt(se++):Se],!ce||(J=ce(K,te,J))<0)return-1}else if(Se!=te.charCodeAt(J++))return-1}return J}o(S,"parseSpecifier");function _(K,X,te){var J=h.exec(X.slice(te));return J?(K.p=f.get(J[0].toLowerCase()),te+J[0].length):-1}o(_,"parsePeriod");function I(K,X,te){var J=m.exec(X.slice(te));return J?(K.w=g.get(J[0].toLowerCase()),te+J[0].length):-1}o(I,"parseShortWeekday");function D(K,X,te){var J=d.exec(X.slice(te));return J?(K.w=p.get(J[0].toLowerCase()),te+J[0].length):-1}o(D,"parseWeekday");function k(K,X,te){var J=x.exec(X.slice(te));return J?(K.m=b.get(J[0].toLowerCase()),te+J[0].length):-1}o(k,"parseShortMonth");function L(K,X,te){var J=y.exec(X.slice(te));return J?(K.m=v.get(J[0].toLowerCase()),te+J[0].length):-1}o(L,"parseMonth");function R(K,X,te){return S(K,e,X,te)}o(R,"parseLocaleDateTime");function O(K,X,te){return S(K,r,X,te)}o(O,"parseLocaleDate");function M(K,X,te){return S(K,n,X,te)}o(M,"parseLocaleTime");function B(K){return s[K.getDay()]}o(B,"formatShortWeekday");function F(K){return a[K.getDay()]}o(F,"formatWeekday");function P(K){return u[K.getMonth()]}o(P,"formatShortMonth");function z(K){return l[K.getMonth()]}o(z,"formatMonth");function $(K){return i[+(K.getHours()>=12)]}o($,"formatPeriod");function H(K){return 1+~~(K.getMonth()/3)}o(H,"formatQuarter");function Q(K){return s[K.getUTCDay()]}o(Q,"formatUTCShortWeekday");function j(K){return a[K.getUTCDay()]}o(j,"formatUTCWeekday");function ie(K){return u[K.getUTCMonth()]}o(ie,"formatUTCShortMonth");function ne(K){return l[K.getUTCMonth()]}o(ne,"formatUTCMonth");function le(K){return i[+(K.getUTCHours()>=12)]}o(le,"formatUTCPeriod");function he(K){return 1+~~(K.getUTCMonth()/3)}return o(he,"formatUTCQuarter"),{format:o(function(K){var X=E(K+="",w);return X.toString=function(){return K},X},"format"),parse:o(function(K){var X=A(K+="",!1);return X.toString=function(){return K},X},"parse"),utcFormat:o(function(K){var X=E(K+="",C);return X.toString=function(){return K},X},"utcFormat"),utcParse:o(function(K){var X=A(K+="",!0);return X.toString=function(){return K},X},"utcParse")}}function Wr(t,e,r){var n=t<0?"-":"",i=(n?-t:t)+"",a=i.length;return n+(a<r?new Array(r-a+1).join(e)+i:i)}function $Te(t){return t.replace(FTe,"\\$&")}function Av(t){return new RegExp("^(?:"+t.map($Te).join("|")+")","i")}function _v(t){return new Map(t.map((e,r)=>[e.toLowerCase(),r]))}function zTe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function GTe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function VTe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function UTe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function HTe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function xW(t,e,r){var n=Qi.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function bW(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function WTe(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function qTe(t,e,r){var n=Qi.exec(e.slice(r,r+1));return n?(t.q=n[0]*3-3,r+n[0].length):-1}function YTe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function wW(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function XTe(t,e,r){var n=Qi.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function TW(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function jTe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function KTe(t,e,r){var n=Qi.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function QTe(t,e,r){var n=Qi.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function ZTe(t,e,r){var n=Qi.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function JTe(t,e,r){var n=BTe.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function eke(t,e,r){var n=Qi.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function tke(t,e,r){var n=Qi.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function kW(t,e){return Wr(t.getDate(),e,2)}function rke(t,e){return Wr(t.getHours(),e,2)}function nke(t,e){return Wr(t.getHours()%12||12,e,2)}function ike(t,e){return Wr(1+_o.count(Qs(t),t),e,3)}function _W(t,e){return Wr(t.getMilliseconds(),e,3)}function ake(t,e){return _W(t,e)+"000"}function ske(t,e){return Wr(t.getMonth()+1,e,2)}function oke(t,e){return Wr(t.getMinutes(),e,2)}function lke(t,e){return Wr(t.getSeconds(),e,2)}function cke(t){var e=t.getDay();return e===0?7:e}function uke(t,e){return Wr(yl.count(Qs(t)-1,t),e,2)}function DW(t){var e=t.getDay();return e>=4||e===0?oc(t):oc.ceil(t)}function hke(t,e){return t=DW(t),Wr(oc.count(Qs(t),t)+(Qs(t).getDay()===4),e,2)}function fke(t){return t.getDay()}function dke(t,e){return Wr(Ch.count(Qs(t)-1,t),e,2)}function pke(t,e){return Wr(t.getFullYear()%100,e,2)}function mke(t,e){return t=DW(t),Wr(t.getFullYear()%100,e,2)}function gke(t,e){return Wr(t.getFullYear()%1e4,e,4)}function yke(t,e){var r=t.getDay();return t=r>=4||r===0?oc(t):oc.ceil(t),Wr(t.getFullYear()%1e4,e,4)}function vke(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Wr(e/60|0,"0",2)+Wr(e%60,"0",2)}function EW(t,e){return Wr(t.getUTCDate(),e,2)}function xke(t,e){return Wr(t.getUTCHours(),e,2)}function bke(t,e){return Wr(t.getUTCHours()%12||12,e,2)}function wke(t,e){return Wr(1+Sv.count(vl(t),t),e,3)}function LW(t,e){return Wr(t.getUTCMilliseconds(),e,3)}function Tke(t,e){return LW(t,e)+"000"}function kke(t,e){return Wr(t.getUTCMonth()+1,e,2)}function Eke(t,e){return Wr(t.getUTCMinutes(),e,2)}function Ske(t,e){return Wr(t.getUTCSeconds(),e,2)}function Cke(t){var e=t.getUTCDay();return e===0?7:e}function Ake(t,e){return Wr(bd.count(vl(t)-1,t),e,2)}function RW(t){var e=t.getUTCDay();return e>=4||e===0?Ah(t):Ah.ceil(t)}function _ke(t,e){return t=RW(t),Wr(Ah.count(vl(t),t)+(vl(t).getUTCDay()===4),e,2)}function Dke(t){return t.getUTCDay()}function Lke(t,e){return Wr(N0.count(vl(t)-1,t),e,2)}function Rke(t,e){return Wr(t.getUTCFullYear()%100,e,2)}function Nke(t,e){return t=RW(t),Wr(t.getUTCFullYear()%100,e,2)}function Mke(t,e){return Wr(t.getUTCFullYear()%1e4,e,4)}function Ike(t,e){var r=t.getUTCDay();return t=r>=4||r===0?Ah(t):Ah.ceil(t),Wr(t.getUTCFullYear()%1e4,e,4)}function Oke(){return"+0000"}function SW(){return"%"}function CW(t){return+t}function AW(t){return Math.floor(+t/1e3)}var vW,Qi,BTe,FTe,NW=N(()=>{"use strict";A5();o(X_,"localDate");o(j_,"utcDate");o(Cv,"newDate");o(K_,"formatLocale");vW={"-":"",_:" ",0:"0"},Qi=/^\s*\d+/,BTe=/^%/,FTe=/[\\^$*+?|[\]().{}]/g;o(Wr,"pad");o($Te,"requote");o(Av,"formatRe");o(_v,"formatLookup");o(zTe,"parseWeekdayNumberSunday");o(GTe,"parseWeekdayNumberMonday");o(VTe,"parseWeekNumberSunday");o(UTe,"parseWeekNumberISO");o(HTe,"parseWeekNumberMonday");o(xW,"parseFullYear");o(bW,"parseYear");o(WTe,"parseZone");o(qTe,"parseQuarter");o(YTe,"parseMonthNumber");o(wW,"parseDayOfMonth");o(XTe,"parseDayOfYear");o(TW,"parseHour24");o(jTe,"parseMinutes");o(KTe,"parseSeconds");o(QTe,"parseMilliseconds");o(ZTe,"parseMicroseconds");o(JTe,"parseLiteralPercent");o(eke,"parseUnixTimestamp");o(tke,"parseUnixTimestampSeconds");o(kW,"formatDayOfMonth");o(rke,"formatHour24");o(nke,"formatHour12");o(ike,"formatDayOfYear");o(_W,"formatMilliseconds");o(ake,"formatMicroseconds");o(ske,"formatMonthNumber");o(oke,"formatMinutes");o(lke,"formatSeconds");o(cke,"formatWeekdayNumberMonday");o(uke,"formatWeekNumberSunday");o(DW,"dISO");o(hke,"formatWeekNumberISO");o(fke,"formatWeekdayNumberSunday");o(dke,"formatWeekNumberMonday");o(pke,"formatYear");o(mke,"formatYearISO");o(gke,"formatFullYear");o(yke,"formatFullYearISO");o(vke,"formatZone");o(EW,"formatUTCDayOfMonth");o(xke,"formatUTCHour24");o(bke,"formatUTCHour12");o(wke,"formatUTCDayOfYear");o(LW,"formatUTCMilliseconds");o(Tke,"formatUTCMicroseconds");o(kke,"formatUTCMonthNumber");o(Eke,"formatUTCMinutes");o(Ske,"formatUTCSeconds");o(Cke,"formatUTCWeekdayNumberMonday");o(Ake,"formatUTCWeekNumberSunday");o(RW,"UTCdISO");o(_ke,"formatUTCWeekNumberISO");o(Dke,"formatUTCWeekdayNumberSunday");o(Lke,"formatUTCWeekNumberMonday");o(Rke,"formatUTCYear");o(Nke,"formatUTCYearISO");o(Mke,"formatUTCFullYear");o(Ike,"formatUTCFullYearISO");o(Oke,"formatUTCZone");o(SW,"formatLiteralPercent");o(CW,"formatUnixTimestamp");o(AW,"formatUnixTimestampSeconds")});function Q_(t){return M0=K_(t),wd=M0.format,MW=M0.parse,IW=M0.utcFormat,OW=M0.utcParse,M0}var M0,wd,MW,IW,OW,PW=N(()=>{"use strict";NW();Q_({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});o(Q_,"defaultLocale")});var Z_=N(()=>{"use strict";PW()});function Pke(t){return new Date(t)}function Bke(t){return t instanceof Date?+t:+new Date(+t)}function BW(t,e,r,n,i,a,s,l,u,h){var f=kv(),d=f.invert,p=f.domain,m=h(".%L"),g=h(":%S"),y=h("%I:%M"),v=h("%I %p"),x=h("%a %d"),b=h("%b %d"),w=h("%B"),C=h("%Y");function T(E){return(u(E)<E?m:l(E)<E?g:s(E)<E?y:a(E)<E?v:n(E)<E?i(E)<E?x:b:r(E)<E?w:C)(E)}return o(T,"tickFormat"),f.invert=function(E){return new Date(d(E))},f.domain=function(E){return arguments.length?p(Array.from(E,Bke)):p().map(Pke)},f.ticks=function(E){var A=p();return t(A[0],A[A.length-1],E??10)},f.tickFormat=function(E,A){return A==null?T:h(A)},f.nice=function(E){var A=p();return(!E||typeof E.range!="function")&&(E=e(A[0],A[A.length-1],E??10)),E?p(O_(A,E)):f},f.copy=function(){return v5(f,BW(t,e,r,n,i,a,s,l,u,h))},f}function _5(){return Sh.apply(BW(q_,Y_,Qs,bu,yl,_o,xu,vu,Ks,wd).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}var FW=N(()=>{"use strict";A5();Z_();M_();Tv();aW();o(Pke,"date");o(Bke,"number");o(BW,"calendar");o(_5,"time")});var $W=N(()=>{"use strict";JH();iW();D_();FW()});function J_(t){for(var e=t.length/6|0,r=new Array(e),n=0;n<e;)r[n]="#"+t.slice(n*6,++n*6);return r}var zW=N(()=>{"use strict";o(J_,"default")});var e9,GW=N(()=>{"use strict";zW();e9=J_("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab")});var VW=N(()=>{"use strict";GW()});function Bn(t){return o(function(){return t},"constant")}var D5=N(()=>{"use strict";o(Bn,"default")});function HW(t){return t>1?0:t<-1?I0:Math.acos(t)}function r9(t){return t>=1?Dv:t<=-1?-Dv:Math.asin(t)}var t9,fa,_h,UW,L5,xl,Td,Zi,I0,Dv,O0,R5=N(()=>{"use strict";t9=Math.abs,fa=Math.atan2,_h=Math.cos,UW=Math.max,L5=Math.min,xl=Math.sin,Td=Math.sqrt,Zi=1e-12,I0=Math.PI,Dv=I0/2,O0=2*I0;o(HW,"acos");o(r9,"asin")});function N5(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(r==null)e=null;else{let n=Math.floor(r);if(!(n>=0))throw new RangeError(`invalid digits: ${r}`);e=n}return t},()=>new pd(e)}var n9=N(()=>{"use strict";m_();o(N5,"withPath")});function Fke(t){return t.innerRadius}function $ke(t){return t.outerRadius}function zke(t){return t.startAngle}function Gke(t){return t.endAngle}function Vke(t){return t&&t.padAngle}function Uke(t,e,r,n,i,a,s,l){var u=r-t,h=n-e,f=s-i,d=l-a,p=d*u-f*h;if(!(p*p<Zi))return p=(f*(e-a)-d*(t-i))/p,[t+p*u,e+p*h]}function M5(t,e,r,n,i,a,s){var l=t-r,u=e-n,h=(s?a:-a)/Td(l*l+u*u),f=h*u,d=-h*l,p=t+f,m=e+d,g=r+f,y=n+d,v=(p+g)/2,x=(m+y)/2,b=g-p,w=y-m,C=b*b+w*w,T=i-a,E=p*y-g*m,A=(w<0?-1:1)*Td(UW(0,T*T*C-E*E)),S=(E*w-b*A)/C,_=(-E*b-w*A)/C,I=(E*w+b*A)/C,D=(-E*b+w*A)/C,k=S-v,L=_-x,R=I-v,O=D-x;return k*k+L*L>R*R+O*O&&(S=I,_=D),{cx:S,cy:_,x01:-f,y01:-d,x11:S*(i/T-1),y11:_*(i/T-1)}}function bl(){var t=Fke,e=$ke,r=Bn(0),n=null,i=zke,a=Gke,s=Vke,l=null,u=N5(h);function h(){var f,d,p=+t.apply(this,arguments),m=+e.apply(this,arguments),g=i.apply(this,arguments)-Dv,y=a.apply(this,arguments)-Dv,v=t9(y-g),x=y>g;if(l||(l=f=u()),m<p&&(d=m,m=p,p=d),!(m>Zi))l.moveTo(0,0);else if(v>O0-Zi)l.moveTo(m*_h(g),m*xl(g)),l.arc(0,0,m,g,y,!x),p>Zi&&(l.moveTo(p*_h(y),p*xl(y)),l.arc(0,0,p,y,g,x));else{var b=g,w=y,C=g,T=y,E=v,A=v,S=s.apply(this,arguments)/2,_=S>Zi&&(n?+n.apply(this,arguments):Td(p*p+m*m)),I=L5(t9(m-p)/2,+r.apply(this,arguments)),D=I,k=I,L,R;if(_>Zi){var O=r9(_/p*xl(S)),M=r9(_/m*xl(S));(E-=O*2)>Zi?(O*=x?1:-1,C+=O,T-=O):(E=0,C=T=(g+y)/2),(A-=M*2)>Zi?(M*=x?1:-1,b+=M,w-=M):(A=0,b=w=(g+y)/2)}var B=m*_h(b),F=m*xl(b),P=p*_h(T),z=p*xl(T);if(I>Zi){var $=m*_h(w),H=m*xl(w),Q=p*_h(C),j=p*xl(C),ie;if(v<I0)if(ie=Uke(B,F,Q,j,$,H,P,z)){var ne=B-ie[0],le=F-ie[1],he=$-ie[0],K=H-ie[1],X=1/xl(HW((ne*he+le*K)/(Td(ne*ne+le*le)*Td(he*he+K*K)))/2),te=Td(ie[0]*ie[0]+ie[1]*ie[1]);D=L5(I,(p-te)/(X-1)),k=L5(I,(m-te)/(X+1))}else D=k=0}A>Zi?k>Zi?(L=M5(Q,j,B,F,m,k,x),R=M5($,H,P,z,m,k,x),l.moveTo(L.cx+L.x01,L.cy+L.y01),k<I?l.arc(L.cx,L.cy,k,fa(L.y01,L.x01),fa(R.y01,R.x01),!x):(l.arc(L.cx,L.cy,k,fa(L.y01,L.x01),fa(L.y11,L.x11),!x),l.arc(0,0,m,fa(L.cy+L.y11,L.cx+L.x11),fa(R.cy+R.y11,R.cx+R.x11),!x),l.arc(R.cx,R.cy,k,fa(R.y11,R.x11),fa(R.y01,R.x01),!x))):(l.moveTo(B,F),l.arc(0,0,m,b,w,!x)):l.moveTo(B,F),!(p>Zi)||!(E>Zi)?l.lineTo(P,z):D>Zi?(L=M5(P,z,$,H,p,-D,x),R=M5(B,F,Q,j,p,-D,x),l.lineTo(L.cx+L.x01,L.cy+L.y01),D<I?l.arc(L.cx,L.cy,D,fa(L.y01,L.x01),fa(R.y01,R.x01),!x):(l.arc(L.cx,L.cy,D,fa(L.y01,L.x01),fa(L.y11,L.x11),!x),l.arc(0,0,p,fa(L.cy+L.y11,L.cx+L.x11),fa(R.cy+R.y11,R.cx+R.x11),x),l.arc(R.cx,R.cy,D,fa(R.y11,R.x11),fa(R.y01,R.x01),!x))):l.arc(0,0,p,T,C,x)}if(l.closePath(),f)return l=null,f+""||null}return o(h,"arc"),h.centroid=function(){var f=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,d=(+i.apply(this,arguments)+ +a.apply(this,arguments))/2-I0/2;return[_h(d)*f,xl(d)*f]},h.innerRadius=function(f){return arguments.length?(t=typeof f=="function"?f:Bn(+f),h):t},h.outerRadius=function(f){return arguments.length?(e=typeof f=="function"?f:Bn(+f),h):e},h.cornerRadius=function(f){return arguments.length?(r=typeof f=="function"?f:Bn(+f),h):r},h.padRadius=function(f){return arguments.length?(n=f==null?null:typeof f=="function"?f:Bn(+f),h):n},h.startAngle=function(f){return arguments.length?(i=typeof f=="function"?f:Bn(+f),h):i},h.endAngle=function(f){return arguments.length?(a=typeof f=="function"?f:Bn(+f),h):a},h.padAngle=function(f){return arguments.length?(s=typeof f=="function"?f:Bn(+f),h):s},h.context=function(f){return arguments.length?(l=f??null,h):l},h}var WW=N(()=>{"use strict";D5();R5();n9();o(Fke,"arcInnerRadius");o($ke,"arcOuterRadius");o(zke,"arcStartAngle");o(Gke,"arcEndAngle");o(Vke,"arcPadAngle");o(Uke,"intersect");o(M5,"cornerTangents");o(bl,"default")});function Lv(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}var Nyt,i9=N(()=>{"use strict";Nyt=Array.prototype.slice;o(Lv,"default")});function qW(t){this._context=t}function wu(t){return new qW(t)}var a9=N(()=>{"use strict";o(qW,"Linear");qW.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e);break}},"point")};o(wu,"default")});function YW(t){return t[0]}function XW(t){return t[1]}var jW=N(()=>{"use strict";o(YW,"x");o(XW,"y")});function wl(t,e){var r=Bn(!0),n=null,i=wu,a=null,s=N5(l);t=typeof t=="function"?t:t===void 0?YW:Bn(t),e=typeof e=="function"?e:e===void 0?XW:Bn(e);function l(u){var h,f=(u=Lv(u)).length,d,p=!1,m;for(n==null&&(a=i(m=s())),h=0;h<=f;++h)!(h<f&&r(d=u[h],h,u))===p&&((p=!p)?a.lineStart():a.lineEnd()),p&&a.point(+t(d,h,u),+e(d,h,u));if(m)return a=null,m+""||null}return o(l,"line"),l.x=function(u){return arguments.length?(t=typeof u=="function"?u:Bn(+u),l):t},l.y=function(u){return arguments.length?(e=typeof u=="function"?u:Bn(+u),l):e},l.defined=function(u){return arguments.length?(r=typeof u=="function"?u:Bn(!!u),l):r},l.curve=function(u){return arguments.length?(i=u,n!=null&&(a=i(n)),l):i},l.context=function(u){return arguments.length?(u==null?n=a=null:a=i(n=u),l):n},l}var KW=N(()=>{"use strict";i9();D5();a9();n9();jW();o(wl,"default")});function s9(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}var QW=N(()=>{"use strict";o(s9,"default")});function o9(t){return t}var ZW=N(()=>{"use strict";o(o9,"default")});function I5(){var t=o9,e=s9,r=null,n=Bn(0),i=Bn(O0),a=Bn(0);function s(l){var u,h=(l=Lv(l)).length,f,d,p=0,m=new Array(h),g=new Array(h),y=+n.apply(this,arguments),v=Math.min(O0,Math.max(-O0,i.apply(this,arguments)-y)),x,b=Math.min(Math.abs(v)/h,a.apply(this,arguments)),w=b*(v<0?-1:1),C;for(u=0;u<h;++u)(C=g[m[u]=u]=+t(l[u],u,l))>0&&(p+=C);for(e!=null?m.sort(function(T,E){return e(g[T],g[E])}):r!=null&&m.sort(function(T,E){return r(l[T],l[E])}),u=0,d=p?(v-h*w)/p:0;u<h;++u,y=x)f=m[u],C=g[f],x=y+(C>0?C*d:0)+w,g[f]={data:l[f],index:u,value:C,startAngle:y,endAngle:x,padAngle:b};return g}return o(s,"pie"),s.value=function(l){return arguments.length?(t=typeof l=="function"?l:Bn(+l),s):t},s.sortValues=function(l){return arguments.length?(e=l,r=null,s):e},s.sort=function(l){return arguments.length?(r=l,e=null,s):r},s.startAngle=function(l){return arguments.length?(n=typeof l=="function"?l:Bn(+l),s):n},s.endAngle=function(l){return arguments.length?(i=typeof l=="function"?l:Bn(+l),s):i},s.padAngle=function(l){return arguments.length?(a=typeof l=="function"?l:Bn(+l),s):a},s}var JW=N(()=>{"use strict";i9();D5();QW();ZW();R5();o(I5,"default")});function Rv(t){return new O5(t,!0)}function Nv(t){return new O5(t,!1)}var O5,eq=N(()=>{"use strict";O5=class{static{o(this,"Bump")}constructor(e,r){this._context=e,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,r){switch(e=+e,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,r,e,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,e,this._y0,e,r);break}}this._x0=e,this._y0=r}};o(Rv,"bumpX");o(Nv,"bumpY")});function Zs(){}var Mv=N(()=>{"use strict";o(Zs,"default")});function P0(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function Iv(t){this._context=t}function Do(t){return new Iv(t)}var Ov=N(()=>{"use strict";o(P0,"point");o(Iv,"Basis");Iv.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 3:P0(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:P0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(Do,"default")});function tq(t){this._context=t}function P5(t){return new tq(t)}var rq=N(()=>{"use strict";Mv();Ov();o(tq,"BasisClosed");tq.prototype={areaStart:Zs,areaEnd:Zs,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:P0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(P5,"default")});function nq(t){this._context=t}function B5(t){return new nq(t)}var iq=N(()=>{"use strict";Ov();o(nq,"BasisOpen");nq.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:P0(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e},"point")};o(B5,"default")});function aq(t,e){this._basis=new Iv(t),this._beta=e}var l9,sq=N(()=>{"use strict";Ov();o(aq,"Bundle");aq.prototype={lineStart:o(function(){this._x=[],this._y=[],this._basis.lineStart()},"lineStart"),lineEnd:o(function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var n=t[0],i=e[0],a=t[r]-n,s=e[r]-i,l=-1,u;++l<=r;)u=l/r,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+u*a),this._beta*e[l]+(1-this._beta)*(i+u*s));this._x=this._y=null,this._basis.lineEnd()},"lineEnd"),point:o(function(t,e){this._x.push(+t),this._y.push(+e)},"point")};l9=o(function t(e){function r(n){return e===1?new Iv(n):new aq(n,e)}return o(r,"bundle"),r.beta=function(n){return t(+n)},r},"custom")(.85)});function B0(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function F5(t,e){this._context=t,this._k=(1-e)/6}var Pv,Bv=N(()=>{"use strict";o(B0,"point");o(F5,"Cardinal");F5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:B0(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:B0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};Pv=o(function t(e){function r(n){return new F5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function $5(t,e){this._context=t,this._k=(1-e)/6}var c9,u9=N(()=>{"use strict";Mv();Bv();o($5,"CardinalClosed");$5.prototype={areaStart:Zs,areaEnd:Zs,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:B0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};c9=o(function t(e){function r(n){return new $5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function z5(t,e){this._context=t,this._k=(1-e)/6}var h9,f9=N(()=>{"use strict";Bv();o(z5,"CardinalOpen");z5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:B0(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};h9=o(function t(e){function r(n){return new z5(n,e)}return o(r,"cardinal"),r.tension=function(n){return t(+n)},r},"custom")(0)});function Fv(t,e,r){var n=t._x1,i=t._y1,a=t._x2,s=t._y2;if(t._l01_a>Zi){var l=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,u=3*t._l01_a*(t._l01_a+t._l12_a);n=(n*l-t._x0*t._l12_2a+t._x2*t._l01_2a)/u,i=(i*l-t._y0*t._l12_2a+t._y2*t._l01_2a)/u}if(t._l23_a>Zi){var h=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*h+t._x1*t._l23_2a-e*t._l12_2a)/f,s=(s*h+t._y1*t._l23_2a-r*t._l12_2a)/f}t._context.bezierCurveTo(n,i,a,s,t._x2,t._y2)}function oq(t,e){this._context=t,this._alpha=e}var $v,G5=N(()=>{"use strict";R5();Bv();o(Fv,"point");o(oq,"CatmullRom");oq.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Fv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};$v=o(function t(e){function r(n){return e?new oq(n,e):new F5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function lq(t,e){this._context=t,this._alpha=e}var d9,cq=N(()=>{"use strict";u9();Mv();G5();o(lq,"CatmullRomClosed");lq.prototype={areaStart:Zs,areaEnd:Zs,lineStart:o(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Fv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};d9=o(function t(e){function r(n){return e?new lq(n,e):new $5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function uq(t,e){this._context=t,this._alpha=e}var p9,hq=N(()=>{"use strict";f9();G5();o(uq,"CatmullRomOpen");uq.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:o(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Fv(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e},"point")};p9=o(function t(e){function r(n){return e?new uq(n,e):new z5(n,0)}return o(r,"catmullRom"),r.alpha=function(n){return t(+n)},r},"custom")(.5)});function fq(t){this._context=t}function V5(t){return new fq(t)}var dq=N(()=>{"use strict";Mv();o(fq,"LinearClosed");fq.prototype={areaStart:Zs,areaEnd:Zs,lineStart:o(function(){this._point=0},"lineStart"),lineEnd:o(function(){this._point&&this._context.closePath()},"lineEnd"),point:o(function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))},"point")};o(V5,"default")});function pq(t){return t<0?-1:1}function mq(t,e,r){var n=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(n||i<0&&-0),s=(r-t._y1)/(i||n<0&&-0),l=(a*i+s*n)/(n+i);return(pq(a)+pq(s))*Math.min(Math.abs(a),Math.abs(s),.5*Math.abs(l))||0}function gq(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function m9(t,e,r){var n=t._x0,i=t._y0,a=t._x1,s=t._y1,l=(a-n)/3;t._context.bezierCurveTo(n+l,i+l*e,a-l,s-l*r,a,s)}function U5(t){this._context=t}function yq(t){this._context=new vq(t)}function vq(t){this._context=t}function zv(t){return new U5(t)}function Gv(t){return new yq(t)}var xq=N(()=>{"use strict";o(pq,"sign");o(mq,"slope3");o(gq,"slope2");o(m9,"point");o(U5,"MonotoneX");U5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},"lineStart"),lineEnd:o(function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:m9(this,this._t0,gq(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:o(function(t,e){var r=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,m9(this,gq(this,r=mq(this,t,e)),r);break;default:m9(this,this._t0,r=mq(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}},"point")};o(yq,"MonotoneY");(yq.prototype=Object.create(U5.prototype)).point=function(t,e){U5.prototype.point.call(this,e,t)};o(vq,"ReflectContext");vq.prototype={moveTo:o(function(t,e){this._context.moveTo(e,t)},"moveTo"),closePath:o(function(){this._context.closePath()},"closePath"),lineTo:o(function(t,e){this._context.lineTo(e,t)},"lineTo"),bezierCurveTo:o(function(t,e,r,n,i,a){this._context.bezierCurveTo(e,t,n,r,a,i)},"bezierCurveTo")};o(zv,"monotoneX");o(Gv,"monotoneY")});function wq(t){this._context=t}function bq(t){var e,r=t.length-1,n,i=new Array(r),a=new Array(r),s=new Array(r);for(i[0]=0,a[0]=2,s[0]=t[0]+2*t[1],e=1;e<r-1;++e)i[e]=1,a[e]=4,s[e]=4*t[e]+2*t[e+1];for(i[r-1]=2,a[r-1]=7,s[r-1]=8*t[r-1]+t[r],e=1;e<r;++e)n=i[e]/a[e-1],a[e]-=n,s[e]-=n*s[e-1];for(i[r-1]=s[r-1]/a[r-1],e=r-2;e>=0;--e)i[e]=(s[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e<r-1;++e)a[e]=2*t[e+1]-i[e+1];return[i,a]}function F0(t){return new wq(t)}var Tq=N(()=>{"use strict";o(wq,"Natural");wq.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x=[],this._y=[]},"lineStart"),lineEnd:o(function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),r===2)this._context.lineTo(t[1],e[1]);else for(var n=bq(t),i=bq(e),a=0,s=1;s<r;++a,++s)this._context.bezierCurveTo(n[0][a],i[0][a],n[1][a],i[1][a],t[s],e[s]);(this._line||this._line!==0&&r===1)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},"lineEnd"),point:o(function(t,e){this._x.push(+t),this._y.push(+e)},"point")};o(bq,"controlPoints");o(F0,"default")});function H5(t,e){this._context=t,this._t=e}function $0(t){return new H5(t,.5)}function Vv(t){return new H5(t,0)}function Uv(t){return new H5(t,1)}var kq=N(()=>{"use strict";o(H5,"Step");H5.prototype={areaStart:o(function(){this._line=0},"areaStart"),areaEnd:o(function(){this._line=NaN},"areaEnd"),lineStart:o(function(){this._x=this._y=NaN,this._point=0},"lineStart"),lineEnd:o(function(){0<this._t&&this._t<1&&this._point===2&&this._context.lineTo(this._x,this._y),(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},"lineEnd"),point:o(function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}break}}this._x=t,this._y=e},"point")};o($0,"default");o(Vv,"stepBefore");o(Uv,"stepAfter")});var Eq=N(()=>{"use strict";WW();KW();JW();rq();iq();Ov();eq();sq();u9();f9();Bv();cq();hq();G5();dq();a9();xq();Tq();kq()});var Sq=N(()=>{"use strict"});var Cq=N(()=>{"use strict"});function Dh(t,e,r){this.k=t,this.x=e,this.y=r}function y9(t){for(;!t.__zoom;)if(!(t=t.parentNode))return g9;return t.__zoom}var g9,v9=N(()=>{"use strict";o(Dh,"Transform");Dh.prototype={constructor:Dh,scale:o(function(t){return t===1?this:new Dh(this.k*t,this.x,this.y)},"scale"),translate:o(function(t,e){return t===0&e===0?this:new Dh(this.k,this.x+this.k*t,this.y+this.k*e)},"translate"),apply:o(function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},"apply"),applyX:o(function(t){return t*this.k+this.x},"applyX"),applyY:o(function(t){return t*this.k+this.y},"applyY"),invert:o(function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},"invert"),invertX:o(function(t){return(t-this.x)/this.k},"invertX"),invertY:o(function(t){return(t-this.y)/this.k},"invertY"),rescaleX:o(function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},"rescaleX"),rescaleY:o(function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},"rescaleY"),toString:o(function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"},"toString")};g9=new Dh(1,0,0);y9.prototype=Dh.prototype;o(y9,"transform")});var Aq=N(()=>{"use strict"});var _q=N(()=>{"use strict";l5();Sq();Cq();v9();Aq()});var Dq=N(()=>{"use strict";_q();v9()});var dr=N(()=>{"use strict";vh();sV();SH();DH();E0();LH();RH();TA();QV();NH();u_();MH();OH();A_();jH();KH();A0();m_();QH();IH();ZH();$W();VW();fl();Eq();A5();Z_();r5();l5();Dq()});var Lq=Mi(Ji=>{"use strict";Object.defineProperty(Ji,"__esModule",{value:!0});Ji.BLANK_URL=Ji.relativeFirstCharacters=Ji.whitespaceEscapeCharsRegex=Ji.urlSchemeRegex=Ji.ctrlCharactersRegex=Ji.htmlCtrlEntityRegex=Ji.htmlEntitiesRegex=Ji.invalidProtocolRegex=void 0;Ji.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im;Ji.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g;Ji.htmlCtrlEntityRegex=/&(newline|tab);/gi;Ji.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim;Ji.urlSchemeRegex=/^.+(:|&colon;)/gim;Ji.whitespaceEscapeCharsRegex=/(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g;Ji.relativeFirstCharacters=[".","/"];Ji.BLANK_URL="about:blank"});var z0=Mi(W5=>{"use strict";Object.defineProperty(W5,"__esModule",{value:!0});W5.sanitizeUrl=void 0;var Aa=Lq();function Hke(t){return Aa.relativeFirstCharacters.indexOf(t[0])>-1}o(Hke,"isRelativeUrlWithoutProtocol");function Wke(t){var e=t.replace(Aa.ctrlCharactersRegex,"");return e.replace(Aa.htmlEntitiesRegex,function(r,n){return String.fromCharCode(n)})}o(Wke,"decodeHtmlCharacters");function qke(t){return URL.canParse(t)}o(qke,"isValidUrl");function Rq(t){try{return decodeURIComponent(t)}catch{return t}}o(Rq,"decodeURI");function Yke(t){if(!t)return Aa.BLANK_URL;var e,r=Rq(t.trim());do r=Wke(r).replace(Aa.htmlCtrlEntityRegex,"").replace(Aa.ctrlCharactersRegex,"").replace(Aa.whitespaceEscapeCharsRegex,"").trim(),r=Rq(r),e=r.match(Aa.ctrlCharactersRegex)||r.match(Aa.htmlEntitiesRegex)||r.match(Aa.htmlCtrlEntityRegex)||r.match(Aa.whitespaceEscapeCharsRegex);while(e&&e.length>0);var n=r;if(!n)return Aa.BLANK_URL;if(Hke(n))return n;var i=n.trimStart(),a=i.match(Aa.urlSchemeRegex);if(!a)return n;var s=a[0].toLowerCase().trim();if(Aa.invalidProtocolRegex.test(s))return Aa.BLANK_URL;var l=i.replace(/\\/g,"/");if(s==="mailto:"||s.includes("://"))return l;if(s==="http:"||s==="https:"){if(!qke(l))return Aa.BLANK_URL;var u=new URL(l);return u.protocol=u.protocol.toLowerCase(),u.hostname=u.hostname.toLowerCase(),u.toString()}return l}o(Yke,"sanitizeUrl");W5.sanitizeUrl=Yke});var x9,kd,q5,Nq,Mq,Iq,Tl,Hv,Wv=N(()=>{"use strict";x9=Sa(z0(),1);gr();kd=o((t,e)=>{let r=t.append("rect");if(r.attr("x",e.x),r.attr("y",e.y),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("width",e.width),r.attr("height",e.height),e.name&&r.attr("name",e.name),e.rx&&r.attr("rx",e.rx),e.ry&&r.attr("ry",e.ry),e.attrs!==void 0)for(let n in e.attrs)r.attr(n,e.attrs[n]);return e.class&&r.attr("class",e.class),r},"drawRect"),q5=o((t,e)=>{let r={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};kd(t,r).lower()},"drawBackgroundRect"),Nq=o((t,e)=>{let r=e.text.replace(nd," "),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.attr("class","legend"),n.style("text-anchor",e.anchor),e.class&&n.attr("class",e.class);let i=n.append("tspan");return i.attr("x",e.x+e.textMargin*2),i.text(r),n},"drawText"),Mq=o((t,e,r,n)=>{let i=t.append("image");i.attr("x",e),i.attr("y",r);let a=(0,x9.sanitizeUrl)(n);i.attr("xlink:href",a)},"drawImage"),Iq=o((t,e,r,n)=>{let i=t.append("use");i.attr("x",e),i.attr("y",r);let a=(0,x9.sanitizeUrl)(n);i.attr("xlink:href",`#${a}`)},"drawEmbeddedImage"),Tl=o(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),Hv=o(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj")});var Oq,b9,Pq,Xke,jke,Kke,Qke,Zke,Jke,eEe,tEe,rEe,nEe,iEe,aEe,Tu,kl,Bq=N(()=>{"use strict";gr();Wv();Oq=Sa(z0(),1),b9=o(function(t,e){return kd(t,e)},"drawRect"),Pq=o(function(t,e,r,n,i,a){let s=t.append("image");s.attr("width",e),s.attr("height",r),s.attr("x",n),s.attr("y",i);let l=a.startsWith("data:image/png;base64")?a:(0,Oq.sanitizeUrl)(a);s.attr("xlink:href",l)},"drawImage"),Xke=o((t,e,r)=>{let n=t.append("g"),i=0;for(let a of e){let s=a.textColor?a.textColor:"#444444",l=a.lineColor?a.lineColor:"#444444",u=a.offsetX?parseInt(a.offsetX):0,h=a.offsetY?parseInt(a.offsetY):0,f="";if(i===0){let p=n.append("line");p.attr("x1",a.startPoint.x),p.attr("y1",a.startPoint.y),p.attr("x2",a.endPoint.x),p.attr("y2",a.endPoint.y),p.attr("stroke-width","1"),p.attr("stroke",l),p.style("fill","none"),a.type!=="rel_b"&&p.attr("marker-end","url("+f+"#arrowhead)"),(a.type==="birel"||a.type==="rel_b")&&p.attr("marker-start","url("+f+"#arrowend)"),i=-1}else{let p=n.append("path");p.attr("fill","none").attr("stroke-width","1").attr("stroke",l).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",a.startPoint.x).replaceAll("starty",a.startPoint.y).replaceAll("controlx",a.startPoint.x+(a.endPoint.x-a.startPoint.x)/2-(a.endPoint.x-a.startPoint.x)/4).replaceAll("controly",a.startPoint.y+(a.endPoint.y-a.startPoint.y)/2).replaceAll("stopx",a.endPoint.x).replaceAll("stopy",a.endPoint.y)),a.type!=="rel_b"&&p.attr("marker-end","url("+f+"#arrowhead)"),(a.type==="birel"||a.type==="rel_b")&&p.attr("marker-start","url("+f+"#arrowend)")}let d=r.messageFont();Tu(r)(a.label.text,n,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+u,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+h,a.label.width,a.label.height,{fill:s},d),a.techn&&a.techn.text!==""&&(d=r.messageFont(),Tu(r)("["+a.techn.text+"]",n,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+u,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+r.messageFontSize+5+h,Math.max(a.label.width,a.techn.width),a.techn.height,{fill:s,"font-style":"italic"},d))}},"drawRels"),jke=o(function(t,e,r){let n=t.append("g"),i=e.bgColor?e.bgColor:"none",a=e.borderColor?e.borderColor:"#444444",s=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let u={x:e.x,y:e.y,fill:i,stroke:a,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};b9(n,u);let h=r.boundaryFont();h.fontWeight="bold",h.fontSize=h.fontSize+2,h.fontColor=s,Tu(r)(e.label.text,n,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},h),e.type&&e.type.text!==""&&(h=r.boundaryFont(),h.fontColor=s,Tu(r)(e.type.text,n,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},h)),e.descr&&e.descr.text!==""&&(h=r.boundaryFont(),h.fontSize=h.fontSize-2,h.fontColor=s,Tu(r)(e.descr.text,n,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},h))},"drawBoundary"),Kke=o(function(t,e,r){let n=e.bgColor?e.bgColor:r[e.typeC4Shape.text+"_bg_color"],i=e.borderColor?e.borderColor:r[e.typeC4Shape.text+"_border_color"],a=e.fontColor?e.fontColor:"#FFFFFF",s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII=";break}let l=t.append("g");l.attr("class","person-man");let u=Tl();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":u.x=e.x,u.y=e.y,u.fill=n,u.width=e.width,u.height=e.height,u.stroke=i,u.rx=2.5,u.ry=2.5,u.attrs={"stroke-width":.5},b9(l,u);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":l.append("path").attr("fill",n).attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),l.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":l.append("path").attr("fill",n).attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),l.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",i).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2));break}let h=aEe(r,e.typeC4Shape.text);switch(l.append("text").attr("fill",a).attr("font-family",h.fontFamily).attr("font-size",h.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":Pq(l,48,48,e.x+e.width/2-24,e.y+e.image.Y,s);break}let f=r[e.typeC4Shape.text+"Font"]();return f.fontWeight="bold",f.fontSize=f.fontSize+2,f.fontColor=a,Tu(r)(e.label.text,l,e.x,e.y+e.label.Y,e.width,e.height,{fill:a},f),f=r[e.typeC4Shape.text+"Font"](),f.fontColor=a,e.techn&&e.techn?.text!==""?Tu(r)(e.techn.text,l,e.x,e.y+e.techn.Y,e.width,e.height,{fill:a,"font-style":"italic"},f):e.type&&e.type.text!==""&&Tu(r)(e.type.text,l,e.x,e.y+e.type.Y,e.width,e.height,{fill:a,"font-style":"italic"},f),e.descr&&e.descr.text!==""&&(f=r.personFont(),f.fontColor=a,Tu(r)(e.descr.text,l,e.x,e.y+e.descr.Y,e.width,e.height,{fill:a},f)),e.height},"drawC4Shape"),Qke=o(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),Zke=o(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),Jke=o(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),eEe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},"insertArrowHead"),tEe=o(function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},"insertArrowEnd"),rEe=o(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),nEe=o(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertDynamicNumber"),iEe=o(function(t){let r=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);r.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),r.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},"insertArrowCrossHead"),aEe=o((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"getC4ShapeFont"),Tu=function(){function t(i,a,s,l,u,h,f){let d=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("text-anchor","middle").text(i);n(d,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d){let{fontSize:p,fontFamily:m,fontWeight:g}=d,y=i.split(Ze.lineBreakRegex);for(let v=0;v<y.length;v++){let x=v*p-p*(y.length-1)/2,b=a.append("text").attr("x",s+u/2).attr("y",l).style("text-anchor","middle").attr("dominant-baseline","middle").style("font-size",p).style("font-weight",g).style("font-family",m);b.append("tspan").attr("dy",x).text(y[v]).attr("alignment-baseline","mathematical"),n(b,f)}}o(e,"byTspan");function r(i,a,s,l,u,h,f,d){let p=a.append("switch"),g=p.append("foreignObject").attr("x",s).attr("y",l).attr("width",u).attr("height",h).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");g.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(i),e(i,p,s,l,u,h,f,d),n(g,f)}o(r,"byFo");function n(i,a){for(let s in a)a.hasOwnProperty(s)&&i.attr(s,a[s])}return o(n,"_setTextAttrs"),function(i){return i.textPlacement==="fo"?r:i.textPlacement==="old"?t:e}}(),kl={drawRect:b9,drawBoundary:jke,drawC4Shape:Kke,drawRels:Xke,drawImage:Pq,insertArrowHead:eEe,insertArrowEnd:tEe,insertArrowFilledHead:rEe,insertDynamicNumber:nEe,insertArrowCrossHead:iEe,insertDatabaseIcon:Qke,insertComputerIcon:Zke,insertClockIcon:Jke}});var sEe,X5,w9=N(()=>{"use strict";sEe=typeof global=="object"&&global&&global.Object===Object&&global,X5=sEe});var oEe,lEe,li,Lo=N(()=>{"use strict";w9();oEe=typeof self=="object"&&self&&self.Object===Object&&self,lEe=X5||oEe||Function("return this")(),li=lEe});var cEe,ea,Ed=N(()=>{"use strict";Lo();cEe=li.Symbol,ea=cEe});function fEe(t){var e=uEe.call(t,qv),r=t[qv];try{t[qv]=void 0;var n=!0}catch{}var i=hEe.call(t);return n&&(e?t[qv]=r:delete t[qv]),i}var Fq,uEe,hEe,qv,$q,zq=N(()=>{"use strict";Ed();Fq=Object.prototype,uEe=Fq.hasOwnProperty,hEe=Fq.toString,qv=ea?ea.toStringTag:void 0;o(fEe,"getRawTag");$q=fEe});function mEe(t){return pEe.call(t)}var dEe,pEe,Gq,Vq=N(()=>{"use strict";dEe=Object.prototype,pEe=dEe.toString;o(mEe,"objectToString");Gq=mEe});function vEe(t){return t==null?t===void 0?yEe:gEe:Uq&&Uq in Object(t)?$q(t):Gq(t)}var gEe,yEe,Uq,da,ku=N(()=>{"use strict";Ed();zq();Vq();gEe="[object Null]",yEe="[object Undefined]",Uq=ea?ea.toStringTag:void 0;o(vEe,"baseGetTag");da=vEe});function xEe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}var bn,Js=N(()=>{"use strict";o(xEe,"isObject");bn=xEe});function EEe(t){if(!bn(t))return!1;var e=da(t);return e==wEe||e==TEe||e==bEe||e==kEe}var bEe,wEe,TEe,kEe,Si,Yv=N(()=>{"use strict";ku();Js();bEe="[object AsyncFunction]",wEe="[object Function]",TEe="[object GeneratorFunction]",kEe="[object Proxy]";o(EEe,"isFunction");Si=EEe});var SEe,j5,Hq=N(()=>{"use strict";Lo();SEe=li["__core-js_shared__"],j5=SEe});function CEe(t){return!!Wq&&Wq in t}var Wq,qq,Yq=N(()=>{"use strict";Hq();Wq=function(){var t=/[^.]+$/.exec(j5&&j5.keys&&j5.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();o(CEe,"isMasked");qq=CEe});function DEe(t){if(t!=null){try{return _Ee.call(t)}catch{}try{return t+""}catch{}}return""}var AEe,_Ee,Eu,T9=N(()=>{"use strict";AEe=Function.prototype,_Ee=AEe.toString;o(DEe,"toSource");Eu=DEe});function BEe(t){if(!bn(t)||qq(t))return!1;var e=Si(t)?PEe:REe;return e.test(Eu(t))}var LEe,REe,NEe,MEe,IEe,OEe,PEe,Xq,jq=N(()=>{"use strict";Yv();Yq();Js();T9();LEe=/[\\^$.*+?()[\]{}|]/g,REe=/^\[object .+?Constructor\]$/,NEe=Function.prototype,MEe=Object.prototype,IEe=NEe.toString,OEe=MEe.hasOwnProperty,PEe=RegExp("^"+IEe.call(OEe).replace(LEe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");o(BEe,"baseIsNative");Xq=BEe});function FEe(t,e){return t?.[e]}var Kq,Qq=N(()=>{"use strict";o(FEe,"getValue");Kq=FEe});function $Ee(t,e){var r=Kq(t,e);return Xq(r)?r:void 0}var Ss,Lh=N(()=>{"use strict";jq();Qq();o($Ee,"getNative");Ss=$Ee});var zEe,Su,Xv=N(()=>{"use strict";Lh();zEe=Ss(Object,"create"),Su=zEe});function GEe(){this.__data__=Su?Su(null):{},this.size=0}var Zq,Jq=N(()=>{"use strict";Xv();o(GEe,"hashClear");Zq=GEe});function VEe(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}var eY,tY=N(()=>{"use strict";o(VEe,"hashDelete");eY=VEe});function qEe(t){var e=this.__data__;if(Su){var r=e[t];return r===UEe?void 0:r}return WEe.call(e,t)?e[t]:void 0}var UEe,HEe,WEe,rY,nY=N(()=>{"use strict";Xv();UEe="__lodash_hash_undefined__",HEe=Object.prototype,WEe=HEe.hasOwnProperty;o(qEe,"hashGet");rY=qEe});function jEe(t){var e=this.__data__;return Su?e[t]!==void 0:XEe.call(e,t)}var YEe,XEe,iY,aY=N(()=>{"use strict";Xv();YEe=Object.prototype,XEe=YEe.hasOwnProperty;o(jEe,"hashHas");iY=jEe});function QEe(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=Su&&e===void 0?KEe:e,this}var KEe,sY,oY=N(()=>{"use strict";Xv();KEe="__lodash_hash_undefined__";o(QEe,"hashSet");sY=QEe});function G0(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}var k9,lY=N(()=>{"use strict";Jq();tY();nY();aY();oY();o(G0,"Hash");G0.prototype.clear=Zq;G0.prototype.delete=eY;G0.prototype.get=rY;G0.prototype.has=iY;G0.prototype.set=sY;k9=G0});function ZEe(){this.__data__=[],this.size=0}var cY,uY=N(()=>{"use strict";o(ZEe,"listCacheClear");cY=ZEe});function JEe(t,e){return t===e||t!==t&&e!==e}var Ro,Sd=N(()=>{"use strict";o(JEe,"eq");Ro=JEe});function e6e(t,e){for(var r=t.length;r--;)if(Ro(t[r][0],e))return r;return-1}var Rh,jv=N(()=>{"use strict";Sd();o(e6e,"assocIndexOf");Rh=e6e});function n6e(t){var e=this.__data__,r=Rh(e,t);if(r<0)return!1;var n=e.length-1;return r==n?e.pop():r6e.call(e,r,1),--this.size,!0}var t6e,r6e,hY,fY=N(()=>{"use strict";jv();t6e=Array.prototype,r6e=t6e.splice;o(n6e,"listCacheDelete");hY=n6e});function i6e(t){var e=this.__data__,r=Rh(e,t);return r<0?void 0:e[r][1]}var dY,pY=N(()=>{"use strict";jv();o(i6e,"listCacheGet");dY=i6e});function a6e(t){return Rh(this.__data__,t)>-1}var mY,gY=N(()=>{"use strict";jv();o(a6e,"listCacheHas");mY=a6e});function s6e(t,e){var r=this.__data__,n=Rh(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this}var yY,vY=N(()=>{"use strict";jv();o(s6e,"listCacheSet");yY=s6e});function V0(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}var Nh,Kv=N(()=>{"use strict";uY();fY();pY();gY();vY();o(V0,"ListCache");V0.prototype.clear=cY;V0.prototype.delete=hY;V0.prototype.get=dY;V0.prototype.has=mY;V0.prototype.set=yY;Nh=V0});var o6e,Mh,K5=N(()=>{"use strict";Lh();Lo();o6e=Ss(li,"Map"),Mh=o6e});function l6e(){this.size=0,this.__data__={hash:new k9,map:new(Mh||Nh),string:new k9}}var xY,bY=N(()=>{"use strict";lY();Kv();K5();o(l6e,"mapCacheClear");xY=l6e});function c6e(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}var wY,TY=N(()=>{"use strict";o(c6e,"isKeyable");wY=c6e});function u6e(t,e){var r=t.__data__;return wY(e)?r[typeof e=="string"?"string":"hash"]:r.map}var Ih,Qv=N(()=>{"use strict";TY();o(u6e,"getMapData");Ih=u6e});function h6e(t){var e=Ih(this,t).delete(t);return this.size-=e?1:0,e}var kY,EY=N(()=>{"use strict";Qv();o(h6e,"mapCacheDelete");kY=h6e});function f6e(t){return Ih(this,t).get(t)}var SY,CY=N(()=>{"use strict";Qv();o(f6e,"mapCacheGet");SY=f6e});function d6e(t){return Ih(this,t).has(t)}var AY,_Y=N(()=>{"use strict";Qv();o(d6e,"mapCacheHas");AY=d6e});function p6e(t,e){var r=Ih(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,this}var DY,LY=N(()=>{"use strict";Qv();o(p6e,"mapCacheSet");DY=p6e});function U0(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}var Cd,Q5=N(()=>{"use strict";bY();EY();CY();_Y();LY();o(U0,"MapCache");U0.prototype.clear=xY;U0.prototype.delete=kY;U0.prototype.get=SY;U0.prototype.has=AY;U0.prototype.set=DY;Cd=U0});function E9(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(m6e);var r=o(function(){var n=arguments,i=e?e.apply(this,n):n[0],a=r.cache;if(a.has(i))return a.get(i);var s=t.apply(this,n);return r.cache=a.set(i,s)||a,s},"memoized");return r.cache=new(E9.Cache||Cd),r}var m6e,H0,S9=N(()=>{"use strict";Q5();m6e="Expected a function";o(E9,"memoize");E9.Cache=Cd;H0=E9});function g6e(){this.__data__=new Nh,this.size=0}var RY,NY=N(()=>{"use strict";Kv();o(g6e,"stackClear");RY=g6e});function y6e(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}var MY,IY=N(()=>{"use strict";o(y6e,"stackDelete");MY=y6e});function v6e(t){return this.__data__.get(t)}var OY,PY=N(()=>{"use strict";o(v6e,"stackGet");OY=v6e});function x6e(t){return this.__data__.has(t)}var BY,FY=N(()=>{"use strict";o(x6e,"stackHas");BY=x6e});function w6e(t,e){var r=this.__data__;if(r instanceof Nh){var n=r.__data__;if(!Mh||n.length<b6e-1)return n.push([t,e]),this.size=++r.size,this;r=this.__data__=new Cd(n)}return r.set(t,e),this.size=r.size,this}var b6e,$Y,zY=N(()=>{"use strict";Kv();K5();Q5();b6e=200;o(w6e,"stackSet");$Y=w6e});function W0(t){var e=this.__data__=new Nh(t);this.size=e.size}var lc,Zv=N(()=>{"use strict";Kv();NY();IY();PY();FY();zY();o(W0,"Stack");W0.prototype.clear=RY;W0.prototype.delete=MY;W0.prototype.get=OY;W0.prototype.has=BY;W0.prototype.set=$Y;lc=W0});var T6e,q0,C9=N(()=>{"use strict";Lh();T6e=function(){try{var t=Ss(Object,"defineProperty");return t({},"",{}),t}catch{}}(),q0=T6e});function k6e(t,e,r){e=="__proto__"&&q0?q0(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}var cc,Y0=N(()=>{"use strict";C9();o(k6e,"baseAssignValue");cc=k6e});function E6e(t,e,r){(r!==void 0&&!Ro(t[e],r)||r===void 0&&!(e in t))&&cc(t,e,r)}var Jv,A9=N(()=>{"use strict";Y0();Sd();o(E6e,"assignMergeValue");Jv=E6e});function S6e(t){return function(e,r,n){for(var i=-1,a=Object(e),s=n(e),l=s.length;l--;){var u=s[t?l:++i];if(r(a[u],u,a)===!1)break}return e}}var GY,VY=N(()=>{"use strict";o(S6e,"createBaseFor");GY=S6e});var C6e,X0,Z5=N(()=>{"use strict";VY();C6e=GY(),X0=C6e});function _6e(t,e){if(e)return t.slice();var r=t.length,n=WY?WY(r):new t.constructor(r);return t.copy(n),n}var qY,UY,A6e,HY,WY,J5,_9=N(()=>{"use strict";Lo();qY=typeof exports=="object"&&exports&&!exports.nodeType&&exports,UY=qY&&typeof module=="object"&&module&&!module.nodeType&&module,A6e=UY&&UY.exports===qY,HY=A6e?li.Buffer:void 0,WY=HY?HY.allocUnsafe:void 0;o(_6e,"cloneBuffer");J5=_6e});var D6e,j0,D9=N(()=>{"use strict";Lo();D6e=li.Uint8Array,j0=D6e});function L6e(t){var e=new t.constructor(t.byteLength);return new j0(e).set(new j0(t)),e}var K0,ew=N(()=>{"use strict";D9();o(L6e,"cloneArrayBuffer");K0=L6e});function R6e(t,e){var r=e?K0(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}var tw,L9=N(()=>{"use strict";ew();o(R6e,"cloneTypedArray");tw=R6e});function N6e(t,e){var r=-1,n=t.length;for(e||(e=Array(n));++r<n;)e[r]=t[r];return e}var rw,R9=N(()=>{"use strict";o(N6e,"copyArray");rw=N6e});var YY,M6e,XY,jY=N(()=>{"use strict";Js();YY=Object.create,M6e=function(){function t(){}return o(t,"object"),function(e){if(!bn(e))return{};if(YY)return YY(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}(),XY=M6e});function I6e(t,e){return function(r){return t(e(r))}}var nw,N9=N(()=>{"use strict";o(I6e,"overArg");nw=I6e});var O6e,Q0,iw=N(()=>{"use strict";N9();O6e=nw(Object.getPrototypeOf,Object),Q0=O6e});function B6e(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||P6e;return t===r}var P6e,uc,Z0=N(()=>{"use strict";P6e=Object.prototype;o(B6e,"isPrototype");uc=B6e});function F6e(t){return typeof t.constructor=="function"&&!uc(t)?XY(Q0(t)):{}}var aw,M9=N(()=>{"use strict";jY();iw();Z0();o(F6e,"initCloneObject");aw=F6e});function $6e(t){return t!=null&&typeof t=="object"}var ri,No=N(()=>{"use strict";o($6e,"isObjectLike");ri=$6e});function G6e(t){return ri(t)&&da(t)==z6e}var z6e,I9,KY=N(()=>{"use strict";ku();No();z6e="[object Arguments]";o(G6e,"baseIsArguments");I9=G6e});var QY,V6e,U6e,H6e,El,J0=N(()=>{"use strict";KY();No();QY=Object.prototype,V6e=QY.hasOwnProperty,U6e=QY.propertyIsEnumerable,H6e=I9(function(){return arguments}())?I9:function(t){return ri(t)&&V6e.call(t,"callee")&&!U6e.call(t,"callee")},El=H6e});var W6e,Pt,Un=N(()=>{"use strict";W6e=Array.isArray,Pt=W6e});function Y6e(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=q6e}var q6e,em,sw=N(()=>{"use strict";q6e=9007199254740991;o(Y6e,"isLength");em=Y6e});function X6e(t){return t!=null&&em(t.length)&&!Si(t)}var ci,Mo=N(()=>{"use strict";Yv();sw();o(X6e,"isArrayLike");ci=X6e});function j6e(t){return ri(t)&&ci(t)}var Ad,ow=N(()=>{"use strict";Mo();No();o(j6e,"isArrayLikeObject");Ad=j6e});function K6e(){return!1}var ZY,JY=N(()=>{"use strict";o(K6e,"stubFalse");ZY=K6e});var rX,eX,Q6e,tX,Z6e,J6e,Sl,tm=N(()=>{"use strict";Lo();JY();rX=typeof exports=="object"&&exports&&!exports.nodeType&&exports,eX=rX&&typeof module=="object"&&module&&!module.nodeType&&module,Q6e=eX&&eX.exports===rX,tX=Q6e?li.Buffer:void 0,Z6e=tX?tX.isBuffer:void 0,J6e=Z6e||ZY,Sl=J6e});function aSe(t){if(!ri(t)||da(t)!=eSe)return!1;var e=Q0(t);if(e===null)return!0;var r=nSe.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&nX.call(r)==iSe}var eSe,tSe,rSe,nX,nSe,iSe,iX,aX=N(()=>{"use strict";ku();iw();No();eSe="[object Object]",tSe=Function.prototype,rSe=Object.prototype,nX=tSe.toString,nSe=rSe.hasOwnProperty,iSe=nX.call(Object);o(aSe,"isPlainObject");iX=aSe});function LSe(t){return ri(t)&&em(t.length)&&!!Fn[da(t)]}var sSe,oSe,lSe,cSe,uSe,hSe,fSe,dSe,pSe,mSe,gSe,ySe,vSe,xSe,bSe,wSe,TSe,kSe,ESe,SSe,CSe,ASe,_Se,DSe,Fn,sX,oX=N(()=>{"use strict";ku();sw();No();sSe="[object Arguments]",oSe="[object Array]",lSe="[object Boolean]",cSe="[object Date]",uSe="[object Error]",hSe="[object Function]",fSe="[object Map]",dSe="[object Number]",pSe="[object Object]",mSe="[object RegExp]",gSe="[object Set]",ySe="[object String]",vSe="[object WeakMap]",xSe="[object ArrayBuffer]",bSe="[object DataView]",wSe="[object Float32Array]",TSe="[object Float64Array]",kSe="[object Int8Array]",ESe="[object Int16Array]",SSe="[object Int32Array]",CSe="[object Uint8Array]",ASe="[object Uint8ClampedArray]",_Se="[object Uint16Array]",DSe="[object Uint32Array]",Fn={};Fn[wSe]=Fn[TSe]=Fn[kSe]=Fn[ESe]=Fn[SSe]=Fn[CSe]=Fn[ASe]=Fn[_Se]=Fn[DSe]=!0;Fn[sSe]=Fn[oSe]=Fn[xSe]=Fn[lSe]=Fn[bSe]=Fn[cSe]=Fn[uSe]=Fn[hSe]=Fn[fSe]=Fn[dSe]=Fn[pSe]=Fn[mSe]=Fn[gSe]=Fn[ySe]=Fn[vSe]=!1;o(LSe,"baseIsTypedArray");sX=LSe});function RSe(t){return function(e){return t(e)}}var Io,_d=N(()=>{"use strict";o(RSe,"baseUnary");Io=RSe});var lX,e2,NSe,O9,MSe,Oo,t2=N(()=>{"use strict";w9();lX=typeof exports=="object"&&exports&&!exports.nodeType&&exports,e2=lX&&typeof module=="object"&&module&&!module.nodeType&&module,NSe=e2&&e2.exports===lX,O9=NSe&&X5.process,MSe=function(){try{var t=e2&&e2.require&&e2.require("util").types;return t||O9&&O9.binding&&O9.binding("util")}catch{}}(),Oo=MSe});var cX,ISe,Oh,r2=N(()=>{"use strict";oX();_d();t2();cX=Oo&&Oo.isTypedArray,ISe=cX?Io(cX):sX,Oh=ISe});function OSe(t,e){if(!(e==="constructor"&&typeof t[e]=="function")&&e!="__proto__")return t[e]}var n2,P9=N(()=>{"use strict";o(OSe,"safeGet");n2=OSe});function FSe(t,e,r){var n=t[e];(!(BSe.call(t,e)&&Ro(n,r))||r===void 0&&!(e in t))&&cc(t,e,r)}var PSe,BSe,hc,rm=N(()=>{"use strict";Y0();Sd();PSe=Object.prototype,BSe=PSe.hasOwnProperty;o(FSe,"assignValue");hc=FSe});function $Se(t,e,r,n){var i=!r;r||(r={});for(var a=-1,s=e.length;++a<s;){var l=e[a],u=n?n(r[l],t[l],l,r,t):void 0;u===void 0&&(u=t[l]),i?cc(r,l,u):hc(r,l,u)}return r}var Po,Dd=N(()=>{"use strict";rm();Y0();o($Se,"copyObject");Po=$Se});function zSe(t,e){for(var r=-1,n=Array(t);++r<t;)n[r]=e(r);return n}var uX,hX=N(()=>{"use strict";o(zSe,"baseTimes");uX=zSe});function USe(t,e){var r=typeof t;return e=e??GSe,!!e&&(r=="number"||r!="symbol"&&VSe.test(t))&&t>-1&&t%1==0&&t<e}var GSe,VSe,Ph,i2=N(()=>{"use strict";GSe=9007199254740991,VSe=/^(?:0|[1-9]\d*)$/;o(USe,"isIndex");Ph=USe});function qSe(t,e){var r=Pt(t),n=!r&&El(t),i=!r&&!n&&Sl(t),a=!r&&!n&&!i&&Oh(t),s=r||n||i||a,l=s?uX(t.length,String):[],u=l.length;for(var h in t)(e||WSe.call(t,h))&&!(s&&(h=="length"||i&&(h=="offset"||h=="parent")||a&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||Ph(h,u)))&&l.push(h);return l}var HSe,WSe,lw,B9=N(()=>{"use strict";hX();J0();Un();tm();i2();r2();HSe=Object.prototype,WSe=HSe.hasOwnProperty;o(qSe,"arrayLikeKeys");lw=qSe});function YSe(t){var e=[];if(t!=null)for(var r in Object(t))e.push(r);return e}var fX,dX=N(()=>{"use strict";o(YSe,"nativeKeysIn");fX=YSe});function KSe(t){if(!bn(t))return fX(t);var e=uc(t),r=[];for(var n in t)n=="constructor"&&(e||!jSe.call(t,n))||r.push(n);return r}var XSe,jSe,pX,mX=N(()=>{"use strict";Js();Z0();dX();XSe=Object.prototype,jSe=XSe.hasOwnProperty;o(KSe,"baseKeysIn");pX=KSe});function QSe(t){return ci(t)?lw(t,!0):pX(t)}var Cs,Bh=N(()=>{"use strict";B9();mX();Mo();o(QSe,"keysIn");Cs=QSe});function ZSe(t){return Po(t,Cs(t))}var gX,yX=N(()=>{"use strict";Dd();Bh();o(ZSe,"toPlainObject");gX=ZSe});function JSe(t,e,r,n,i,a,s){var l=n2(t,r),u=n2(e,r),h=s.get(u);if(h){Jv(t,r,h);return}var f=a?a(l,u,r+"",t,e,s):void 0,d=f===void 0;if(d){var p=Pt(u),m=!p&&Sl(u),g=!p&&!m&&Oh(u);f=u,p||m||g?Pt(l)?f=l:Ad(l)?f=rw(l):m?(d=!1,f=J5(u,!0)):g?(d=!1,f=tw(u,!0)):f=[]:iX(u)||El(u)?(f=l,El(l)?f=gX(l):(!bn(l)||Si(l))&&(f=aw(u))):d=!1}d&&(s.set(u,f),i(f,u,n,a,s),s.delete(u)),Jv(t,r,f)}var vX,xX=N(()=>{"use strict";A9();_9();L9();R9();M9();J0();Un();ow();tm();Yv();Js();aX();r2();P9();yX();o(JSe,"baseMergeDeep");vX=JSe});function bX(t,e,r,n,i){t!==e&&X0(e,function(a,s){if(i||(i=new lc),bn(a))vX(t,e,s,r,bX,n,i);else{var l=n?n(n2(t,s),a,s+"",t,e,i):void 0;l===void 0&&(l=a),Jv(t,s,l)}},Cs)}var wX,TX=N(()=>{"use strict";Zv();A9();Z5();xX();Js();Bh();P9();o(bX,"baseMerge");wX=bX});function eCe(t){return t}var ta,Cu=N(()=>{"use strict";o(eCe,"identity");ta=eCe});function tCe(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}var kX,EX=N(()=>{"use strict";o(tCe,"apply");kX=tCe});function rCe(t,e,r){return e=SX(e===void 0?t.length-1:e,0),function(){for(var n=arguments,i=-1,a=SX(n.length-e,0),s=Array(a);++i<a;)s[i]=n[e+i];i=-1;for(var l=Array(e+1);++i<e;)l[i]=n[i];return l[e]=r(s),kX(t,this,l)}}var SX,cw,F9=N(()=>{"use strict";EX();SX=Math.max;o(rCe,"overRest");cw=rCe});function nCe(t){return function(){return t}}var As,$9=N(()=>{"use strict";o(nCe,"constant");As=nCe});var iCe,CX,AX=N(()=>{"use strict";$9();C9();Cu();iCe=q0?function(t,e){return q0(t,"toString",{configurable:!0,enumerable:!1,value:As(e),writable:!0})}:ta,CX=iCe});function lCe(t){var e=0,r=0;return function(){var n=oCe(),i=sCe-(n-r);if(r=n,i>0){if(++e>=aCe)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}var aCe,sCe,oCe,_X,DX=N(()=>{"use strict";aCe=800,sCe=16,oCe=Date.now;o(lCe,"shortOut");_X=lCe});var cCe,uw,z9=N(()=>{"use strict";AX();DX();cCe=_X(CX),uw=cCe});function uCe(t,e){return uw(cw(t,e,ta),t+"")}var fc,nm=N(()=>{"use strict";Cu();F9();z9();o(uCe,"baseRest");fc=uCe});function hCe(t,e,r){if(!bn(r))return!1;var n=typeof e;return(n=="number"?ci(r)&&Ph(e,r.length):n=="string"&&e in r)?Ro(r[e],t):!1}var eo,Ld=N(()=>{"use strict";Sd();Mo();i2();Js();o(hCe,"isIterateeCall");eo=hCe});function fCe(t){return fc(function(e,r){var n=-1,i=r.length,a=i>1?r[i-1]:void 0,s=i>2?r[2]:void 0;for(a=t.length>3&&typeof a=="function"?(i--,a):void 0,s&&eo(r[0],r[1],s)&&(a=i<3?void 0:a,i=1),e=Object(e);++n<i;){var l=r[n];l&&t(e,l,n,a)}return e})}var hw,G9=N(()=>{"use strict";nm();Ld();o(fCe,"createAssigner");hw=fCe});var dCe,Fh,V9=N(()=>{"use strict";TX();G9();dCe=hw(function(t,e,r){wX(t,e,r)}),Fh=dCe});function W9(t,e){if(!t)return e;let r=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return pCe[r]??e}function vCe(t,e){let r=t.trim();if(r)return e.securityLevel!=="loose"?(0,NX.sanitizeUrl)(r):r}function OX(t,e){return!t||!e?0:Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function bCe(t){let e,r=0;t.forEach(i=>{r+=OX(i,e),e=i});let n=r/2;return q9(t,n)}function wCe(t){return t.length===1?t[0]:bCe(t)}function kCe(t,e,r){let n=structuredClone(r);Y.info("our points",n),e!=="start_left"&&e!=="start_right"&&n.reverse();let i=25+t,a=q9(n,i),s=10+t*.5,l=Math.atan2(n[0].y-a.y,n[0].x-a.x),u={x:0,y:0};return e==="start_left"?(u.x=Math.sin(l+Math.PI)*s+(n[0].x+a.x)/2,u.y=-Math.cos(l+Math.PI)*s+(n[0].y+a.y)/2):e==="end_right"?(u.x=Math.sin(l-Math.PI)*s+(n[0].x+a.x)/2-5,u.y=-Math.cos(l-Math.PI)*s+(n[0].y+a.y)/2-5):e==="end_left"?(u.x=Math.sin(l)*s+(n[0].x+a.x)/2-5,u.y=-Math.cos(l)*s+(n[0].y+a.y)/2-5):(u.x=Math.sin(l)*s+(n[0].x+a.x)/2,u.y=-Math.cos(l)*s+(n[0].y+a.y)/2),u}function Y9(t){let e="",r="";for(let n of t)n!==void 0&&(n.startsWith("color:")||n.startsWith("text-align:")?r=r+n+";":e=e+n+";");return{style:e,labelStyle:r}}function ECe(t){let e="",r="0123456789abcdef",n=r.length;for(let i=0;i<t;i++)e+=r.charAt(Math.floor(Math.random()*n));return e}function dw(t,e){return Q9(t,e).height}function ra(t,e){return Q9(t,e).width}function Z9(t){return"str"in t}function Fi(t,e){return Fh({},t,e)}function $n(t){return t??null}var NX,H9,pCe,mCe,gCe,MX,IX,yCe,xCe,LX,q9,TCe,RX,X9,j9,SCe,CCe,K9,ACe,Q9,U9,fw,_Ce,DCe,Bo,Gt,PX,na,$h,ir=N(()=>{"use strict";NX=Sa(z0(),1);dr();gr();e7();vt();Xf();s0();S9();V9();$4();H9="\u200B",pCe={curveBasis:Do,curveBasisClosed:P5,curveBasisOpen:B5,curveBumpX:Rv,curveBumpY:Nv,curveBundle:l9,curveCardinalClosed:c9,curveCardinalOpen:h9,curveCardinal:Pv,curveCatmullRomClosed:d9,curveCatmullRomOpen:p9,curveCatmullRom:$v,curveLinear:wu,curveLinearClosed:V5,curveMonotoneX:zv,curveMonotoneY:Gv,curveNatural:F0,curveStep:$0,curveStepAfter:Uv,curveStepBefore:Vv},mCe=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,gCe=o(function(t,e){let r=MX(t,/(?:init\b)|(?:initialize\b)/),n={};if(Array.isArray(r)){let s=r.map(l=>l.args);l0(s),n=Gn(n,[...s])}else n=r.args;if(!n)return;let i=a0(t,e),a="config";return n[a]!==void 0&&(i==="flowchart-v2"&&(i="flowchart"),n[i]=n[a],delete n[a]),n},"detectInit"),MX=o(function(t,e=null){try{let r=new RegExp(`[%]{2}(?![{]${mCe.source})(?=[}][%]{2}).*
+`,"ig");t=t.trim().replace(r,"").replace(/'/gm,'"'),Y.debug(`Detecting diagram directive${e!==null?" type:"+e:""} based on the text:${t}`);let n,i=[];for(;(n=qf.exec(t))!==null;)if(n.index===qf.lastIndex&&qf.lastIndex++,n&&!e||e&&n[1]?.match(e)||e&&n[2]?.match(e)){let a=n[1]?n[1]:n[2],s=n[3]?n[3].trim():n[4]?JSON.parse(n[4].trim()):null;i.push({type:a,args:s})}return i.length===0?{type:t,args:null}:i.length===1?i[0]:i}catch(r){return Y.error(`ERROR: ${r.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}},"detectDirective"),IX=o(function(t){return t.replace(qf,"")},"removeDirectives"),yCe=o(function(t,e){for(let[r,n]of e.entries())if(n.match(t))return r;return-1},"isSubstringInArray");o(W9,"interpolateToCurve");o(vCe,"formatUrl");xCe=o((t,...e)=>{let r=t.split("."),n=r.length-1,i=r[n],a=window;for(let s=0;s<n;s++)if(a=a[r[s]],!a){Y.error(`Function name: ${t} not found in window`);return}a[i](...e)},"runFunc");o(OX,"distance");o(bCe,"traverseEdge");o(wCe,"calcLabelPosition");LX=o((t,e=2)=>{let r=Math.pow(10,e);return Math.round(t*r)/r},"roundNumber"),q9=o((t,e)=>{let r,n=e;for(let i of t){if(r){let a=OX(i,r);if(a===0)return r;if(a<n)n-=a;else{let s=n/a;if(s<=0)return r;if(s>=1)return{x:i.x,y:i.y};if(s>0&&s<1)return{x:LX((1-s)*r.x+s*i.x,5),y:LX((1-s)*r.y+s*i.y,5)}}}r=i}throw new Error("Could not find a suitable point for the given distance")},"calculatePoint"),TCe=o((t,e,r)=>{Y.info(`our points ${JSON.stringify(e)}`),e[0]!==r&&(e=e.reverse());let i=q9(e,25),a=t?10:5,s=Math.atan2(e[0].y-i.y,e[0].x-i.x),l={x:0,y:0};return l.x=Math.sin(s)*a+(e[0].x+i.x)/2,l.y=-Math.cos(s)*a+(e[0].y+i.y)/2,l},"calcCardinalityPosition");o(kCe,"calcTerminalLabelPosition");o(Y9,"getStylesFromArray");RX=0,X9=o(()=>(RX++,"id-"+Math.random().toString(36).substr(2,12)+"-"+RX),"generateId");o(ECe,"makeRandomHex");j9=o(t=>ECe(t.length),"random"),SCe=o(function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}},"getTextObj"),CCe=o(function(t,e){let r=e.text.replace(Ze.lineBreakRegex," "),[,n]=Bo(e.fontSize),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.style("text-anchor",e.anchor),i.style("font-family",e.fontFamily),i.style("font-size",n),i.style("font-weight",e.fontWeight),i.attr("fill",e.fill),e.class!==void 0&&i.attr("class",e.class);let a=i.append("tspan");return a.attr("x",e.x+e.textMargin*2),a.attr("fill",e.fill),a.text(r),i},"drawSimpleText"),K9=H0((t,e,r)=>{if(!t||(r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},r),Ze.lineBreakRegex.test(t)))return t;let n=t.split(" ").filter(Boolean),i=[],a="";return n.forEach((s,l)=>{let u=ra(`${s} `,r),h=ra(a,r);if(u>e){let{hyphenatedStrings:p,remainingWord:m}=ACe(s,e,"-",r);i.push(a,...p),a=m}else h+u>=e?(i.push(a),a=s):a=[a,s].filter(Boolean).join(" ");l+1===n.length&&i.push(a)}),i.filter(s=>s!=="").join(r.joinWith)},(t,e,r)=>`${t}${e}${r.fontSize}${r.fontWeight}${r.fontFamily}${r.joinWith}`),ACe=H0((t,e,r="-",n)=>{n=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},n);let i=[...t],a=[],s="";return i.forEach((l,u)=>{let h=`${s}${l}`;if(ra(h,n)>=e){let d=u+1,p=i.length===d,m=`${h}${r}`;a.push(p?h:m),s=""}else s=h}),{hyphenatedStrings:a,remainingWord:s}},(t,e,r="-",n)=>`${t}${e}${r}${n.fontSize}${n.fontWeight}${n.fontFamily}`);o(dw,"calculateTextHeight");o(ra,"calculateTextWidth");Q9=H0((t,e)=>{let{fontSize:r=12,fontFamily:n="Arial",fontWeight:i=400}=e;if(!t)return{width:0,height:0};let[,a]=Bo(r),s=["sans-serif",n],l=t.split(Ze.lineBreakRegex),u=[],h=Ge("body");if(!h.remove)return{width:0,height:0,lineHeight:0};let f=h.append("svg");for(let p of s){let m=0,g={width:0,height:0,lineHeight:0};for(let y of l){let v=SCe();v.text=y||H9;let x=CCe(f,v).style("font-size",a).style("font-weight",i).style("font-family",p),b=(x._groups||x)[0][0].getBBox();if(b.width===0&&b.height===0)throw new Error("svg element not in render tree");g.width=Math.round(Math.max(g.width,b.width)),m=Math.round(b.height),g.height+=m,g.lineHeight=Math.round(Math.max(g.lineHeight,m))}u.push(g)}f.remove();let d=isNaN(u[1].height)||isNaN(u[1].width)||isNaN(u[1].lineHeight)||u[0].height>u[1].height&&u[0].width>u[1].width&&u[0].lineHeight>u[1].lineHeight?0:1;return u[d]},(t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`),U9=class{constructor(e=!1,r){this.count=0;this.count=r?r.length:0,this.next=e?()=>this.count++:()=>Date.now()}static{o(this,"InitIDGenerator")}},_Ce=o(function(t){return fw=fw||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),fw.innerHTML=t,unescape(fw.textContent)},"entityDecode");o(Z9,"isDetailedError");DCe=o((t,e,r,n)=>{if(!n)return;let i=t.node()?.getBBox();i&&t.append("text").text(n).attr("text-anchor","middle").attr("x",i.x+i.width/2).attr("y",-r).attr("class",e)},"insertTitle"),Bo=o(t=>{if(typeof t=="number")return[t,t+"px"];let e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]},"parseFontSize");o(Fi,"cleanAndMerge");Gt={assignWithDepth:Gn,wrapLabel:K9,calculateTextHeight:dw,calculateTextWidth:ra,calculateTextDimensions:Q9,cleanAndMerge:Fi,detectInit:gCe,detectDirective:MX,isSubstringInArray:yCe,interpolateToCurve:W9,calcLabelPosition:wCe,calcCardinalityPosition:TCe,calcTerminalLabelPosition:kCe,formatUrl:vCe,getStylesFromArray:Y9,generateId:X9,random:j9,runFunc:xCe,entityDecode:_Ce,insertTitle:DCe,parseFontSize:Bo,InitIDGenerator:U9},PX=o(function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,function(r){return r.substring(0,r.length-1)}),e=e.replace(/classDef.*:\S*#.*;/g,function(r){return r.substring(0,r.length-1)}),e=e.replace(/#\w+;/g,function(r){let n=r.substring(1,r.length-1);return/^\+?\d+$/.test(n)?"\uFB02\xB0\xB0"+n+"\xB6\xDF":"\uFB02\xB0"+n+"\xB6\xDF"}),e},"encodeEntities"),na=o(function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},"decodeEntities"),$h=o((t,e,{counter:r=0,prefix:n,suffix:i},a)=>a||`${n?`${n}_`:""}${t}_${e}_${r}${i?`_${i}`:""}`,"getEdgeId");o($n,"handleUndefinedAttr")});function Cl(t,e,r,n,i){if(!e[t].width)if(r)e[t].text=K9(e[t].text,i,n),e[t].textLines=e[t].text.split(Ze.lineBreakRegex).length,e[t].width=i,e[t].height=dw(e[t].text,n);else{let a=e[t].text.split(Ze.lineBreakRegex);e[t].textLines=a.length;let s=0;e[t].height=0,e[t].width=0;for(let l of a)e[t].width=Math.max(ra(l,n),e[t].width),s=dw(l,n),e[t].height=e[t].height+s}}function GX(t,e,r,n,i){let a=new yw(i);a.data.widthLimit=r.data.widthLimit/Math.min(J9,n.length);for(let[s,l]of n.entries()){let u=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=u,u=l.image.Y+l.image.height);let h=l.wrap&&Vt.wrap,f=pw(Vt);if(f.fontSize=f.fontSize+2,f.fontWeight="bold",Cl("label",l,h,f,a.data.widthLimit),l.label.Y=u+8,u=l.label.Y+l.label.height,l.type&&l.type.text!==""){l.type.text="["+l.type.text+"]";let g=pw(Vt);Cl("type",l,h,g,a.data.widthLimit),l.type.Y=u+5,u=l.type.Y+l.type.height}if(l.descr&&l.descr.text!==""){let g=pw(Vt);g.fontSize=g.fontSize-2,Cl("descr",l,h,g,a.data.widthLimit),l.descr.Y=u+20,u=l.descr.Y+l.descr.height}if(s==0||s%J9===0){let g=r.data.startx+Vt.diagramMarginX,y=r.data.stopy+Vt.diagramMarginY+u;a.setData(g,g,y,y)}else{let g=a.data.stopx!==a.data.startx?a.data.stopx+Vt.diagramMarginX:a.data.startx,y=a.data.starty;a.setData(g,g,y,y)}a.name=l.alias;let d=i.db.getC4ShapeArray(l.alias),p=i.db.getC4ShapeKeys(l.alias);p.length>0&&zX(a,t,d,p),e=l.alias;let m=i.db.getBoundarys(e);m.length>0&&GX(t,e,a,m,i),l.alias!=="global"&&$X(t,l,a),r.data.stopy=Math.max(a.data.stopy+Vt.c4ShapeMargin,r.data.stopy),r.data.stopx=Math.max(a.data.stopx+Vt.c4ShapeMargin,r.data.stopx),mw=Math.max(mw,r.data.stopx),gw=Math.max(gw,r.data.stopy)}}var mw,gw,FX,J9,Vt,yw,eD,a2,pw,LCe,$X,zX,_s,BX,RCe,NCe,MCe,tD,VX=N(()=>{"use strict";dr();Bq();vt();$C();gr();uA();zt();s0();ir();Ei();mw=0,gw=0,FX=4,J9=2;Ty.yy=Qy;Vt={},yw=class{static{o(this,"Bounds")}constructor(e){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,eD(e.db.getConfig())}setData(e,r,n,i){this.nextData.startx=this.data.startx=e,this.nextData.stopx=this.data.stopx=r,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=i}updateVal(e,r,n,i){e[r]===void 0?e[r]=n:e[r]=i(n,e[r])}insert(e){this.nextData.cnt=this.nextData.cnt+1;let r=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+e.margin:this.nextData.stopx+e.margin*2,n=r+e.width,i=this.nextData.starty+e.margin*2,a=i+e.height;(r>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>FX)&&(r=this.nextData.startx+e.margin+Vt.nextLinePaddingX,i=this.nextData.stopy+e.margin*2,this.nextData.stopx=n=r+e.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=a=i+e.height,this.nextData.cnt=1),e.x=r,e.y=i,this.updateVal(this.data,"startx",r,Math.min),this.updateVal(this.data,"starty",i,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",a,Math.max),this.updateVal(this.nextData,"startx",r,Math.min),this.updateVal(this.nextData,"starty",i,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",a,Math.max)}init(e){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},eD(e.db.getConfig())}bumpLastMargin(e){this.data.stopx+=e,this.data.stopy+=e}},eD=o(function(t){Gn(Vt,t),t.fontFamily&&(Vt.personFontFamily=Vt.systemFontFamily=Vt.messageFontFamily=t.fontFamily),t.fontSize&&(Vt.personFontSize=Vt.systemFontSize=Vt.messageFontSize=t.fontSize),t.fontWeight&&(Vt.personFontWeight=Vt.systemFontWeight=Vt.messageFontWeight=t.fontWeight)},"setConf"),a2=o((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),"c4ShapeFont"),pw=o(t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight}),"boundaryFont"),LCe=o(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont");o(Cl,"calcC4ShapeTextWH");$X=o(function(t,e,r){e.x=r.data.startx,e.y=r.data.starty,e.width=r.data.stopx-r.data.startx,e.height=r.data.stopy-r.data.starty,e.label.y=Vt.c4ShapeMargin-35;let n=e.wrap&&Vt.wrap,i=pw(Vt);i.fontSize=i.fontSize+2,i.fontWeight="bold";let a=ra(e.label.text,i);Cl("label",e,n,i,a),kl.drawBoundary(t,e,Vt)},"drawBoundary"),zX=o(function(t,e,r,n){let i=0;for(let a of n){i=0;let s=r[a],l=a2(Vt,s.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,s.typeC4Shape.width=ra("\xAB"+s.typeC4Shape.text+"\xBB",l),s.typeC4Shape.height=l.fontSize+2,s.typeC4Shape.Y=Vt.c4ShapePadding,i=s.typeC4Shape.Y+s.typeC4Shape.height-4,s.image={width:0,height:0,Y:0},s.typeC4Shape.text){case"person":case"external_person":s.image.width=48,s.image.height=48,s.image.Y=i,i=s.image.Y+s.image.height;break}s.sprite&&(s.image.width=48,s.image.height=48,s.image.Y=i,i=s.image.Y+s.image.height);let u=s.wrap&&Vt.wrap,h=Vt.width-Vt.c4ShapePadding*2,f=a2(Vt,s.typeC4Shape.text);if(f.fontSize=f.fontSize+2,f.fontWeight="bold",Cl("label",s,u,f,h),s.label.Y=i+8,i=s.label.Y+s.label.height,s.type&&s.type.text!==""){s.type.text="["+s.type.text+"]";let m=a2(Vt,s.typeC4Shape.text);Cl("type",s,u,m,h),s.type.Y=i+5,i=s.type.Y+s.type.height}else if(s.techn&&s.techn.text!==""){s.techn.text="["+s.techn.text+"]";let m=a2(Vt,s.techn.text);Cl("techn",s,u,m,h),s.techn.Y=i+5,i=s.techn.Y+s.techn.height}let d=i,p=s.label.width;if(s.descr&&s.descr.text!==""){let m=a2(Vt,s.typeC4Shape.text);Cl("descr",s,u,m,h),s.descr.Y=i+20,i=s.descr.Y+s.descr.height,p=Math.max(s.label.width,s.descr.width),d=i-s.descr.textLines*5}p=p+Vt.c4ShapePadding,s.width=Math.max(s.width||Vt.width,p,Vt.width),s.height=Math.max(s.height||Vt.height,d,Vt.height),s.margin=s.margin||Vt.c4ShapeMargin,t.insert(s),kl.drawC4Shape(e,s,Vt)}t.bumpLastMargin(Vt.c4ShapeMargin)},"drawC4ShapeArray"),_s=class{static{o(this,"Point")}constructor(e,r){this.x=e,this.y=r}},BX=o(function(t,e){let r=t.x,n=t.y,i=e.x,a=e.y,s=r+t.width/2,l=n+t.height/2,u=Math.abs(r-i),h=Math.abs(n-a),f=h/u,d=t.height/t.width,p=null;return n==a&&r<i?p=new _s(r+t.width,l):n==a&&r>i?p=new _s(r,l):r==i&&n<a?p=new _s(s,n+t.height):r==i&&n>a&&(p=new _s(s,n)),r>i&&n<a?d>=f?p=new _s(r,l+f*t.width/2):p=new _s(s-u/h*t.height/2,n+t.height):r<i&&n<a?d>=f?p=new _s(r+t.width,l+f*t.width/2):p=new _s(s+u/h*t.height/2,n+t.height):r<i&&n>a?d>=f?p=new _s(r+t.width,l-f*t.width/2):p=new _s(s+t.height/2*u/h,n):r>i&&n>a&&(d>=f?p=new _s(r,l-t.width/2*f):p=new _s(s-t.height/2*u/h,n)),p},"getIntersectPoint"),RCe=o(function(t,e){let r={x:0,y:0};r.x=e.x+e.width/2,r.y=e.y+e.height/2;let n=BX(t,r);r.x=t.x+t.width/2,r.y=t.y+t.height/2;let i=BX(e,r);return{startPoint:n,endPoint:i}},"getIntersectPoints"),NCe=o(function(t,e,r,n){let i=0;for(let a of e){i=i+1;let s=a.wrap&&Vt.wrap,l=LCe(Vt);n.db.getC4Type()==="C4Dynamic"&&(a.label.text=i+": "+a.label.text);let h=ra(a.label.text,l);Cl("label",a,s,l,h),a.techn&&a.techn.text!==""&&(h=ra(a.techn.text,l),Cl("techn",a,s,l,h)),a.descr&&a.descr.text!==""&&(h=ra(a.descr.text,l),Cl("descr",a,s,l,h));let f=r(a.from),d=r(a.to),p=RCe(f,d);a.startPoint=p.startPoint,a.endPoint=p.endPoint}kl.drawRels(t,e,Vt)},"drawRels");o(GX,"drawInsideBoundary");MCe=o(function(t,e,r,n){Vt=me().c4;let i=me().securityLevel,a;i==="sandbox"&&(a=Ge("#i"+e));let s=i==="sandbox"?Ge(a.nodes()[0].contentDocument.body):Ge("body"),l=n.db;n.db.setWrap(Vt.wrap),FX=l.getC4ShapeInRow(),J9=l.getC4BoundaryInRow(),Y.debug(`C:${JSON.stringify(Vt,null,2)}`);let u=i==="sandbox"?s.select(`[id="${e}"]`):Ge(`[id="${e}"]`);kl.insertComputerIcon(u),kl.insertDatabaseIcon(u),kl.insertClockIcon(u);let h=new yw(n);h.setData(Vt.diagramMarginX,Vt.diagramMarginX,Vt.diagramMarginY,Vt.diagramMarginY),h.data.widthLimit=screen.availWidth,mw=Vt.diagramMarginX,gw=Vt.diagramMarginY;let f=n.db.getTitle(),d=n.db.getBoundarys("");GX(u,"",h,d,n),kl.insertArrowHead(u),kl.insertArrowEnd(u),kl.insertArrowCrossHead(u),kl.insertArrowFilledHead(u),NCe(u,n.db.getRels(),n.db.getC4Shape,n),h.data.stopx=mw,h.data.stopy=gw;let p=h.data,g=p.stopy-p.starty+2*Vt.diagramMarginY,v=p.stopx-p.startx+2*Vt.diagramMarginX;f&&u.append("text").text(f).attr("x",(p.stopx-p.startx)/2-4*Vt.diagramMarginX).attr("y",p.starty+Vt.diagramMarginY),vn(u,g,v,Vt.useMaxWidth);let x=f?60:0;u.attr("viewBox",p.startx-Vt.diagramMarginX+" -"+(Vt.diagramMarginY+x)+" "+v+" "+(g+x)),Y.debug("models:",p)},"draw"),tD={drawPersonOrSystemArray:zX,drawBoundary:$X,setConf:eD,draw:MCe}});var ICe,UX,HX=N(()=>{"use strict";ICe=o(t=>`.person {
+ stroke: ${t.personBorder};
+ fill: ${t.personBkg};
+ }
+`,"getStyles"),UX=ICe});var WX={};hr(WX,{diagram:()=>OCe});var OCe,qX=N(()=>{"use strict";$C();uA();VX();HX();OCe={parser:JF,db:Qy,renderer:tD,styles:UX,init:o(({c4:t,wrap:e})=>{tD.setConf(t),Qy.setWrap(e)},"init")}});function uj(t){return typeof t>"u"||t===null}function $Ce(t){return typeof t=="object"&&t!==null}function zCe(t){return Array.isArray(t)?t:uj(t)?[]:[t]}function GCe(t,e){var r,n,i,a;if(e)for(a=Object.keys(e),r=0,n=a.length;r<n;r+=1)i=a[r],t[i]=e[i];return t}function VCe(t,e){var r="",n;for(n=0;n<e;n+=1)r+=t;return r}function UCe(t){return t===0&&Number.NEGATIVE_INFINITY===1/t}function hj(t,e){var r="",n=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(r+='in "'+t.mark.name+'" '),r+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(r+=`
+
+`+t.mark.snippet),n+" "+r):n}function o2(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=hj(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}function rD(t,e,r,n,i){var a="",s="",l=Math.floor(i/2)-1;return n-e>l&&(a=" ... ",e=n-l+a.length),r-n>l&&(s=" ...",r=n+l-s.length),{str:a+t.slice(e,r).replace(/\t/g,"\u2192")+s,pos:n-e+a.length}}function nD(t,e){return $i.repeat(" ",e-t.length)+t}function KCe(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),typeof e.indent!="number"&&(e.indent=1),typeof e.linesBefore!="number"&&(e.linesBefore=3),typeof e.linesAfter!="number"&&(e.linesAfter=2);for(var r=/\r?\n|\r|\0/g,n=[0],i=[],a,s=-1;a=r.exec(t.buffer);)i.push(a.index),n.push(a.index+a[0].length),t.position<=a.index&&s<0&&(s=n.length-2);s<0&&(s=n.length-1);var l="",u,h,f=Math.min(t.line+e.linesAfter,i.length).toString().length,d=e.maxLength-(e.indent+f+3);for(u=1;u<=e.linesBefore&&!(s-u<0);u++)h=rD(t.buffer,n[s-u],i[s-u],t.position-(n[s]-n[s-u]),d),l=$i.repeat(" ",e.indent)+nD((t.line-u+1).toString(),f)+" | "+h.str+`
+`+l;for(h=rD(t.buffer,n[s],i[s],t.position,d),l+=$i.repeat(" ",e.indent)+nD((t.line+1).toString(),f)+" | "+h.str+`
+`,l+=$i.repeat("-",e.indent+f+3+h.pos)+`^
+`,u=1;u<=e.linesAfter&&!(s+u>=i.length);u++)h=rD(t.buffer,n[s+u],i[s+u],t.position-(n[s]-n[s+u]),d),l+=$i.repeat(" ",e.indent)+nD((t.line+u+1).toString(),f)+" | "+h.str+`
+`;return l.replace(/\n$/,"")}function e7e(t){var e={};return t!==null&&Object.keys(t).forEach(function(r){t[r].forEach(function(n){e[String(n)]=r})}),e}function t7e(t,e){if(e=e||{},Object.keys(e).forEach(function(r){if(ZCe.indexOf(r)===-1)throw new Ds('Unknown option "'+r+'" is met in definition of "'+t+'" YAML type.')}),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(r){return r},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=e7e(e.styleAliases||null),JCe.indexOf(this.kind)===-1)throw new Ds('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}function jX(t,e){var r=[];return t[e].forEach(function(n){var i=r.length;r.forEach(function(a,s){a.tag===n.tag&&a.kind===n.kind&&a.multi===n.multi&&(i=s)}),r[i]=n}),r}function r7e(){var t={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}},e,r;function n(i){i.multi?(t.multi[i.kind].push(i),t.multi.fallback.push(i)):t[i.kind][i.tag]=t.fallback[i.tag]=i}for(o(n,"collectType"),e=0,r=arguments.length;e<r;e+=1)arguments[e].forEach(n);return t}function aD(t){return this.extend(t)}function l7e(t){if(t===null)return!0;var e=t.length;return e===1&&t==="~"||e===4&&(t==="null"||t==="Null"||t==="NULL")}function c7e(){return null}function u7e(t){return t===null}function f7e(t){if(t===null)return!1;var e=t.length;return e===4&&(t==="true"||t==="True"||t==="TRUE")||e===5&&(t==="false"||t==="False"||t==="FALSE")}function d7e(t){return t==="true"||t==="True"||t==="TRUE"}function p7e(t){return Object.prototype.toString.call(t)==="[object Boolean]"}function g7e(t){return 48<=t&&t<=57||65<=t&&t<=70||97<=t&&t<=102}function y7e(t){return 48<=t&&t<=55}function v7e(t){return 48<=t&&t<=57}function x7e(t){if(t===null)return!1;var e=t.length,r=0,n=!1,i;if(!e)return!1;if(i=t[r],(i==="-"||i==="+")&&(i=t[++r]),i==="0"){if(r+1===e)return!0;if(i=t[++r],i==="b"){for(r++;r<e;r++)if(i=t[r],i!=="_"){if(i!=="0"&&i!=="1")return!1;n=!0}return n&&i!=="_"}if(i==="x"){for(r++;r<e;r++)if(i=t[r],i!=="_"){if(!g7e(t.charCodeAt(r)))return!1;n=!0}return n&&i!=="_"}if(i==="o"){for(r++;r<e;r++)if(i=t[r],i!=="_"){if(!y7e(t.charCodeAt(r)))return!1;n=!0}return n&&i!=="_"}}if(i==="_")return!1;for(;r<e;r++)if(i=t[r],i!=="_"){if(!v7e(t.charCodeAt(r)))return!1;n=!0}return!(!n||i==="_")}function b7e(t){var e=t,r=1,n;if(e.indexOf("_")!==-1&&(e=e.replace(/_/g,"")),n=e[0],(n==="-"||n==="+")&&(n==="-"&&(r=-1),e=e.slice(1),n=e[0]),e==="0")return 0;if(n==="0"){if(e[1]==="b")return r*parseInt(e.slice(2),2);if(e[1]==="x")return r*parseInt(e.slice(2),16);if(e[1]==="o")return r*parseInt(e.slice(2),8)}return r*parseInt(e,10)}function w7e(t){return Object.prototype.toString.call(t)==="[object Number]"&&t%1===0&&!$i.isNegativeZero(t)}function E7e(t){return!(t===null||!k7e.test(t)||t[t.length-1]==="_")}function S7e(t){var e,r;return e=t.replace(/_/g,"").toLowerCase(),r=e[0]==="-"?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:r*parseFloat(e,10)}function A7e(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if($i.isNegativeZero(t))return"-0.0";return r=t.toString(10),C7e.test(r)?r.replace("e",".e"):r}function _7e(t){return Object.prototype.toString.call(t)==="[object Number]"&&(t%1!==0||$i.isNegativeZero(t))}function R7e(t){return t===null?!1:dj.exec(t)!==null||pj.exec(t)!==null}function N7e(t){var e,r,n,i,a,s,l,u=0,h=null,f,d,p;if(e=dj.exec(t),e===null&&(e=pj.exec(t)),e===null)throw new Error("Date resolve error");if(r=+e[1],n=+e[2]-1,i=+e[3],!e[4])return new Date(Date.UTC(r,n,i));if(a=+e[4],s=+e[5],l=+e[6],e[7]){for(u=e[7].slice(0,3);u.length<3;)u+="0";u=+u}return e[9]&&(f=+e[10],d=+(e[11]||0),h=(f*60+d)*6e4,e[9]==="-"&&(h=-h)),p=new Date(Date.UTC(r,n,i,a,s,l,u)),h&&p.setTime(p.getTime()-h),p}function M7e(t){return t.toISOString()}function O7e(t){return t==="<<"||t===null}function B7e(t){if(t===null)return!1;var e,r,n=0,i=t.length,a=uD;for(r=0;r<i;r++)if(e=a.indexOf(t.charAt(r)),!(e>64)){if(e<0)return!1;n+=6}return n%8===0}function F7e(t){var e,r,n=t.replace(/[\r\n=]/g,""),i=n.length,a=uD,s=0,l=[];for(e=0;e<i;e++)e%4===0&&e&&(l.push(s>>16&255),l.push(s>>8&255),l.push(s&255)),s=s<<6|a.indexOf(n.charAt(e));return r=i%4*6,r===0?(l.push(s>>16&255),l.push(s>>8&255),l.push(s&255)):r===18?(l.push(s>>10&255),l.push(s>>2&255)):r===12&&l.push(s>>4&255),new Uint8Array(l)}function $7e(t){var e="",r=0,n,i,a=t.length,s=uD;for(n=0;n<a;n++)n%3===0&&n&&(e+=s[r>>18&63],e+=s[r>>12&63],e+=s[r>>6&63],e+=s[r&63]),r=(r<<8)+t[n];return i=a%3,i===0?(e+=s[r>>18&63],e+=s[r>>12&63],e+=s[r>>6&63],e+=s[r&63]):i===2?(e+=s[r>>10&63],e+=s[r>>4&63],e+=s[r<<2&63],e+=s[64]):i===1&&(e+=s[r>>2&63],e+=s[r<<4&63],e+=s[64],e+=s[64]),e}function z7e(t){return Object.prototype.toString.call(t)==="[object Uint8Array]"}function H7e(t){if(t===null)return!0;var e=[],r,n,i,a,s,l=t;for(r=0,n=l.length;r<n;r+=1){if(i=l[r],s=!1,U7e.call(i)!=="[object Object]")return!1;for(a in i)if(V7e.call(i,a))if(!s)s=!0;else return!1;if(!s)return!1;if(e.indexOf(a)===-1)e.push(a);else return!1}return!0}function W7e(t){return t!==null?t:[]}function X7e(t){if(t===null)return!0;var e,r,n,i,a,s=t;for(a=new Array(s.length),e=0,r=s.length;e<r;e+=1){if(n=s[e],Y7e.call(n)!=="[object Object]"||(i=Object.keys(n),i.length!==1))return!1;a[e]=[i[0],n[i[0]]]}return!0}function j7e(t){if(t===null)return[];var e,r,n,i,a,s=t;for(a=new Array(s.length),e=0,r=s.length;e<r;e+=1)n=s[e],i=Object.keys(n),a[e]=[i[0],n[i[0]]];return a}function Z7e(t){if(t===null)return!0;var e,r=t;for(e in r)if(Q7e.call(r,e)&&r[e]!==null)return!1;return!0}function J7e(t){return t!==null?t:{}}function QX(t){return Object.prototype.toString.call(t)}function dc(t){return t===10||t===13}function Nd(t){return t===9||t===32}function Ls(t){return t===9||t===32||t===10||t===13}function am(t){return t===44||t===91||t===93||t===123||t===125}function aAe(t){var e;return 48<=t&&t<=57?t-48:(e=t|32,97<=e&&e<=102?e-97+10:-1)}function sAe(t){return t===120?2:t===117?4:t===85?8:0}function oAe(t){return 48<=t&&t<=57?t-48:-1}function ZX(t){return t===48?"\0":t===97?"\x07":t===98?"\b":t===116||t===9?" ":t===110?`
+`:t===118?"\v":t===102?"\f":t===114?"\r":t===101?"\x1B":t===32?" ":t===34?'"':t===47?"/":t===92?"\\":t===78?"\x85":t===95?"\xA0":t===76?"\u2028":t===80?"\u2029":""}function lAe(t){return t<=65535?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}function cAe(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||mj,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function Tj(t,e){var r={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return r.snippet=QCe(r),new Ds(e,r)}function Qt(t,e){throw Tj(t,e)}function bw(t,e){t.onWarning&&t.onWarning.call(null,Tj(t,e))}function zh(t,e,r,n){var i,a,s,l;if(e<r){if(l=t.input.slice(e,r),n)for(i=0,a=l.length;i<a;i+=1)s=l.charCodeAt(i),s===9||32<=s&&s<=1114111||Qt(t,"expected valid JSON character");else rAe.test(l)&&Qt(t,"the stream contains non-printable characters");t.result+=l}}function ej(t,e,r,n){var i,a,s,l;for($i.isObject(r)||Qt(t,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(r),s=0,l=i.length;s<l;s+=1)a=i[s],Gh.call(e,a)||(e[a]=r[a],n[a]=!0)}function sm(t,e,r,n,i,a,s,l,u){var h,f;if(Array.isArray(i))for(i=Array.prototype.slice.call(i),h=0,f=i.length;h<f;h+=1)Array.isArray(i[h])&&Qt(t,"nested arrays are not supported inside keys"),typeof i=="object"&&QX(i[h])==="[object Object]"&&(i[h]="[object Object]");if(typeof i=="object"&&QX(i)==="[object Object]"&&(i="[object Object]"),i=String(i),e===null&&(e={}),n==="tag:yaml.org,2002:merge")if(Array.isArray(a))for(h=0,f=a.length;h<f;h+=1)ej(t,e,a[h],r);else ej(t,e,a,r);else!t.json&&!Gh.call(r,i)&&Gh.call(e,i)&&(t.line=s||t.line,t.lineStart=l||t.lineStart,t.position=u||t.position,Qt(t,"duplicated mapping key")),i==="__proto__"?Object.defineProperty(e,i,{configurable:!0,enumerable:!0,writable:!0,value:a}):e[i]=a,delete r[i];return e}function hD(t){var e;e=t.input.charCodeAt(t.position),e===10?t.position++:e===13?(t.position++,t.input.charCodeAt(t.position)===10&&t.position++):Qt(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function Ci(t,e,r){for(var n=0,i=t.input.charCodeAt(t.position);i!==0;){for(;Nd(i);)i===9&&t.firstTabInLine===-1&&(t.firstTabInLine=t.position),i=t.input.charCodeAt(++t.position);if(e&&i===35)do i=t.input.charCodeAt(++t.position);while(i!==10&&i!==13&&i!==0);if(dc(i))for(hD(t),i=t.input.charCodeAt(t.position),n++,t.lineIndent=0;i===32;)t.lineIndent++,i=t.input.charCodeAt(++t.position);else break}return r!==-1&&n!==0&&t.lineIndent<r&&bw(t,"deficient indentation"),n}function kw(t){var e=t.position,r;return r=t.input.charCodeAt(e),!!((r===45||r===46)&&r===t.input.charCodeAt(e+1)&&r===t.input.charCodeAt(e+2)&&(e+=3,r=t.input.charCodeAt(e),r===0||Ls(r)))}function fD(t,e){e===1?t.result+=" ":e>1&&(t.result+=$i.repeat(`
+`,e-1))}function uAe(t,e,r){var n,i,a,s,l,u,h,f,d=t.kind,p=t.result,m;if(m=t.input.charCodeAt(t.position),Ls(m)||am(m)||m===35||m===38||m===42||m===33||m===124||m===62||m===39||m===34||m===37||m===64||m===96||(m===63||m===45)&&(i=t.input.charCodeAt(t.position+1),Ls(i)||r&&am(i)))return!1;for(t.kind="scalar",t.result="",a=s=t.position,l=!1;m!==0;){if(m===58){if(i=t.input.charCodeAt(t.position+1),Ls(i)||r&&am(i))break}else if(m===35){if(n=t.input.charCodeAt(t.position-1),Ls(n))break}else{if(t.position===t.lineStart&&kw(t)||r&&am(m))break;if(dc(m))if(u=t.line,h=t.lineStart,f=t.lineIndent,Ci(t,!1,-1),t.lineIndent>=e){l=!0,m=t.input.charCodeAt(t.position);continue}else{t.position=s,t.line=u,t.lineStart=h,t.lineIndent=f;break}}l&&(zh(t,a,s,!1),fD(t,t.line-u),a=s=t.position,l=!1),Nd(m)||(s=t.position+1),m=t.input.charCodeAt(++t.position)}return zh(t,a,s,!1),t.result?!0:(t.kind=d,t.result=p,!1)}function hAe(t,e){var r,n,i;if(r=t.input.charCodeAt(t.position),r!==39)return!1;for(t.kind="scalar",t.result="",t.position++,n=i=t.position;(r=t.input.charCodeAt(t.position))!==0;)if(r===39)if(zh(t,n,t.position,!0),r=t.input.charCodeAt(++t.position),r===39)n=t.position,t.position++,i=t.position;else return!0;else dc(r)?(zh(t,n,i,!0),fD(t,Ci(t,!1,e)),n=i=t.position):t.position===t.lineStart&&kw(t)?Qt(t,"unexpected end of the document within a single quoted scalar"):(t.position++,i=t.position);Qt(t,"unexpected end of the stream within a single quoted scalar")}function fAe(t,e){var r,n,i,a,s,l;if(l=t.input.charCodeAt(t.position),l!==34)return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;(l=t.input.charCodeAt(t.position))!==0;){if(l===34)return zh(t,r,t.position,!0),t.position++,!0;if(l===92){if(zh(t,r,t.position,!0),l=t.input.charCodeAt(++t.position),dc(l))Ci(t,!1,e);else if(l<256&&bj[l])t.result+=wj[l],t.position++;else if((s=sAe(l))>0){for(i=s,a=0;i>0;i--)l=t.input.charCodeAt(++t.position),(s=aAe(l))>=0?a=(a<<4)+s:Qt(t,"expected hexadecimal character");t.result+=lAe(a),t.position++}else Qt(t,"unknown escape sequence");r=n=t.position}else dc(l)?(zh(t,r,n,!0),fD(t,Ci(t,!1,e)),r=n=t.position):t.position===t.lineStart&&kw(t)?Qt(t,"unexpected end of the document within a double quoted scalar"):(t.position++,n=t.position)}Qt(t,"unexpected end of the stream within a double quoted scalar")}function dAe(t,e){var r=!0,n,i,a,s=t.tag,l,u=t.anchor,h,f,d,p,m,g=Object.create(null),y,v,x,b;if(b=t.input.charCodeAt(t.position),b===91)f=93,m=!1,l=[];else if(b===123)f=125,m=!0,l={};else return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=l),b=t.input.charCodeAt(++t.position);b!==0;){if(Ci(t,!0,e),b=t.input.charCodeAt(t.position),b===f)return t.position++,t.tag=s,t.anchor=u,t.kind=m?"mapping":"sequence",t.result=l,!0;r?b===44&&Qt(t,"expected the node content, but found ','"):Qt(t,"missed comma between flow collection entries"),v=y=x=null,d=p=!1,b===63&&(h=t.input.charCodeAt(t.position+1),Ls(h)&&(d=p=!0,t.position++,Ci(t,!0,e))),n=t.line,i=t.lineStart,a=t.position,om(t,e,vw,!1,!0),v=t.tag,y=t.result,Ci(t,!0,e),b=t.input.charCodeAt(t.position),(p||t.line===n)&&b===58&&(d=!0,b=t.input.charCodeAt(++t.position),Ci(t,!0,e),om(t,e,vw,!1,!0),x=t.result),m?sm(t,l,g,v,y,x,n,i,a):d?l.push(sm(t,null,g,v,y,x,n,i,a)):l.push(y),Ci(t,!0,e),b=t.input.charCodeAt(t.position),b===44?(r=!0,b=t.input.charCodeAt(++t.position)):r=!1}Qt(t,"unexpected end of the stream within a flow collection")}function pAe(t,e){var r,n,i=iD,a=!1,s=!1,l=e,u=0,h=!1,f,d;if(d=t.input.charCodeAt(t.position),d===124)n=!1;else if(d===62)n=!0;else return!1;for(t.kind="scalar",t.result="";d!==0;)if(d=t.input.charCodeAt(++t.position),d===43||d===45)iD===i?i=d===43?KX:tAe:Qt(t,"repeat of a chomping mode identifier");else if((f=oAe(d))>=0)f===0?Qt(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):s?Qt(t,"repeat of an indentation width identifier"):(l=e+f-1,s=!0);else break;if(Nd(d)){do d=t.input.charCodeAt(++t.position);while(Nd(d));if(d===35)do d=t.input.charCodeAt(++t.position);while(!dc(d)&&d!==0)}for(;d!==0;){for(hD(t),t.lineIndent=0,d=t.input.charCodeAt(t.position);(!s||t.lineIndent<l)&&d===32;)t.lineIndent++,d=t.input.charCodeAt(++t.position);if(!s&&t.lineIndent>l&&(l=t.lineIndent),dc(d)){u++;continue}if(t.lineIndent<l){i===KX?t.result+=$i.repeat(`
+`,a?1+u:u):i===iD&&a&&(t.result+=`
+`);break}for(n?Nd(d)?(h=!0,t.result+=$i.repeat(`
+`,a?1+u:u)):h?(h=!1,t.result+=$i.repeat(`
+`,u+1)):u===0?a&&(t.result+=" "):t.result+=$i.repeat(`
+`,u):t.result+=$i.repeat(`
+`,a?1+u:u),a=!0,s=!0,u=0,r=t.position;!dc(d)&&d!==0;)d=t.input.charCodeAt(++t.position);zh(t,r,t.position,!1)}return!0}function tj(t,e){var r,n=t.tag,i=t.anchor,a=[],s,l=!1,u;if(t.firstTabInLine!==-1)return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=a),u=t.input.charCodeAt(t.position);u!==0&&(t.firstTabInLine!==-1&&(t.position=t.firstTabInLine,Qt(t,"tab characters must not be used in indentation")),!(u!==45||(s=t.input.charCodeAt(t.position+1),!Ls(s))));){if(l=!0,t.position++,Ci(t,!0,-1)&&t.lineIndent<=e){a.push(null),u=t.input.charCodeAt(t.position);continue}if(r=t.line,om(t,e,yj,!1,!0),a.push(t.result),Ci(t,!0,-1),u=t.input.charCodeAt(t.position),(t.line===r||t.lineIndent>e)&&u!==0)Qt(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break}return l?(t.tag=n,t.anchor=i,t.kind="sequence",t.result=a,!0):!1}function mAe(t,e,r){var n,i,a,s,l,u,h=t.tag,f=t.anchor,d={},p=Object.create(null),m=null,g=null,y=null,v=!1,x=!1,b;if(t.firstTabInLine!==-1)return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=d),b=t.input.charCodeAt(t.position);b!==0;){if(!v&&t.firstTabInLine!==-1&&(t.position=t.firstTabInLine,Qt(t,"tab characters must not be used in indentation")),n=t.input.charCodeAt(t.position+1),a=t.line,(b===63||b===58)&&Ls(n))b===63?(v&&(sm(t,d,p,m,g,null,s,l,u),m=g=y=null),x=!0,v=!0,i=!0):v?(v=!1,i=!0):Qt(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,b=n;else{if(s=t.line,l=t.lineStart,u=t.position,!om(t,r,gj,!1,!0))break;if(t.line===a){for(b=t.input.charCodeAt(t.position);Nd(b);)b=t.input.charCodeAt(++t.position);if(b===58)b=t.input.charCodeAt(++t.position),Ls(b)||Qt(t,"a whitespace character is expected after the key-value separator within a block mapping"),v&&(sm(t,d,p,m,g,null,s,l,u),m=g=y=null),x=!0,v=!1,i=!1,m=t.tag,g=t.result;else if(x)Qt(t,"can not read an implicit mapping pair; a colon is missed");else return t.tag=h,t.anchor=f,!0}else if(x)Qt(t,"can not read a block mapping entry; a multiline key may not be an implicit key");else return t.tag=h,t.anchor=f,!0}if((t.line===a||t.lineIndent>e)&&(v&&(s=t.line,l=t.lineStart,u=t.position),om(t,e,xw,!0,i)&&(v?g=t.result:y=t.result),v||(sm(t,d,p,m,g,y,s,l,u),m=g=y=null),Ci(t,!0,-1),b=t.input.charCodeAt(t.position)),(t.line===a||t.lineIndent>e)&&b!==0)Qt(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return v&&sm(t,d,p,m,g,null,s,l,u),x&&(t.tag=h,t.anchor=f,t.kind="mapping",t.result=d),x}function gAe(t){var e,r=!1,n=!1,i,a,s;if(s=t.input.charCodeAt(t.position),s!==33)return!1;if(t.tag!==null&&Qt(t,"duplication of a tag property"),s=t.input.charCodeAt(++t.position),s===60?(r=!0,s=t.input.charCodeAt(++t.position)):s===33?(n=!0,i="!!",s=t.input.charCodeAt(++t.position)):i="!",e=t.position,r){do s=t.input.charCodeAt(++t.position);while(s!==0&&s!==62);t.position<t.length?(a=t.input.slice(e,t.position),s=t.input.charCodeAt(++t.position)):Qt(t,"unexpected end of the stream within a verbatim tag")}else{for(;s!==0&&!Ls(s);)s===33&&(n?Qt(t,"tag suffix cannot contain exclamation marks"):(i=t.input.slice(e-1,t.position+1),vj.test(i)||Qt(t,"named tag handle cannot contain such characters"),n=!0,e=t.position+1)),s=t.input.charCodeAt(++t.position);a=t.input.slice(e,t.position),iAe.test(a)&&Qt(t,"tag suffix cannot contain flow indicator characters")}a&&!xj.test(a)&&Qt(t,"tag name cannot contain such characters: "+a);try{a=decodeURIComponent(a)}catch{Qt(t,"tag name is malformed: "+a)}return r?t.tag=a:Gh.call(t.tagMap,i)?t.tag=t.tagMap[i]+a:i==="!"?t.tag="!"+a:i==="!!"?t.tag="tag:yaml.org,2002:"+a:Qt(t,'undeclared tag handle "'+i+'"'),!0}function yAe(t){var e,r;if(r=t.input.charCodeAt(t.position),r!==38)return!1;for(t.anchor!==null&&Qt(t,"duplication of an anchor property"),r=t.input.charCodeAt(++t.position),e=t.position;r!==0&&!Ls(r)&&!am(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Qt(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function vAe(t){var e,r,n;if(n=t.input.charCodeAt(t.position),n!==42)return!1;for(n=t.input.charCodeAt(++t.position),e=t.position;n!==0&&!Ls(n)&&!am(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&Qt(t,"name of an alias node must contain at least one character"),r=t.input.slice(e,t.position),Gh.call(t.anchorMap,r)||Qt(t,'unidentified alias "'+r+'"'),t.result=t.anchorMap[r],Ci(t,!0,-1),!0}function om(t,e,r,n,i){var a,s,l,u=1,h=!1,f=!1,d,p,m,g,y,v;if(t.listener!==null&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,a=s=l=xw===r||yj===r,n&&Ci(t,!0,-1)&&(h=!0,t.lineIndent>e?u=1:t.lineIndent===e?u=0:t.lineIndent<e&&(u=-1)),u===1)for(;gAe(t)||yAe(t);)Ci(t,!0,-1)?(h=!0,l=a,t.lineIndent>e?u=1:t.lineIndent===e?u=0:t.lineIndent<e&&(u=-1)):l=!1;if(l&&(l=h||i),(u===1||xw===r)&&(vw===r||gj===r?y=e:y=e+1,v=t.position-t.lineStart,u===1?l&&(tj(t,v)||mAe(t,v,y))||dAe(t,y)?f=!0:(s&&pAe(t,y)||hAe(t,y)||fAe(t,y)?f=!0:vAe(t)?(f=!0,(t.tag!==null||t.anchor!==null)&&Qt(t,"alias node should not have any properties")):uAe(t,y,vw===r)&&(f=!0,t.tag===null&&(t.tag="?")),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):u===0&&(f=l&&tj(t,v))),t.tag===null)t.anchor!==null&&(t.anchorMap[t.anchor]=t.result);else if(t.tag==="?"){for(t.result!==null&&t.kind!=="scalar"&&Qt(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),d=0,p=t.implicitTypes.length;d<p;d+=1)if(g=t.implicitTypes[d],g.resolve(t.result)){t.result=g.construct(t.result),t.tag=g.tag,t.anchor!==null&&(t.anchorMap[t.anchor]=t.result);break}}else if(t.tag!=="!"){if(Gh.call(t.typeMap[t.kind||"fallback"],t.tag))g=t.typeMap[t.kind||"fallback"][t.tag];else for(g=null,m=t.typeMap.multi[t.kind||"fallback"],d=0,p=m.length;d<p;d+=1)if(t.tag.slice(0,m[d].tag.length)===m[d].tag){g=m[d];break}g||Qt(t,"unknown tag !<"+t.tag+">"),t.result!==null&&g.kind!==t.kind&&Qt(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+g.kind+'", not "'+t.kind+'"'),g.resolve(t.result,t.tag)?(t.result=g.construct(t.result,t.tag),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):Qt(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return t.listener!==null&&t.listener("close",t),t.tag!==null||t.anchor!==null||f}function xAe(t){var e=t.position,r,n,i,a=!1,s;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);(s=t.input.charCodeAt(t.position))!==0&&(Ci(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||s!==37));){for(a=!0,s=t.input.charCodeAt(++t.position),r=t.position;s!==0&&!Ls(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(r,t.position),i=[],n.length<1&&Qt(t,"directive name must not be less than one character in length");s!==0;){for(;Nd(s);)s=t.input.charCodeAt(++t.position);if(s===35){do s=t.input.charCodeAt(++t.position);while(s!==0&&!dc(s));break}if(dc(s))break;for(r=t.position;s!==0&&!Ls(s);)s=t.input.charCodeAt(++t.position);i.push(t.input.slice(r,t.position))}s!==0&&hD(t),Gh.call(JX,n)?JX[n](t,n,i):bw(t,'unknown document directive "'+n+'"')}if(Ci(t,!0,-1),t.lineIndent===0&&t.input.charCodeAt(t.position)===45&&t.input.charCodeAt(t.position+1)===45&&t.input.charCodeAt(t.position+2)===45?(t.position+=3,Ci(t,!0,-1)):a&&Qt(t,"directives end mark is expected"),om(t,t.lineIndent-1,xw,!1,!0),Ci(t,!0,-1),t.checkLineBreaks&&nAe.test(t.input.slice(e,t.position))&&bw(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&kw(t)){t.input.charCodeAt(t.position)===46&&(t.position+=3,Ci(t,!0,-1));return}if(t.position<t.length-1)Qt(t,"end of the stream or a document separator is expected");else return}function kj(t,e){t=String(t),e=e||{},t.length!==0&&(t.charCodeAt(t.length-1)!==10&&t.charCodeAt(t.length-1)!==13&&(t+=`
+`),t.charCodeAt(0)===65279&&(t=t.slice(1)));var r=new cAe(t,e),n=t.indexOf("\0");for(n!==-1&&(r.position=n,Qt(r,"null byte is not allowed in input")),r.input+="\0";r.input.charCodeAt(r.position)===32;)r.lineIndent+=1,r.position+=1;for(;r.position<r.length-1;)xAe(r);return r.documents}function bAe(t,e,r){e!==null&&typeof e=="object"&&typeof r>"u"&&(r=e,e=null);var n=kj(t,r);if(typeof e!="function")return n;for(var i=0,a=n.length;i<a;i+=1)e(n[i])}function wAe(t,e){var r=kj(t,e);if(r.length!==0){if(r.length===1)return r[0];throw new Ds("expected a single document in the stream, but found more")}}function VAe(t,e){var r,n,i,a,s,l,u;if(e===null)return{};for(r={},n=Object.keys(e),i=0,a=n.length;i<a;i+=1)s=n[i],l=String(e[s]),s.slice(0,2)==="!!"&&(s="tag:yaml.org,2002:"+s.slice(2)),u=t.compiledTypeMap.fallback[s],u&&Cj.call(u.styleAliases,l)&&(l=u.styleAliases[l]),r[s]=l;return r}function UAe(t){var e,r,n;if(e=t.toString(16).toUpperCase(),t<=255)r="x",n=2;else if(t<=65535)r="u",n=4;else if(t<=4294967295)r="U",n=8;else throw new Ds("code point within a string may not be greater than 0xFFFFFFFF");return"\\"+r+$i.repeat("0",n-e.length)+e}function WAe(t){this.schema=t.schema||mj,this.indent=Math.max(1,t.indent||2),this.noArrayIndent=t.noArrayIndent||!1,this.skipInvalid=t.skipInvalid||!1,this.flowLevel=$i.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=VAe(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.noRefs=t.noRefs||!1,this.noCompatMode=t.noCompatMode||!1,this.condenseFlow=t.condenseFlow||!1,this.quotingType=t.quotingType==='"'?c2:HAe,this.forceQuotes=t.forceQuotes||!1,this.replacer=typeof t.replacer=="function"?t.replacer:null,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function rj(t,e){for(var r=$i.repeat(" ",e),n=0,i=-1,a="",s,l=t.length;n<l;)i=t.indexOf(`
+`,n),i===-1?(s=t.slice(n),n=l):(s=t.slice(n,i+1),n=i+1),s.length&&s!==`
+`&&(a+=r),a+=s;return a}function oD(t,e){return`
+`+$i.repeat(" ",t.indent*e)}function qAe(t,e){var r,n,i;for(r=0,n=t.implicitTypes.length;r<n;r+=1)if(i=t.implicitTypes[r],i.resolve(e))return!0;return!1}function Tw(t){return t===CAe||t===EAe}function u2(t){return 32<=t&&t<=126||161<=t&&t<=55295&&t!==8232&&t!==8233||57344<=t&&t<=65533&&t!==dD||65536<=t&&t<=1114111}function nj(t){return u2(t)&&t!==dD&&t!==SAe&&t!==l2}function ij(t,e,r){var n=nj(t),i=n&&!Tw(t);return(r?n:n&&t!==Aj&&t!==_j&&t!==Dj&&t!==Lj&&t!==Rj)&&t!==sD&&!(e===ww&&!i)||nj(e)&&!Tw(e)&&t===sD||e===ww&&i}function YAe(t){return u2(t)&&t!==dD&&!Tw(t)&&t!==MAe&&t!==PAe&&t!==ww&&t!==Aj&&t!==_j&&t!==Dj&&t!==Lj&&t!==Rj&&t!==sD&&t!==LAe&&t!==NAe&&t!==AAe&&t!==$Ae&&t!==IAe&&t!==OAe&&t!==RAe&&t!==_Ae&&t!==DAe&&t!==BAe&&t!==FAe}function XAe(t){return!Tw(t)&&t!==ww}function s2(t,e){var r=t.charCodeAt(e),n;return r>=55296&&r<=56319&&e+1<t.length&&(n=t.charCodeAt(e+1),n>=56320&&n<=57343)?(r-55296)*1024+n-56320+65536:r}function Nj(t){var e=/^\n* /;return e.test(t)}function jAe(t,e,r,n,i,a,s,l){var u,h=0,f=null,d=!1,p=!1,m=n!==-1,g=-1,y=YAe(s2(t,0))&&XAe(s2(t,t.length-1));if(e||s)for(u=0;u<t.length;h>=65536?u+=2:u++){if(h=s2(t,u),!u2(h))return im;y=y&&ij(h,f,l),f=h}else{for(u=0;u<t.length;h>=65536?u+=2:u++){if(h=s2(t,u),h===l2)d=!0,m&&(p=p||u-g-1>n&&t[g+1]!==" ",g=u);else if(!u2(h))return im;y=y&&ij(h,f,l),f=h}p=p||m&&u-g-1>n&&t[g+1]!==" "}return!d&&!p?y&&!s&&!i(t)?Mj:a===c2?im:lD:r>9&&Nj(t)?im:s?a===c2?im:lD:p?Oj:Ij}function KAe(t,e,r,n,i){t.dump=function(){if(e.length===0)return t.quotingType===c2?'""':"''";if(!t.noCompatMode&&(zAe.indexOf(e)!==-1||GAe.test(e)))return t.quotingType===c2?'"'+e+'"':"'"+e+"'";var a=t.indent*Math.max(1,r),s=t.lineWidth===-1?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-a),l=n||t.flowLevel>-1&&r>=t.flowLevel;function u(h){return qAe(t,h)}switch(o(u,"testAmbiguity"),jAe(e,l,t.indent,s,u,t.quotingType,t.forceQuotes&&!n,i)){case Mj:return e;case lD:return"'"+e.replace(/'/g,"''")+"'";case Ij:return"|"+aj(e,t.indent)+sj(rj(e,a));case Oj:return">"+aj(e,t.indent)+sj(rj(QAe(e,s),a));case im:return'"'+ZAe(e)+'"';default:throw new Ds("impossible error: invalid scalar style")}}()}function aj(t,e){var r=Nj(t)?String(e):"",n=t[t.length-1]===`
+`,i=n&&(t[t.length-2]===`
+`||t===`
+`),a=i?"+":n?"":"-";return r+a+`
+`}function sj(t){return t[t.length-1]===`
+`?t.slice(0,-1):t}function QAe(t,e){for(var r=/(\n+)([^\n]*)/g,n=function(){var h=t.indexOf(`
+`);return h=h!==-1?h:t.length,r.lastIndex=h,oj(t.slice(0,h),e)}(),i=t[0]===`
+`||t[0]===" ",a,s;s=r.exec(t);){var l=s[1],u=s[2];a=u[0]===" ",n+=l+(!i&&!a&&u!==""?`
+`:"")+oj(u,e),i=a}return n}function oj(t,e){if(t===""||t[0]===" ")return t;for(var r=/ [^ ]/g,n,i=0,a,s=0,l=0,u="";n=r.exec(t);)l=n.index,l-i>e&&(a=s>i?s:l,u+=`
+`+t.slice(i,a),i=a+1),s=l;return u+=`
+`,t.length-i>e&&s>i?u+=t.slice(i,s)+`
+`+t.slice(s+1):u+=t.slice(i),u.slice(1)}function ZAe(t){for(var e="",r=0,n,i=0;i<t.length;r>=65536?i+=2:i++)r=s2(t,i),n=Da[r],!n&&u2(r)?(e+=t[i],r>=65536&&(e+=t[i+1])):e+=n||UAe(r);return e}function JAe(t,e,r){var n="",i=t.tag,a,s,l;for(a=0,s=r.length;a<s;a+=1)l=r[a],t.replacer&&(l=t.replacer.call(r,String(a),l)),(Au(t,e,l,!1,!1)||typeof l>"u"&&Au(t,e,null,!1,!1))&&(n!==""&&(n+=","+(t.condenseFlow?"":" ")),n+=t.dump);t.tag=i,t.dump="["+n+"]"}function lj(t,e,r,n){var i="",a=t.tag,s,l,u;for(s=0,l=r.length;s<l;s+=1)u=r[s],t.replacer&&(u=t.replacer.call(r,String(s),u)),(Au(t,e+1,u,!0,!0,!1,!0)||typeof u>"u"&&Au(t,e+1,null,!0,!0,!1,!0))&&((!n||i!=="")&&(i+=oD(t,e)),t.dump&&l2===t.dump.charCodeAt(0)?i+="-":i+="- ",i+=t.dump);t.tag=a,t.dump=i||"[]"}function e8e(t,e,r){var n="",i=t.tag,a=Object.keys(r),s,l,u,h,f;for(s=0,l=a.length;s<l;s+=1)f="",n!==""&&(f+=", "),t.condenseFlow&&(f+='"'),u=a[s],h=r[u],t.replacer&&(h=t.replacer.call(r,u,h)),Au(t,e,u,!1,!1)&&(t.dump.length>1024&&(f+="? "),f+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),Au(t,e,h,!1,!1)&&(f+=t.dump,n+=f));t.tag=i,t.dump="{"+n+"}"}function t8e(t,e,r,n){var i="",a=t.tag,s=Object.keys(r),l,u,h,f,d,p;if(t.sortKeys===!0)s.sort();else if(typeof t.sortKeys=="function")s.sort(t.sortKeys);else if(t.sortKeys)throw new Ds("sortKeys must be a boolean or a function");for(l=0,u=s.length;l<u;l+=1)p="",(!n||i!=="")&&(p+=oD(t,e)),h=s[l],f=r[h],t.replacer&&(f=t.replacer.call(r,h,f)),Au(t,e+1,h,!0,!0,!0)&&(d=t.tag!==null&&t.tag!=="?"||t.dump&&t.dump.length>1024,d&&(t.dump&&l2===t.dump.charCodeAt(0)?p+="?":p+="? "),p+=t.dump,d&&(p+=oD(t,e)),Au(t,e+1,f,!0,d)&&(t.dump&&l2===t.dump.charCodeAt(0)?p+=":":p+=": ",p+=t.dump,i+=p));t.tag=a,t.dump=i||"{}"}function cj(t,e,r){var n,i,a,s,l,u;for(i=r?t.explicitTypes:t.implicitTypes,a=0,s=i.length;a<s;a+=1)if(l=i[a],(l.instanceOf||l.predicate)&&(!l.instanceOf||typeof e=="object"&&e instanceof l.instanceOf)&&(!l.predicate||l.predicate(e))){if(r?l.multi&&l.representName?t.tag=l.representName(e):t.tag=l.tag:t.tag="?",l.represent){if(u=t.styleMap[l.tag]||l.defaultStyle,Sj.call(l.represent)==="[object Function]")n=l.represent(e,u);else if(Cj.call(l.represent,u))n=l.represent[u](e,u);else throw new Ds("!<"+l.tag+'> tag resolver accepts not "'+u+'" style');t.dump=n}return!0}return!1}function Au(t,e,r,n,i,a,s){t.tag=null,t.dump=r,cj(t,r,!1)||cj(t,r,!0);var l=Sj.call(t.dump),u=n,h;n&&(n=t.flowLevel<0||t.flowLevel>e);var f=l==="[object Object]"||l==="[object Array]",d,p;if(f&&(d=t.duplicates.indexOf(r),p=d!==-1),(t.tag!==null&&t.tag!=="?"||p||t.indent!==2&&e>0)&&(i=!1),p&&t.usedDuplicates[d])t.dump="*ref_"+d;else{if(f&&p&&!t.usedDuplicates[d]&&(t.usedDuplicates[d]=!0),l==="[object Object]")n&&Object.keys(t.dump).length!==0?(t8e(t,e,t.dump,i),p&&(t.dump="&ref_"+d+t.dump)):(e8e(t,e,t.dump),p&&(t.dump="&ref_"+d+" "+t.dump));else if(l==="[object Array]")n&&t.dump.length!==0?(t.noArrayIndent&&!s&&e>0?lj(t,e-1,t.dump,i):lj(t,e,t.dump,i),p&&(t.dump="&ref_"+d+t.dump)):(JAe(t,e,t.dump),p&&(t.dump="&ref_"+d+" "+t.dump));else if(l==="[object String]")t.tag!=="?"&&KAe(t,t.dump,e,a,u);else{if(l==="[object Undefined]")return!1;if(t.skipInvalid)return!1;throw new Ds("unacceptable kind of an object to dump "+l)}t.tag!==null&&t.tag!=="?"&&(h=encodeURI(t.tag[0]==="!"?t.tag.slice(1):t.tag).replace(/!/g,"%21"),t.tag[0]==="!"?h="!"+h:h.slice(0,18)==="tag:yaml.org,2002:"?h="!!"+h.slice(18):h="!<"+h+">",t.dump=h+" "+t.dump)}return!0}function r8e(t,e){var r=[],n=[],i,a;for(cD(t,r,n),i=0,a=n.length;i<a;i+=1)e.duplicates.push(r[n[i]]);e.usedDuplicates=new Array(a)}function cD(t,e,r){var n,i,a;if(t!==null&&typeof t=="object")if(i=e.indexOf(t),i!==-1)r.indexOf(i)===-1&&r.push(i);else if(e.push(t),Array.isArray(t))for(i=0,a=t.length;i<a;i+=1)cD(t[i],e,r);else for(n=Object.keys(t),i=0,a=n.length;i<a;i+=1)cD(t[n[i]],e,r)}function n8e(t,e){e=e||{};var r=new WAe(e);r.noRefs||r8e(t,r);var n=t;return r.replacer&&(n=r.replacer.call({"":n},"",n)),Au(r,0,n,!0,!0)?r.dump+`
+`:""}function pD(t,e){return function(){throw new Error("Function yaml."+t+" is removed in js-yaml 4. Use yaml."+e+" instead, which is now safe by default.")}}var HCe,WCe,qCe,YCe,XCe,jCe,$i,Ds,QCe,ZCe,JCe,_a,n7e,i7e,a7e,s7e,o7e,h7e,m7e,T7e,k7e,C7e,D7e,fj,L7e,dj,pj,I7e,P7e,uD,G7e,V7e,U7e,q7e,Y7e,K7e,Q7e,eAe,mj,Gh,vw,gj,yj,xw,iD,tAe,KX,rAe,nAe,iAe,vj,xj,bj,wj,Rd,JX,TAe,kAe,Ej,Sj,Cj,dD,EAe,l2,SAe,CAe,AAe,_Ae,sD,DAe,LAe,RAe,NAe,Aj,MAe,ww,IAe,OAe,PAe,BAe,_j,Dj,FAe,Lj,$Ae,Rj,Da,zAe,GAe,HAe,c2,Mj,lD,Ij,Oj,im,i8e,a8e,lm,cm,okt,lkt,ckt,ukt,hkt,Ew=N(()=>{"use strict";o(uj,"isNothing");o($Ce,"isObject");o(zCe,"toArray");o(GCe,"extend");o(VCe,"repeat");o(UCe,"isNegativeZero");HCe=uj,WCe=$Ce,qCe=zCe,YCe=VCe,XCe=UCe,jCe=GCe,$i={isNothing:HCe,isObject:WCe,toArray:qCe,repeat:YCe,isNegativeZero:XCe,extend:jCe};o(hj,"formatError");o(o2,"YAMLException$1");o2.prototype=Object.create(Error.prototype);o2.prototype.constructor=o2;o2.prototype.toString=o(function(e){return this.name+": "+hj(this,e)},"toString");Ds=o2;o(rD,"getLine");o(nD,"padStart");o(KCe,"makeSnippet");QCe=KCe,ZCe=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],JCe=["scalar","sequence","mapping"];o(e7e,"compileStyleAliases");o(t7e,"Type$1");_a=t7e;o(jX,"compileList");o(r7e,"compileMap");o(aD,"Schema$1");aD.prototype.extend=o(function(e){var r=[],n=[];if(e instanceof _a)n.push(e);else if(Array.isArray(e))n=n.concat(e);else if(e&&(Array.isArray(e.implicit)||Array.isArray(e.explicit)))e.implicit&&(r=r.concat(e.implicit)),e.explicit&&(n=n.concat(e.explicit));else throw new Ds("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");r.forEach(function(a){if(!(a instanceof _a))throw new Ds("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(a.loadKind&&a.loadKind!=="scalar")throw new Ds("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(a.multi)throw new Ds("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")}),n.forEach(function(a){if(!(a instanceof _a))throw new Ds("Specified list of YAML types (or a single Type object) contains a non-Type object.")});var i=Object.create(aD.prototype);return i.implicit=(this.implicit||[]).concat(r),i.explicit=(this.explicit||[]).concat(n),i.compiledImplicit=jX(i,"implicit"),i.compiledExplicit=jX(i,"explicit"),i.compiledTypeMap=r7e(i.compiledImplicit,i.compiledExplicit),i},"extend");n7e=aD,i7e=new _a("tag:yaml.org,2002:str",{kind:"scalar",construct:o(function(t){return t!==null?t:""},"construct")}),a7e=new _a("tag:yaml.org,2002:seq",{kind:"sequence",construct:o(function(t){return t!==null?t:[]},"construct")}),s7e=new _a("tag:yaml.org,2002:map",{kind:"mapping",construct:o(function(t){return t!==null?t:{}},"construct")}),o7e=new n7e({explicit:[i7e,a7e,s7e]});o(l7e,"resolveYamlNull");o(c7e,"constructYamlNull");o(u7e,"isNull");h7e=new _a("tag:yaml.org,2002:null",{kind:"scalar",resolve:l7e,construct:c7e,predicate:u7e,represent:{canonical:o(function(){return"~"},"canonical"),lowercase:o(function(){return"null"},"lowercase"),uppercase:o(function(){return"NULL"},"uppercase"),camelcase:o(function(){return"Null"},"camelcase"),empty:o(function(){return""},"empty")},defaultStyle:"lowercase"});o(f7e,"resolveYamlBoolean");o(d7e,"constructYamlBoolean");o(p7e,"isBoolean");m7e=new _a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:f7e,construct:d7e,predicate:p7e,represent:{lowercase:o(function(t){return t?"true":"false"},"lowercase"),uppercase:o(function(t){return t?"TRUE":"FALSE"},"uppercase"),camelcase:o(function(t){return t?"True":"False"},"camelcase")},defaultStyle:"lowercase"});o(g7e,"isHexCode");o(y7e,"isOctCode");o(v7e,"isDecCode");o(x7e,"resolveYamlInteger");o(b7e,"constructYamlInteger");o(w7e,"isInteger");T7e=new _a("tag:yaml.org,2002:int",{kind:"scalar",resolve:x7e,construct:b7e,predicate:w7e,represent:{binary:o(function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},"binary"),octal:o(function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},"octal"),decimal:o(function(t){return t.toString(10)},"decimal"),hexadecimal:o(function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)},"hexadecimal")},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),k7e=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");o(E7e,"resolveYamlFloat");o(S7e,"constructYamlFloat");C7e=/^[-+]?[0-9]+e/;o(A7e,"representYamlFloat");o(_7e,"isFloat");D7e=new _a("tag:yaml.org,2002:float",{kind:"scalar",resolve:E7e,construct:S7e,predicate:_7e,represent:A7e,defaultStyle:"lowercase"}),fj=o7e.extend({implicit:[h7e,m7e,T7e,D7e]}),L7e=fj,dj=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),pj=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");o(R7e,"resolveYamlTimestamp");o(N7e,"constructYamlTimestamp");o(M7e,"representYamlTimestamp");I7e=new _a("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:R7e,construct:N7e,instanceOf:Date,represent:M7e});o(O7e,"resolveYamlMerge");P7e=new _a("tag:yaml.org,2002:merge",{kind:"scalar",resolve:O7e}),uD=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
+\r`;o(B7e,"resolveYamlBinary");o(F7e,"constructYamlBinary");o($7e,"representYamlBinary");o(z7e,"isBinary");G7e=new _a("tag:yaml.org,2002:binary",{kind:"scalar",resolve:B7e,construct:F7e,predicate:z7e,represent:$7e}),V7e=Object.prototype.hasOwnProperty,U7e=Object.prototype.toString;o(H7e,"resolveYamlOmap");o(W7e,"constructYamlOmap");q7e=new _a("tag:yaml.org,2002:omap",{kind:"sequence",resolve:H7e,construct:W7e}),Y7e=Object.prototype.toString;o(X7e,"resolveYamlPairs");o(j7e,"constructYamlPairs");K7e=new _a("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:X7e,construct:j7e}),Q7e=Object.prototype.hasOwnProperty;o(Z7e,"resolveYamlSet");o(J7e,"constructYamlSet");eAe=new _a("tag:yaml.org,2002:set",{kind:"mapping",resolve:Z7e,construct:J7e}),mj=L7e.extend({implicit:[I7e,P7e],explicit:[G7e,q7e,K7e,eAe]}),Gh=Object.prototype.hasOwnProperty,vw=1,gj=2,yj=3,xw=4,iD=1,tAe=2,KX=3,rAe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,nAe=/[\x85\u2028\u2029]/,iAe=/[,\[\]\{\}]/,vj=/^(?:!|!!|![a-z\-]+!)$/i,xj=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;o(QX,"_class");o(dc,"is_EOL");o(Nd,"is_WHITE_SPACE");o(Ls,"is_WS_OR_EOL");o(am,"is_FLOW_INDICATOR");o(aAe,"fromHexCode");o(sAe,"escapedHexLen");o(oAe,"fromDecimalCode");o(ZX,"simpleEscapeSequence");o(lAe,"charFromCodepoint");bj=new Array(256),wj=new Array(256);for(Rd=0;Rd<256;Rd++)bj[Rd]=ZX(Rd)?1:0,wj[Rd]=ZX(Rd);o(cAe,"State$1");o(Tj,"generateError");o(Qt,"throwError");o(bw,"throwWarning");JX={YAML:o(function(e,r,n){var i,a,s;e.version!==null&&Qt(e,"duplication of %YAML directive"),n.length!==1&&Qt(e,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),i===null&&Qt(e,"ill-formed argument of the YAML directive"),a=parseInt(i[1],10),s=parseInt(i[2],10),a!==1&&Qt(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=s<2,s!==1&&s!==2&&bw(e,"unsupported YAML version of the document")},"handleYamlDirective"),TAG:o(function(e,r,n){var i,a;n.length!==2&&Qt(e,"TAG directive accepts exactly two arguments"),i=n[0],a=n[1],vj.test(i)||Qt(e,"ill-formed tag handle (first argument) of the TAG directive"),Gh.call(e.tagMap,i)&&Qt(e,'there is a previously declared suffix for "'+i+'" tag handle'),xj.test(a)||Qt(e,"ill-formed tag prefix (second argument) of the TAG directive");try{a=decodeURIComponent(a)}catch{Qt(e,"tag prefix is malformed: "+a)}e.tagMap[i]=a},"handleTagDirective")};o(zh,"captureSegment");o(ej,"mergeMappings");o(sm,"storeMappingPair");o(hD,"readLineBreak");o(Ci,"skipSeparationSpace");o(kw,"testDocumentSeparator");o(fD,"writeFoldedLines");o(uAe,"readPlainScalar");o(hAe,"readSingleQuotedScalar");o(fAe,"readDoubleQuotedScalar");o(dAe,"readFlowCollection");o(pAe,"readBlockScalar");o(tj,"readBlockSequence");o(mAe,"readBlockMapping");o(gAe,"readTagProperty");o(yAe,"readAnchorProperty");o(vAe,"readAlias");o(om,"composeNode");o(xAe,"readDocument");o(kj,"loadDocuments");o(bAe,"loadAll$1");o(wAe,"load$1");TAe=bAe,kAe=wAe,Ej={loadAll:TAe,load:kAe},Sj=Object.prototype.toString,Cj=Object.prototype.hasOwnProperty,dD=65279,EAe=9,l2=10,SAe=13,CAe=32,AAe=33,_Ae=34,sD=35,DAe=37,LAe=38,RAe=39,NAe=42,Aj=44,MAe=45,ww=58,IAe=61,OAe=62,PAe=63,BAe=64,_j=91,Dj=93,FAe=96,Lj=123,$Ae=124,Rj=125,Da={};Da[0]="\\0";Da[7]="\\a";Da[8]="\\b";Da[9]="\\t";Da[10]="\\n";Da[11]="\\v";Da[12]="\\f";Da[13]="\\r";Da[27]="\\e";Da[34]='\\"';Da[92]="\\\\";Da[133]="\\N";Da[160]="\\_";Da[8232]="\\L";Da[8233]="\\P";zAe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],GAe=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;o(VAe,"compileStyleMap");o(UAe,"encodeHex");HAe=1,c2=2;o(WAe,"State");o(rj,"indentString");o(oD,"generateNextLine");o(qAe,"testImplicitResolving");o(Tw,"isWhitespace");o(u2,"isPrintable");o(nj,"isNsCharOrWhitespace");o(ij,"isPlainSafe");o(YAe,"isPlainSafeFirst");o(XAe,"isPlainSafeLast");o(s2,"codePointAt");o(Nj,"needIndentIndicator");Mj=1,lD=2,Ij=3,Oj=4,im=5;o(jAe,"chooseScalarStyle");o(KAe,"writeScalar");o(aj,"blockHeader");o(sj,"dropEndingNewline");o(QAe,"foldString");o(oj,"foldLine");o(ZAe,"escapeString");o(JAe,"writeFlowSequence");o(lj,"writeBlockSequence");o(e8e,"writeFlowMapping");o(t8e,"writeBlockMapping");o(cj,"detectType");o(Au,"writeNode");o(r8e,"getDuplicateReferences");o(cD,"inspectNode");o(n8e,"dump$1");i8e=n8e,a8e={dump:i8e};o(pD,"renamed");lm=fj,cm=Ej.load,okt=Ej.loadAll,lkt=a8e.dump,ckt=pD("safeLoad","load"),ukt=pD("safeLoadAll","loadAll"),hkt=pD("safeDump","dump")});function vD(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function Gj(t){Id=t}function nn(t,e=""){let r=typeof t=="string"?t:t.source,n={replace:o((i,a)=>{let s=typeof a=="string"?a:a.source;return s=s.replace(ts.caret,"$1"),r=r.replace(i,s),n},"replace"),getRegex:o(()=>new RegExp(r,e),"getRegex")};return n}function pc(t,e){if(e){if(ts.escapeTest.test(t))return t.replace(ts.escapeReplace,Bj)}else if(ts.escapeTestNoEncode.test(t))return t.replace(ts.escapeReplaceNoEncode,Bj);return t}function Fj(t){try{t=encodeURI(t).replace(ts.percentDecode,"%")}catch{return null}return t}function $j(t,e){let r=t.replace(ts.findPipe,(a,s,l)=>{let u=!1,h=s;for(;--h>=0&&l[h]==="\\";)u=!u;return u?"|":" |"}),n=r.split(ts.splitPipe),i=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length<e;)n.push("");for(;i<n.length;i++)n[i]=n[i].trim().replace(ts.slashPipe,"|");return n}function f2(t,e,r){let n=t.length;if(n===0)return"";let i=0;for(;i<n&&t.charAt(n-i-1)===e;)i++;return t.slice(0,n-i)}function $8e(t,e){if(t.indexOf(e[1])===-1)return-1;let r=0;for(let n=0;n<t.length;n++)if(t[n]==="\\")n++;else if(t[n]===e[0])r++;else if(t[n]===e[1]&&(r--,r<0))return n;return-1}function zj(t,e,r,n,i){let a=e.href,s=e.title||null,l=t[1].replace(i.other.outputLinkReplace,"$1");if(t[0].charAt(0)!=="!"){n.state.inLink=!0;let u={type:"link",raw:r,href:a,title:s,text:l,tokens:n.inlineTokens(l)};return n.state.inLink=!1,u}return{type:"image",raw:r,href:a,title:s,text:l}}function z8e(t,e,r){let n=t.match(r.other.indentCodeCompensation);if(n===null)return e;let i=n[1];return e.split(`
+`).map(a=>{let s=a.match(r.other.beginningSpace);if(s===null)return a;let[l]=s;return l.length>=i.length?a.slice(i.length):a}).join(`
+`)}function Jr(t,e){return Md.parse(t,e)}var Id,d2,ts,s8e,o8e,l8e,m2,c8e,xD,Vj,Uj,u8e,bD,h8e,wD,f8e,d8e,Aw,TD,p8e,Hj,m8e,kD,Pj,g8e,y8e,v8e,x8e,Wj,b8e,_w,ED,qj,w8e,Yj,T8e,k8e,E8e,Xj,S8e,C8e,jj,A8e,_8e,D8e,L8e,R8e,N8e,M8e,Cw,I8e,Kj,Qj,O8e,SD,P8e,gD,B8e,Sw,h2,F8e,Bj,hm,Al,fm,p2,_l,um,yD,Md,dkt,pkt,mkt,gkt,ykt,vkt,xkt,Zj=N(()=>{"use strict";o(vD,"_getDefaults");Id=vD();o(Gj,"changeDefaults");d2={exec:o(()=>null,"exec")};o(nn,"edit");ts={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:o(t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\n]*)?(?:\\n|$))`),"listItemRegex"),nextBulletRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),"nextBulletRegex"),hrRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),"hrRegex"),fencesBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}(?:\`\`\`|~~~)`),"fencesBeginRegex"),headingBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}#`),"headingBeginRegex"),htmlBeginRegex:o(t=>new RegExp(`^ {0,${Math.min(3,t-1)}}<(?:[a-z].*>|!--)`,"i"),"htmlBeginRegex")},s8e=/^(?:[ \t]*(?:\n|$))+/,o8e=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,l8e=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,m2=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,c8e=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,xD=/(?:[*+-]|\d{1,9}[.)])/,Vj=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,Uj=nn(Vj).replace(/bull/g,xD).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),u8e=nn(Vj).replace(/bull/g,xD).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),bD=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,h8e=/^[^\n]+/,wD=/(?!\s*\])(?:\\.|[^\[\]\\])+/,f8e=nn(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",wD).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),d8e=nn(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,xD).getRegex(),Aw="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",TD=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,p8e=nn("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",TD).replace("tag",Aw).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Hj=nn(bD).replace("hr",m2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",Aw).getRegex(),m8e=nn(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",Hj).getRegex(),kD={blockquote:m8e,code:o8e,def:f8e,fences:l8e,heading:c8e,hr:m2,html:p8e,lheading:Uj,list:d8e,newline:s8e,paragraph:Hj,table:d2,text:h8e},Pj=nn("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",m2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",Aw).getRegex(),g8e={...kD,lheading:u8e,table:Pj,paragraph:nn(bD).replace("hr",m2).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",Pj).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",Aw).getRegex()},y8e={...kD,html:nn(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",TD).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:d2,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:nn(bD).replace("hr",m2).replace("heading",` *#{1,6} *[^
+]`).replace("lheading",Uj).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},v8e=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,x8e=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,Wj=/^( {2,}|\\)\n(?!\s*$)/,b8e=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,_w=/[\p{P}\p{S}]/u,ED=/[\s\p{P}\p{S}]/u,qj=/[^\s\p{P}\p{S}]/u,w8e=nn(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,ED).getRegex(),Yj=/(?!~)[\p{P}\p{S}]/u,T8e=/(?!~)[\s\p{P}\p{S}]/u,k8e=/(?:[^\s\p{P}\p{S}]|~)/u,E8e=/\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g,Xj=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,S8e=nn(Xj,"u").replace(/punct/g,_w).getRegex(),C8e=nn(Xj,"u").replace(/punct/g,Yj).getRegex(),jj="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",A8e=nn(jj,"gu").replace(/notPunctSpace/g,qj).replace(/punctSpace/g,ED).replace(/punct/g,_w).getRegex(),_8e=nn(jj,"gu").replace(/notPunctSpace/g,k8e).replace(/punctSpace/g,T8e).replace(/punct/g,Yj).getRegex(),D8e=nn("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,qj).replace(/punctSpace/g,ED).replace(/punct/g,_w).getRegex(),L8e=nn(/\\(punct)/,"gu").replace(/punct/g,_w).getRegex(),R8e=nn(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),N8e=nn(TD).replace("(?:-->|$)","-->").getRegex(),M8e=nn("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",N8e).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),Cw=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,I8e=nn(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",Cw).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),Kj=nn(/^!?\[(label)\]\[(ref)\]/).replace("label",Cw).replace("ref",wD).getRegex(),Qj=nn(/^!?\[(ref)\](?:\[\])?/).replace("ref",wD).getRegex(),O8e=nn("reflink|nolink(?!\\()","g").replace("reflink",Kj).replace("nolink",Qj).getRegex(),SD={_backpedal:d2,anyPunctuation:L8e,autolink:R8e,blockSkip:E8e,br:Wj,code:x8e,del:d2,emStrongLDelim:S8e,emStrongRDelimAst:A8e,emStrongRDelimUnd:D8e,escape:v8e,link:I8e,nolink:Qj,punctuation:w8e,reflink:Kj,reflinkSearch:O8e,tag:M8e,text:b8e,url:d2},P8e={...SD,link:nn(/^!?\[(label)\]\((.*?)\)/).replace("label",Cw).getRegex(),reflink:nn(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",Cw).getRegex()},gD={...SD,emStrongRDelimAst:_8e,emStrongLDelim:C8e,url:nn(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/},B8e={...gD,br:nn(Wj).replace("{2,}","*").getRegex(),text:nn(gD.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},Sw={normal:kD,gfm:g8e,pedantic:y8e},h2={normal:SD,gfm:gD,breaks:B8e,pedantic:P8e},F8e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},Bj=o(t=>F8e[t],"getEscapeReplacement");o(pc,"escape");o(Fj,"cleanUrl");o($j,"splitCells");o(f2,"rtrim");o($8e,"findClosingBracket");o(zj,"outputLink");o(z8e,"indentCodeCompensation");hm=class{static{o(this,"_Tokenizer")}options;rules;lexer;constructor(e){this.options=e||Id}space(e){let r=this.rules.block.newline.exec(e);if(r&&r[0].length>0)return{type:"space",raw:r[0]}}code(e){let r=this.rules.block.code.exec(e);if(r){let n=r[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:r[0],codeBlockStyle:"indented",text:this.options.pedantic?n:f2(n,`
+`)}}}fences(e){let r=this.rules.block.fences.exec(e);if(r){let n=r[0],i=z8e(n,r[3]||"",this.rules);return{type:"code",raw:n,lang:r[2]?r[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):r[2],text:i}}}heading(e){let r=this.rules.block.heading.exec(e);if(r){let n=r[2].trim();if(this.rules.other.endingHash.test(n)){let i=f2(n,"#");(this.options.pedantic||!i||this.rules.other.endingSpaceChar.test(i))&&(n=i.trim())}return{type:"heading",raw:r[0],depth:r[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let r=this.rules.block.hr.exec(e);if(r)return{type:"hr",raw:f2(r[0],`
+`)}}blockquote(e){let r=this.rules.block.blockquote.exec(e);if(r){let n=f2(r[0],`
+`).split(`
+`),i="",a="",s=[];for(;n.length>0;){let l=!1,u=[],h;for(h=0;h<n.length;h++)if(this.rules.other.blockquoteStart.test(n[h]))u.push(n[h]),l=!0;else if(!l)u.push(n[h]);else break;n=n.slice(h);let f=u.join(`
+`),d=f.replace(this.rules.other.blockquoteSetextReplace,`
+ $1`).replace(this.rules.other.blockquoteSetextReplace2,"");i=i?`${i}
+${f}`:f,a=a?`${a}
+${d}`:d;let p=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(d,s,!0),this.lexer.state.top=p,n.length===0)break;let m=s.at(-1);if(m?.type==="code")break;if(m?.type==="blockquote"){let g=m,y=g.raw+`
+`+n.join(`
+`),v=this.blockquote(y);s[s.length-1]=v,i=i.substring(0,i.length-g.raw.length)+v.raw,a=a.substring(0,a.length-g.text.length)+v.text;break}else if(m?.type==="list"){let g=m,y=g.raw+`
+`+n.join(`
+`),v=this.list(y);s[s.length-1]=v,i=i.substring(0,i.length-m.raw.length)+v.raw,a=a.substring(0,a.length-g.raw.length)+v.raw,n=y.substring(s.at(-1).raw.length).split(`
+`);continue}}return{type:"blockquote",raw:i,tokens:s,text:a}}}list(e){let r=this.rules.block.list.exec(e);if(r){let n=r[1].trim(),i=n.length>1,a={type:"list",raw:"",ordered:i,start:i?+n.slice(0,-1):"",loose:!1,items:[]};n=i?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=i?n:"[*+-]");let s=this.rules.other.listItemRegex(n),l=!1;for(;e;){let h=!1,f="",d="";if(!(r=s.exec(e))||this.rules.block.hr.test(e))break;f=r[0],e=e.substring(f.length);let p=r[2].split(`
+`,1)[0].replace(this.rules.other.listReplaceTabs,b=>" ".repeat(3*b.length)),m=e.split(`
+`,1)[0],g=!p.trim(),y=0;if(this.options.pedantic?(y=2,d=p.trimStart()):g?y=r[1].length+1:(y=r[2].search(this.rules.other.nonSpaceChar),y=y>4?1:y,d=p.slice(y),y+=r[1].length),g&&this.rules.other.blankLine.test(m)&&(f+=m+`
+`,e=e.substring(m.length+1),h=!0),!h){let b=this.rules.other.nextBulletRegex(y),w=this.rules.other.hrRegex(y),C=this.rules.other.fencesBeginRegex(y),T=this.rules.other.headingBeginRegex(y),E=this.rules.other.htmlBeginRegex(y);for(;e;){let A=e.split(`
+`,1)[0],S;if(m=A,this.options.pedantic?(m=m.replace(this.rules.other.listReplaceNesting," "),S=m):S=m.replace(this.rules.other.tabCharGlobal," "),C.test(m)||T.test(m)||E.test(m)||b.test(m)||w.test(m))break;if(S.search(this.rules.other.nonSpaceChar)>=y||!m.trim())d+=`
+`+S.slice(y);else{if(g||p.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||C.test(p)||T.test(p)||w.test(p))break;d+=`
+`+m}!g&&!m.trim()&&(g=!0),f+=A+`
+`,e=e.substring(A.length+1),p=S.slice(y)}}a.loose||(l?a.loose=!0:this.rules.other.doubleBlankLine.test(f)&&(l=!0));let v=null,x;this.options.gfm&&(v=this.rules.other.listIsTask.exec(d),v&&(x=v[0]!=="[ ] ",d=d.replace(this.rules.other.listReplaceTask,""))),a.items.push({type:"list_item",raw:f,task:!!v,checked:x,loose:!1,text:d,tokens:[]}),a.raw+=f}let u=a.items.at(-1);if(u)u.raw=u.raw.trimEnd(),u.text=u.text.trimEnd();else return;a.raw=a.raw.trimEnd();for(let h=0;h<a.items.length;h++)if(this.lexer.state.top=!1,a.items[h].tokens=this.lexer.blockTokens(a.items[h].text,[]),!a.loose){let f=a.items[h].tokens.filter(p=>p.type==="space"),d=f.length>0&&f.some(p=>this.rules.other.anyLine.test(p.raw));a.loose=d}if(a.loose)for(let h=0;h<a.items.length;h++)a.items[h].loose=!0;return a}}html(e){let r=this.rules.block.html.exec(e);if(r)return{type:"html",block:!0,raw:r[0],pre:r[1]==="pre"||r[1]==="script"||r[1]==="style",text:r[0]}}def(e){let r=this.rules.block.def.exec(e);if(r){let n=r[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),i=r[2]?r[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",a=r[3]?r[3].substring(1,r[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):r[3];return{type:"def",tag:n,raw:r[0],href:i,title:a}}}table(e){let r=this.rules.block.table.exec(e);if(!r||!this.rules.other.tableDelimiter.test(r[2]))return;let n=$j(r[1]),i=r[2].replace(this.rules.other.tableAlignChars,"").split("|"),a=r[3]?.trim()?r[3].replace(this.rules.other.tableRowBlankLine,"").split(`
+`):[],s={type:"table",raw:r[0],header:[],align:[],rows:[]};if(n.length===i.length){for(let l of i)this.rules.other.tableAlignRight.test(l)?s.align.push("right"):this.rules.other.tableAlignCenter.test(l)?s.align.push("center"):this.rules.other.tableAlignLeft.test(l)?s.align.push("left"):s.align.push(null);for(let l=0;l<n.length;l++)s.header.push({text:n[l],tokens:this.lexer.inline(n[l]),header:!0,align:s.align[l]});for(let l of a)s.rows.push($j(l,s.header.length).map((u,h)=>({text:u,tokens:this.lexer.inline(u),header:!1,align:s.align[h]})));return s}}lheading(e){let r=this.rules.block.lheading.exec(e);if(r)return{type:"heading",raw:r[0],depth:r[2].charAt(0)==="="?1:2,text:r[1],tokens:this.lexer.inline(r[1])}}paragraph(e){let r=this.rules.block.paragraph.exec(e);if(r){let n=r[1].charAt(r[1].length-1)===`
+`?r[1].slice(0,-1):r[1];return{type:"paragraph",raw:r[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let r=this.rules.block.text.exec(e);if(r)return{type:"text",raw:r[0],text:r[0],tokens:this.lexer.inline(r[0])}}escape(e){let r=this.rules.inline.escape.exec(e);if(r)return{type:"escape",raw:r[0],text:r[1]}}tag(e){let r=this.rules.inline.tag.exec(e);if(r)return!this.lexer.state.inLink&&this.rules.other.startATag.test(r[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(r[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(r[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(r[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:r[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:r[0]}}link(e){let r=this.rules.inline.link.exec(e);if(r){let n=r[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let s=f2(n.slice(0,-1),"\\");if((n.length-s.length)%2===0)return}else{let s=$8e(r[2],"()");if(s>-1){let u=(r[0].indexOf("!")===0?5:4)+r[1].length+s;r[2]=r[2].substring(0,s),r[0]=r[0].substring(0,u).trim(),r[3]=""}}let i=r[2],a="";if(this.options.pedantic){let s=this.rules.other.pedanticHrefTitle.exec(i);s&&(i=s[1],a=s[3])}else a=r[3]?r[3].slice(1,-1):"";return i=i.trim(),this.rules.other.startAngleBracket.test(i)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?i=i.slice(1):i=i.slice(1,-1)),zj(r,{href:i&&i.replace(this.rules.inline.anyPunctuation,"$1"),title:a&&a.replace(this.rules.inline.anyPunctuation,"$1")},r[0],this.lexer,this.rules)}}reflink(e,r){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let i=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),a=r[i.toLowerCase()];if(!a){let s=n[0].charAt(0);return{type:"text",raw:s,text:s}}return zj(n,a,n[0],this.lexer,this.rules)}}emStrong(e,r,n=""){let i=this.rules.inline.emStrongLDelim.exec(e);if(!i||i[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(i[1]||i[2]||"")||!n||this.rules.inline.punctuation.exec(n)){let s=[...i[0]].length-1,l,u,h=s,f=0,d=i[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(d.lastIndex=0,r=r.slice(-1*e.length+s);(i=d.exec(r))!=null;){if(l=i[1]||i[2]||i[3]||i[4]||i[5]||i[6],!l)continue;if(u=[...l].length,i[3]||i[4]){h+=u;continue}else if((i[5]||i[6])&&s%3&&!((s+u)%3)){f+=u;continue}if(h-=u,h>0)continue;u=Math.min(u,u+h+f);let p=[...i[0]][0].length,m=e.slice(0,s+i.index+p+u);if(Math.min(s,u)%2){let y=m.slice(1,-1);return{type:"em",raw:m,text:y,tokens:this.lexer.inlineTokens(y)}}let g=m.slice(2,-2);return{type:"strong",raw:m,text:g,tokens:this.lexer.inlineTokens(g)}}}}codespan(e){let r=this.rules.inline.code.exec(e);if(r){let n=r[2].replace(this.rules.other.newLineCharGlobal," "),i=this.rules.other.nonSpaceChar.test(n),a=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return i&&a&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:r[0],text:n}}}br(e){let r=this.rules.inline.br.exec(e);if(r)return{type:"br",raw:r[0]}}del(e){let r=this.rules.inline.del.exec(e);if(r)return{type:"del",raw:r[0],text:r[2],tokens:this.lexer.inlineTokens(r[2])}}autolink(e){let r=this.rules.inline.autolink.exec(e);if(r){let n,i;return r[2]==="@"?(n=r[1],i="mailto:"+n):(n=r[1],i=n),{type:"link",raw:r[0],text:n,href:i,tokens:[{type:"text",raw:n,text:n}]}}}url(e){let r;if(r=this.rules.inline.url.exec(e)){let n,i;if(r[2]==="@")n=r[0],i="mailto:"+n;else{let a;do a=r[0],r[0]=this.rules.inline._backpedal.exec(r[0])?.[0]??"";while(a!==r[0]);n=r[0],r[1]==="www."?i="http://"+r[0]:i=r[0]}return{type:"link",raw:r[0],text:n,href:i,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(e){let r=this.rules.inline.text.exec(e);if(r){let n=this.lexer.state.inRawBlock;return{type:"text",raw:r[0],text:r[0],escaped:n}}}},Al=class t{static{o(this,"_Lexer")}tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||Id,this.options.tokenizer=this.options.tokenizer||new hm,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let r={other:ts,block:Sw.normal,inline:h2.normal};this.options.pedantic?(r.block=Sw.pedantic,r.inline=h2.pedantic):this.options.gfm&&(r.block=Sw.gfm,this.options.breaks?r.inline=h2.breaks:r.inline=h2.gfm),this.tokenizer.rules=r}static get rules(){return{block:Sw,inline:h2}}static lex(e,r){return new t(r).lex(e)}static lexInline(e,r){return new t(r).inlineTokens(e)}lex(e){e=e.replace(ts.carriageReturn,`
+`),this.blockTokens(e,this.tokens);for(let r=0;r<this.inlineQueue.length;r++){let n=this.inlineQueue[r];this.inlineTokens(n.src,n.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,r=[],n=!1){for(this.options.pedantic&&(e=e.replace(ts.tabCharGlobal," ").replace(ts.spaceLine,""));e;){let i;if(this.options.extensions?.block?.some(s=>(i=s.call({lexer:this},e,r))?(e=e.substring(i.raw.length),r.push(i),!0):!1))continue;if(i=this.tokenizer.space(e)){e=e.substring(i.raw.length);let s=r.at(-1);i.raw.length===1&&s!==void 0?s.raw+=`
+`:r.push(i);continue}if(i=this.tokenizer.code(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=`
+`+i.raw,s.text+=`
+`+i.text,this.inlineQueue.at(-1).src=s.text):r.push(i);continue}if(i=this.tokenizer.fences(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.heading(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.hr(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.blockquote(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.list(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.html(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.def(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=`
+`+i.raw,s.text+=`
+`+i.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title});continue}if(i=this.tokenizer.table(e)){e=e.substring(i.raw.length),r.push(i);continue}if(i=this.tokenizer.lheading(e)){e=e.substring(i.raw.length),r.push(i);continue}let a=e;if(this.options.extensions?.startBlock){let s=1/0,l=e.slice(1),u;this.options.extensions.startBlock.forEach(h=>{u=h.call({lexer:this},l),typeof u=="number"&&u>=0&&(s=Math.min(s,u))}),s<1/0&&s>=0&&(a=e.substring(0,s+1))}if(this.state.top&&(i=this.tokenizer.paragraph(a))){let s=r.at(-1);n&&s?.type==="paragraph"?(s.raw+=`
+`+i.raw,s.text+=`
+`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):r.push(i),n=a.length!==e.length,e=e.substring(i.raw.length);continue}if(i=this.tokenizer.text(e)){e=e.substring(i.raw.length);let s=r.at(-1);s?.type==="text"?(s.raw+=`
+`+i.raw,s.text+=`
+`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):r.push(i);continue}if(e){let s="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=!0,r}inline(e,r=[]){return this.inlineQueue.push({src:e,tokens:r}),r}inlineTokens(e,r=[]){let n=e,i=null;if(this.tokens.links){let l=Object.keys(this.tokens.links);if(l.length>0)for(;(i=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)l.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(i=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)n=n.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;(i=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,i.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let a=!1,s="";for(;e;){a||(s=""),a=!1;let l;if(this.options.extensions?.inline?.some(h=>(l=h.call({lexer:this},e,r))?(e=e.substring(l.raw.length),r.push(l),!0):!1))continue;if(l=this.tokenizer.escape(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.tag(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.link(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(l.raw.length);let h=r.at(-1);l.type==="text"&&h?.type==="text"?(h.raw+=l.raw,h.text+=l.text):r.push(l);continue}if(l=this.tokenizer.emStrong(e,n,s)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.codespan(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.br(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.del(e)){e=e.substring(l.raw.length),r.push(l);continue}if(l=this.tokenizer.autolink(e)){e=e.substring(l.raw.length),r.push(l);continue}if(!this.state.inLink&&(l=this.tokenizer.url(e))){e=e.substring(l.raw.length),r.push(l);continue}let u=e;if(this.options.extensions?.startInline){let h=1/0,f=e.slice(1),d;this.options.extensions.startInline.forEach(p=>{d=p.call({lexer:this},f),typeof d=="number"&&d>=0&&(h=Math.min(h,d))}),h<1/0&&h>=0&&(u=e.substring(0,h+1))}if(l=this.tokenizer.inlineText(u)){e=e.substring(l.raw.length),l.raw.slice(-1)!=="_"&&(s=l.raw.slice(-1)),a=!0;let h=r.at(-1);h?.type==="text"?(h.raw+=l.raw,h.text+=l.text):r.push(l);continue}if(e){let h="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(h);break}else throw new Error(h)}}return r}},fm=class{static{o(this,"_Renderer")}options;parser;constructor(e){this.options=e||Id}space(e){return""}code({text:e,lang:r,escaped:n}){let i=(r||"").match(ts.notSpaceStart)?.[0],a=e.replace(ts.endingNewline,"")+`
+`;return i?'<pre><code class="language-'+pc(i)+'">'+(n?a:pc(a,!0))+`</code></pre>
+`:"<pre><code>"+(n?a:pc(a,!0))+`</code></pre>
+`}blockquote({tokens:e}){return`<blockquote>
+${this.parser.parse(e)}</blockquote>
+`}html({text:e}){return e}heading({tokens:e,depth:r}){return`<h${r}>${this.parser.parseInline(e)}</h${r}>
+`}hr(e){return`<hr>
+`}list(e){let r=e.ordered,n=e.start,i="";for(let l=0;l<e.items.length;l++){let u=e.items[l];i+=this.listitem(u)}let a=r?"ol":"ul",s=r&&n!==1?' start="'+n+'"':"";return"<"+a+s+`>
+`+i+"</"+a+`>
+`}listitem(e){let r="";if(e.task){let n=this.checkbox({checked:!!e.checked});e.loose?e.tokens[0]?.type==="paragraph"?(e.tokens[0].text=n+" "+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&e.tokens[0].tokens[0].type==="text"&&(e.tokens[0].tokens[0].text=n+" "+pc(e.tokens[0].tokens[0].text),e.tokens[0].tokens[0].escaped=!0)):e.tokens.unshift({type:"text",raw:n+" ",text:n+" ",escaped:!0}):r+=n+" "}return r+=this.parser.parse(e.tokens,!!e.loose),`<li>${r}</li>
+`}checkbox({checked:e}){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>
+`}table(e){let r="",n="";for(let a=0;a<e.header.length;a++)n+=this.tablecell(e.header[a]);r+=this.tablerow({text:n});let i="";for(let a=0;a<e.rows.length;a++){let s=e.rows[a];n="";for(let l=0;l<s.length;l++)n+=this.tablecell(s[l]);i+=this.tablerow({text:n})}return i&&(i=`<tbody>${i}</tbody>`),`<table>
+<thead>
+`+r+`</thead>
+`+i+`</table>
+`}tablerow({text:e}){return`<tr>
+${e}</tr>
+`}tablecell(e){let r=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+r+`</${n}>
+`}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${pc(e,!0)}</code>`}br(e){return"<br>"}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:r,tokens:n}){let i=this.parser.parseInline(n),a=Fj(e);if(a===null)return i;e=a;let s='<a href="'+e+'"';return r&&(s+=' title="'+pc(r)+'"'),s+=">"+i+"</a>",s}image({href:e,title:r,text:n}){let i=Fj(e);if(i===null)return pc(n);e=i;let a=`<img src="${e}" alt="${n}"`;return r&&(a+=` title="${pc(r)}"`),a+=">",a}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:pc(e.text)}},p2=class{static{o(this,"_TextRenderer")}strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}},_l=class t{static{o(this,"_Parser")}options;renderer;textRenderer;constructor(e){this.options=e||Id,this.options.renderer=this.options.renderer||new fm,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new p2}static parse(e,r){return new t(r).parse(e)}static parseInline(e,r){return new t(r).parseInline(e)}parse(e,r=!0){let n="";for(let i=0;i<e.length;i++){let a=e[i];if(this.options.extensions?.renderers?.[a.type]){let l=a,u=this.options.extensions.renderers[l.type].call({parser:this},l);if(u!==!1||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(l.type)){n+=u||"";continue}}let s=a;switch(s.type){case"space":{n+=this.renderer.space(s);continue}case"hr":{n+=this.renderer.hr(s);continue}case"heading":{n+=this.renderer.heading(s);continue}case"code":{n+=this.renderer.code(s);continue}case"table":{n+=this.renderer.table(s);continue}case"blockquote":{n+=this.renderer.blockquote(s);continue}case"list":{n+=this.renderer.list(s);continue}case"html":{n+=this.renderer.html(s);continue}case"paragraph":{n+=this.renderer.paragraph(s);continue}case"text":{let l=s,u=this.renderer.text(l);for(;i+1<e.length&&e[i+1].type==="text";)l=e[++i],u+=`
+`+this.renderer.text(l);r?n+=this.renderer.paragraph({type:"paragraph",raw:u,text:u,tokens:[{type:"text",raw:u,text:u,escaped:!0}]}):n+=u;continue}default:{let l='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(l),"";throw new Error(l)}}}return n}parseInline(e,r=this.renderer){let n="";for(let i=0;i<e.length;i++){let a=e[i];if(this.options.extensions?.renderers?.[a.type]){let l=this.options.extensions.renderers[a.type].call({parser:this},a);if(l!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(a.type)){n+=l||"";continue}}let s=a;switch(s.type){case"escape":{n+=r.text(s);break}case"html":{n+=r.html(s);break}case"link":{n+=r.link(s);break}case"image":{n+=r.image(s);break}case"strong":{n+=r.strong(s);break}case"em":{n+=r.em(s);break}case"codespan":{n+=r.codespan(s);break}case"br":{n+=r.br(s);break}case"del":{n+=r.del(s);break}case"text":{n+=r.text(s);break}default:{let l='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(l),"";throw new Error(l)}}}return n}},um=class{static{o(this,"_Hooks")}options;block;constructor(e){this.options=e||Id}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}provideLexer(){return this.block?Al.lex:Al.lexInline}provideParser(){return this.block?_l.parse:_l.parseInline}},yD=class{static{o(this,"Marked")}defaults=vD();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=_l;Renderer=fm;TextRenderer=p2;Lexer=Al;Tokenizer=hm;Hooks=um;constructor(...e){this.use(...e)}walkTokens(e,r){let n=[];for(let i of e)switch(n=n.concat(r.call(this,i)),i.type){case"table":{let a=i;for(let s of a.header)n=n.concat(this.walkTokens(s.tokens,r));for(let s of a.rows)for(let l of s)n=n.concat(this.walkTokens(l.tokens,r));break}case"list":{let a=i;n=n.concat(this.walkTokens(a.items,r));break}default:{let a=i;this.defaults.extensions?.childTokens?.[a.type]?this.defaults.extensions.childTokens[a.type].forEach(s=>{let l=a[s].flat(1/0);n=n.concat(this.walkTokens(l,r))}):a.tokens&&(n=n.concat(this.walkTokens(a.tokens,r)))}}return n}use(...e){let r=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let i={...n};if(i.async=this.defaults.async||i.async||!1,n.extensions&&(n.extensions.forEach(a=>{if(!a.name)throw new Error("extension name required");if("renderer"in a){let s=r.renderers[a.name];s?r.renderers[a.name]=function(...l){let u=a.renderer.apply(this,l);return u===!1&&(u=s.apply(this,l)),u}:r.renderers[a.name]=a.renderer}if("tokenizer"in a){if(!a.level||a.level!=="block"&&a.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let s=r[a.level];s?s.unshift(a.tokenizer):r[a.level]=[a.tokenizer],a.start&&(a.level==="block"?r.startBlock?r.startBlock.push(a.start):r.startBlock=[a.start]:a.level==="inline"&&(r.startInline?r.startInline.push(a.start):r.startInline=[a.start]))}"childTokens"in a&&a.childTokens&&(r.childTokens[a.name]=a.childTokens)}),i.extensions=r),n.renderer){let a=this.defaults.renderer||new fm(this.defaults);for(let s in n.renderer){if(!(s in a))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let l=s,u=n.renderer[l],h=a[l];a[l]=(...f)=>{let d=u.apply(a,f);return d===!1&&(d=h.apply(a,f)),d||""}}i.renderer=a}if(n.tokenizer){let a=this.defaults.tokenizer||new hm(this.defaults);for(let s in n.tokenizer){if(!(s in a))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let l=s,u=n.tokenizer[l],h=a[l];a[l]=(...f)=>{let d=u.apply(a,f);return d===!1&&(d=h.apply(a,f)),d}}i.tokenizer=a}if(n.hooks){let a=this.defaults.hooks||new um;for(let s in n.hooks){if(!(s in a))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let l=s,u=n.hooks[l],h=a[l];um.passThroughHooks.has(s)?a[l]=f=>{if(this.defaults.async)return Promise.resolve(u.call(a,f)).then(p=>h.call(a,p));let d=u.call(a,f);return h.call(a,d)}:a[l]=(...f)=>{let d=u.apply(a,f);return d===!1&&(d=h.apply(a,f)),d}}i.hooks=a}if(n.walkTokens){let a=this.defaults.walkTokens,s=n.walkTokens;i.walkTokens=function(l){let u=[];return u.push(s.call(this,l)),a&&(u=u.concat(a.call(this,l))),u}}this.defaults={...this.defaults,...i}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,r){return Al.lex(e,r??this.defaults)}parser(e,r){return _l.parse(e,r??this.defaults)}parseMarkdown(e){return o((n,i)=>{let a={...i},s={...this.defaults,...a},l=this.onError(!!s.silent,!!s.async);if(this.defaults.async===!0&&a.async===!1)return l(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return l(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));s.hooks&&(s.hooks.options=s,s.hooks.block=e);let u=s.hooks?s.hooks.provideLexer():e?Al.lex:Al.lexInline,h=s.hooks?s.hooks.provideParser():e?_l.parse:_l.parseInline;if(s.async)return Promise.resolve(s.hooks?s.hooks.preprocess(n):n).then(f=>u(f,s)).then(f=>s.hooks?s.hooks.processAllTokens(f):f).then(f=>s.walkTokens?Promise.all(this.walkTokens(f,s.walkTokens)).then(()=>f):f).then(f=>h(f,s)).then(f=>s.hooks?s.hooks.postprocess(f):f).catch(l);try{s.hooks&&(n=s.hooks.preprocess(n));let f=u(n,s);s.hooks&&(f=s.hooks.processAllTokens(f)),s.walkTokens&&this.walkTokens(f,s.walkTokens);let d=h(f,s);return s.hooks&&(d=s.hooks.postprocess(d)),d}catch(f){return l(f)}},"parse")}onError(e,r){return n=>{if(n.message+=`
+Please report this to https://github.com/markedjs/marked.`,e){let i="<p>An error occurred:</p><pre>"+pc(n.message+"",!0)+"</pre>";return r?Promise.resolve(i):i}if(r)return Promise.reject(n);throw n}}},Md=new yD;o(Jr,"marked");Jr.options=Jr.setOptions=function(t){return Md.setOptions(t),Jr.defaults=Md.defaults,Gj(Jr.defaults),Jr};Jr.getDefaults=vD;Jr.defaults=Id;Jr.use=function(...t){return Md.use(...t),Jr.defaults=Md.defaults,Gj(Jr.defaults),Jr};Jr.walkTokens=function(t,e){return Md.walkTokens(t,e)};Jr.parseInline=Md.parseInline;Jr.Parser=_l;Jr.parser=_l.parse;Jr.Renderer=fm;Jr.TextRenderer=p2;Jr.Lexer=Al;Jr.lexer=Al.lex;Jr.Tokenizer=hm;Jr.Hooks=um;Jr.parse=Jr;dkt=Jr.options,pkt=Jr.setOptions,mkt=Jr.use,gkt=Jr.walkTokens,ykt=Jr.parseInline,vkt=_l.parse,xkt=Al.lex});function G8e(t,{markdownAutoWrap:e}){let n=t.replace(/<br\/>/g,`
+`).replace(/\n{2,}/g,`
+`),i=B4(n);return e===!1?i.replace(/ /g,"&nbsp;"):i}function Jj(t,e={}){let r=G8e(t,e),n=Jr.lexer(r),i=[[]],a=0;function s(l,u="normal"){l.type==="text"?l.text.split(`
+`).forEach((f,d)=>{d!==0&&(a++,i.push([])),f.split(" ").forEach(p=>{p=p.replace(/&#39;/g,"'"),p&&i[a].push({content:p,type:u})})}):l.type==="strong"||l.type==="em"?l.tokens.forEach(h=>{s(h,l.type)}):l.type==="html"&&i[a].push({content:l.text,type:"normal"})}return o(s,"processNode"),n.forEach(l=>{l.type==="paragraph"?l.tokens?.forEach(u=>{s(u)}):l.type==="html"&&i[a].push({content:l.text,type:"normal"})}),i}function eK(t,{markdownAutoWrap:e}={}){let r=Jr.lexer(t);function n(i){return i.type==="text"?e===!1?i.text.replace(/\n */g,"<br/>").replace(/ /g,"&nbsp;"):i.text.replace(/\n */g,"<br/>"):i.type==="strong"?`<strong>${i.tokens?.map(n).join("")}</strong>`:i.type==="em"?`<em>${i.tokens?.map(n).join("")}</em>`:i.type==="paragraph"?`<p>${i.tokens?.map(n).join("")}</p>`:i.type==="space"?"":i.type==="html"?`${i.text}`:i.type==="escape"?i.text:`Unsupported markdown: ${i.type}`}return o(n,"output"),r.map(n).join("")}var tK=N(()=>{"use strict";Zj();PC();o(G8e,"preprocessMarkdown");o(Jj,"markdownToLines");o(eK,"markdownToHTML")});function V8e(t){return Intl.Segmenter?[...new Intl.Segmenter().segment(t)].map(e=>e.segment):[...t]}function U8e(t,e){let r=V8e(e.content);return rK(t,[],r,e.type)}function rK(t,e,r,n){if(r.length===0)return[{content:e.join(""),type:n},{content:"",type:n}];let[i,...a]=r,s=[...e,i];return t([{content:s.join(""),type:n}])?rK(t,s,a,n):(e.length===0&&i&&(e.push(i),r.shift()),[{content:e.join(""),type:n},{content:r.join(""),type:n}])}function nK(t,e){if(t.some(({content:r})=>r.includes(`
+`)))throw new Error("splitLineToFitWidth does not support newlines in the line");return CD(t,e)}function CD(t,e,r=[],n=[]){if(t.length===0)return n.length>0&&r.push(n),r.length>0?r:[];let i="";t[0].content===" "&&(i=" ",t.shift());let a=t.shift()??{content:" ",type:"normal"},s=[...n];if(i!==""&&s.push({content:i,type:"normal"}),s.push(a),e(s))return CD(t,e,r,s);if(n.length>0)r.push(n),t.unshift(a);else if(a.content){let[l,u]=U8e(e,a);r.push([l]),u.content&&t.unshift(u)}return CD(t,e,r)}var iK=N(()=>{"use strict";o(V8e,"splitTextToChars");o(U8e,"splitWordToFitWidth");o(rK,"splitWordToFitWidthRecursion");o(nK,"splitLineToFitWidth");o(CD,"splitLineToFitWidthRecursion")});function aK(t,e){e&&t.attr("style",e)}async function H8e(t,e,r,n,i=!1){let a=t.append("foreignObject");a.attr("width",`${10*r}px`),a.attr("height",`${10*r}px`);let s=a.append("xhtml:div"),l=e.label;e.label&&pi(e.label)&&(l=await mh(e.label.replace(Ze.lineBreakRegex,`
+`),me()));let u=e.isNode?"nodeLabel":"edgeLabel",h=s.append("span");h.html(l),aK(h,e.labelStyle),h.attr("class",`${u} ${n}`),aK(s,e.labelStyle),s.style("display","table-cell"),s.style("white-space","nowrap"),s.style("line-height","1.5"),s.style("max-width",r+"px"),s.style("text-align","center"),s.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&s.attr("class","labelBkg");let f=s.node().getBoundingClientRect();return f.width===r&&(s.style("display","table"),s.style("white-space","break-spaces"),s.style("width",r+"px"),f=s.node().getBoundingClientRect()),a.node()}function AD(t,e,r){return t.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",e*r-.1+"em").attr("dy",r+"em")}function W8e(t,e,r){let n=t.append("text"),i=AD(n,1,e);_D(i,r);let a=i.node().getComputedTextLength();return n.remove(),a}function sK(t,e,r){let n=t.append("text"),i=AD(n,1,e);_D(i,[{content:r,type:"normal"}]);let a=i.node()?.getBoundingClientRect();return a&&n.remove(),a}function q8e(t,e,r,n=!1){let a=e.append("g"),s=a.insert("rect").attr("class","background").attr("style","stroke: none"),l=a.append("text").attr("y","-10.1"),u=0;for(let h of r){let f=o(p=>W8e(a,1.1,p)<=t,"checkWidth"),d=f(h)?[h]:nK(h,f);for(let p of d){let m=AD(l,u,1.1);_D(m,p),u++}}if(n){let h=l.node().getBBox(),f=2;return s.attr("x",h.x-f).attr("y",h.y-f).attr("width",h.width+2*f).attr("height",h.height+2*f),a.node()}else return l.node()}function _D(t,e){t.text(""),e.forEach((r,n)=>{let i=t.append("tspan").attr("font-style",r.type==="em"?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight",r.type==="strong"?"bold":"normal");n===0?i.text(r.content):i.text(" "+r.content)})}function DD(t){return t.replace(/fa[bklrs]?:fa-[\w-]+/g,e=>`<i class='${e.replace(":"," ")}'></i>`)}var Hn,to=N(()=>{"use strict";zt();gr();dr();vt();tK();ir();iK();o(aK,"applyStyle");o(H8e,"addHtmlSpan");o(AD,"createTspan");o(W8e,"computeWidthOfText");o(sK,"computeDimensionOfText");o(q8e,"createFormattedText");o(_D,"updateTextContentAndStyles");o(DD,"replaceIconSubstring");Hn=o(async(t,e="",{style:r="",isTitle:n=!1,classes:i="",useHtmlLabels:a=!0,isNode:s=!0,width:l=200,addSvgBackground:u=!1}={},h)=>{if(Y.debug("XYZ createText",e,r,n,i,a,s,"addSvgBackground: ",u),a){let f=eK(e,h),d=DD(na(f)),p=e.replace(/\\\\/g,"\\"),m={isNode:s,label:pi(e)?p:d,labelStyle:r.replace("fill:","color:")};return await H8e(t,m,l,i,u)}else{let f=e.replace(/<br\s*\/?>/g,"<br/>"),d=Jj(f.replace("<br>","<br/>"),h),p=q8e(l,t,d,e?u:!1);if(s){/stroke:/.exec(r)&&(r=r.replace("stroke:","lineColor:"));let m=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");Ge(p).attr("style",m)}else{let m=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/background:/g,"fill:");Ge(p).select("rect").attr("style",m.replace(/background:/g,"fill:"));let g=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");Ge(p).select("text").attr("style",g)}return p}},"createText")});function Xt(t){let e=t.map((r,n)=>`${n===0?"M":"L"}${r.x},${r.y}`);return e.push("Z"),e.join(" ")}function Fo(t,e,r,n,i,a){let s=[],u=r-t,h=n-e,f=u/a,d=2*Math.PI/f,p=e+h/2;for(let m=0;m<=50;m++){let g=m/50,y=t+g*u,v=p+i*Math.sin(d*(y-t));s.push({x:y,y:v})}return s}function Lw(t,e,r,n,i,a){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d<n;d++){let p=l+d*f,m=t+r*Math.cos(p),g=e+r*Math.sin(p);s.push({x:-m,y:-g})}return s}var pt,Dw,je,ht,Ft=N(()=>{"use strict";to();zt();dr();Ya();gr();ir();pt=o(async(t,e,r)=>{let n,i=e.useHtmlLabels||fr(me()?.htmlLabels);r?n=r:n="node default";let a=t.insert("g").attr("class",n).attr("id",e.domId||e.id),s=a.insert("g").attr("class","label").attr("style",$n(e.labelStyle)),l;e.label===void 0?l="":l=typeof e.label=="string"?e.label:e.label[0];let u=await Hn(s,Tr(na(l),me()),{useHtmlLabels:i,width:e.width||me().flowchart?.wrappingWidth,cssClasses:"markdown-node-label",style:e.labelStyle,addSvgBackground:!!e.icon||!!e.img}),h=u.getBBox(),f=(e?.padding??0)/2;if(i){let d=u.children[0],p=Ge(u),m=d.getElementsByTagName("img");if(m){let g=l.replace(/<img[^>]*>/g,"").trim()==="";await Promise.all([...m].map(y=>new Promise(v=>{function x(){if(y.style.display="flex",y.style.flexDirection="column",g){let b=me().fontSize?me().fontSize:window.getComputedStyle(document.body).fontSize,w=5,[C=or.fontSize]=Bo(b),T=C*w+"px";y.style.minWidth=T,y.style.maxWidth=T}else y.style.width="100%";v(y)}o(x,"setupImage"),setTimeout(()=>{y.complete&&x()}),y.addEventListener("error",x),y.addEventListener("load",x)})))}h=d.getBoundingClientRect(),p.attr("width",h.width),p.attr("height",h.height)}return i?s.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"):s.attr("transform","translate(0, "+-h.height/2+")"),e.centerLabel&&s.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),s.insert("rect",":first-child"),{shapeSvg:a,bbox:h,halfPadding:f,label:s}},"labelHelper"),Dw=o(async(t,e,r)=>{let n=r.useHtmlLabels||fr(me()?.flowchart?.htmlLabels),i=t.insert("g").attr("class","label").attr("style",r.labelStyle||""),a=await Hn(i,Tr(na(e),me()),{useHtmlLabels:n,width:r.width||me()?.flowchart?.wrappingWidth,style:r.labelStyle,addSvgBackground:!!r.icon||!!r.img}),s=a.getBBox(),l=r.padding/2;if(fr(me()?.flowchart?.htmlLabels)){let u=a.children[0],h=Ge(a);s=u.getBoundingClientRect(),h.attr("width",s.width),h.attr("height",s.height)}return n?i.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"):i.attr("transform","translate(0, "+-s.height/2+")"),r.centerLabel&&i.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),i.insert("rect",":first-child"),{shapeSvg:t,bbox:s,halfPadding:l,label:i}},"insertLabel"),je=o((t,e)=>{let r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds"),ht=o((t,e)=>(t.look==="handDrawn"?"rough-node":"node")+" "+t.cssClasses+" "+(e||""),"getNodeClasses");o(Xt,"createPathFromPoints");o(Fo,"generateFullSineWavePoints");o(Lw,"generateCirclePoints")});function Y8e(t,e){return t.intersect(e)}var oK,lK=N(()=>{"use strict";o(Y8e,"intersectNode");oK=Y8e});function X8e(t,e,r,n){var i=t.x,a=t.y,s=i-n.x,l=a-n.y,u=Math.sqrt(e*e*l*l+r*r*s*s),h=Math.abs(e*r*s/u);n.x<i&&(h=-h);var f=Math.abs(e*r*l/u);return n.y<a&&(f=-f),{x:i+h,y:a+f}}var Rw,LD=N(()=>{"use strict";o(X8e,"intersectEllipse");Rw=X8e});function j8e(t,e,r){return Rw(t,e,e,r)}var cK,uK=N(()=>{"use strict";LD();o(j8e,"intersectCircle");cK=j8e});function K8e(t,e,r,n){var i,a,s,l,u,h,f,d,p,m,g,y,v,x,b;if(i=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,p=i*r.x+s*r.y+u,m=i*n.x+s*n.y+u,!(p!==0&&m!==0&&hK(p,m))&&(a=n.y-r.y,l=r.x-n.x,h=n.x*r.y-r.x*n.y,f=a*t.x+l*t.y+h,d=a*e.x+l*e.y+h,!(f!==0&&d!==0&&hK(f,d))&&(g=i*l-a*s,g!==0)))return y=Math.abs(g/2),v=s*h-l*u,x=v<0?(v-y)/g:(v+y)/g,v=a*u-i*h,b=v<0?(v-y)/g:(v+y)/g,{x,y:b}}function hK(t,e){return t*e>0}var fK,dK=N(()=>{"use strict";o(K8e,"intersectLine");o(hK,"sameSign");fK=K8e});function Q8e(t,e,r){let n=t.x,i=t.y,a=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;typeof e.forEach=="function"?e.forEach(function(f){s=Math.min(s,f.x),l=Math.min(l,f.y)}):(s=Math.min(s,e.x),l=Math.min(l,e.y));let u=n-t.width/2-s,h=i-t.height/2-l;for(let f=0;f<e.length;f++){let d=e[f],p=e[f<e.length-1?f+1:0],m=fK(t,r,{x:u+d.x,y:h+d.y},{x:u+p.x,y:h+p.y});m&&a.push(m)}return a.length?(a.length>1&&a.sort(function(f,d){let p=f.x-r.x,m=f.y-r.y,g=Math.sqrt(p*p+m*m),y=d.x-r.x,v=d.y-r.y,x=Math.sqrt(y*y+v*v);return g<x?-1:g===x?0:1}),a[0]):t}var pK,mK=N(()=>{"use strict";dK();o(Q8e,"intersectPolygon");pK=Q8e});var Z8e,Vh,RD=N(()=>{"use strict";Z8e=o((t,e)=>{var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2,u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=a===0?0:l*i/a,h=l):(i<0&&(s=-s),u=s,h=i===0?0:s*a/i),{x:r+u,y:n+h}},"intersectRect"),Vh=Z8e});var Ye,Ht=N(()=>{"use strict";lK();uK();LD();mK();RD();Ye={node:oK,circle:cK,ellipse:Rw,polygon:pK,rect:Vh}});var gK,mc,J8e,ND,Qe,Ke,Ut=N(()=>{"use strict";zt();gK=o(t=>{let{handDrawnSeed:e}=me();return{fill:t,hachureAngle:120,hachureGap:4,fillWeight:2,roughness:.7,stroke:t,seed:e}},"solidStateFill"),mc=o(t=>{let e=J8e([...t.cssCompiledStyles||[],...t.cssStyles||[]]);return{stylesMap:e,stylesArray:[...e]}},"compileStyles"),J8e=o(t=>{let e=new Map;return t.forEach(r=>{let[n,i]=r.split(":");e.set(n.trim(),i?.trim())}),e},"styles2Map"),ND=o(t=>t==="color"||t==="font-size"||t==="font-family"||t==="font-weight"||t==="font-style"||t==="text-decoration"||t==="text-align"||t==="text-transform"||t==="line-height"||t==="letter-spacing"||t==="word-spacing"||t==="text-shadow"||t==="text-overflow"||t==="white-space"||t==="word-wrap"||t==="word-break"||t==="overflow-wrap"||t==="hyphens","isLabelStyle"),Qe=o(t=>{let{stylesArray:e}=mc(t),r=[],n=[],i=[],a=[];return e.forEach(s=>{let l=s[0];ND(l)?r.push(s.join(":")+" !important"):(n.push(s.join(":")+" !important"),l.includes("stroke")&&i.push(s.join(":")+" !important"),l==="fill"&&a.push(s.join(":")+" !important"))}),{labelStyles:r.join(";"),nodeStyles:n.join(";"),stylesArray:e,borderStyles:i,backgroundStyles:a}},"styles2String"),Ke=o((t,e)=>{let{themeVariables:r,handDrawnSeed:n}=me(),{nodeBorder:i,mainBkg:a}=r,{stylesMap:s}=mc(t);return Object.assign({roughness:.7,fill:s.get("fill")||a,fillStyle:"hachure",fillWeight:4,hachureGap:5.2,stroke:s.get("stroke")||i,seed:n,strokeWidth:s.get("stroke-width")?.replace("px","")||1.3,fillLineDash:[0,0]},e)},"userNodeOverrides")});function MD(t,e,r){if(t&&t.length){let[n,i]=e,a=Math.PI/180*r,s=Math.cos(a),l=Math.sin(a);for(let u of t){let[h,f]=u;u[0]=(h-n)*s-(f-i)*l+n,u[1]=(h-n)*l+(f-i)*s+i}}}function e_e(t,e){return t[0]===e[0]&&t[1]===e[1]}function t_e(t,e,r,n=1){let i=r,a=Math.max(e,.1),s=t[0]&&t[0][0]&&typeof t[0][0]=="number"?[t]:t,l=[0,0];if(i)for(let h of s)MD(h,l,i);let u=function(h,f,d){let p=[];for(let b of h){let w=[...b];e_e(w[0],w[w.length-1])||w.push([w[0][0],w[0][1]]),w.length>2&&p.push(w)}let m=[];f=Math.max(f,.1);let g=[];for(let b of p)for(let w=0;w<b.length-1;w++){let C=b[w],T=b[w+1];if(C[1]!==T[1]){let E=Math.min(C[1],T[1]);g.push({ymin:E,ymax:Math.max(C[1],T[1]),x:E===C[1]?C[0]:T[0],islope:(T[0]-C[0])/(T[1]-C[1])})}}if(g.sort((b,w)=>b.ymin<w.ymin?-1:b.ymin>w.ymin?1:b.x<w.x?-1:b.x>w.x?1:b.ymax===w.ymax?0:(b.ymax-w.ymax)/Math.abs(b.ymax-w.ymax)),!g.length)return m;let y=[],v=g[0].ymin,x=0;for(;y.length||g.length;){if(g.length){let b=-1;for(let w=0;w<g.length&&!(g[w].ymin>v);w++)b=w;g.splice(0,b+1).forEach(w=>{y.push({s:v,edge:w})})}if(y=y.filter(b=>!(b.edge.ymax<=v)),y.sort((b,w)=>b.edge.x===w.edge.x?0:(b.edge.x-w.edge.x)/Math.abs(b.edge.x-w.edge.x)),(d!==1||x%f==0)&&y.length>1)for(let b=0;b<y.length;b+=2){let w=b+1;if(w>=y.length)break;let C=y[b].edge,T=y[w].edge;m.push([[Math.round(C.x),v],[Math.round(T.x),v]])}v+=d,y.forEach(b=>{b.edge.x=b.edge.x+d*b.edge.islope}),x++}return m}(s,a,n);if(i){for(let h of s)MD(h,l,-i);(function(h,f,d){let p=[];h.forEach(m=>p.push(...m)),MD(p,f,d)})(u,l,-i)}return u}function x2(t,e){var r;let n=e.hachureAngle+90,i=e.hachureGap;i<0&&(i=4*e.strokeWidth),i=Math.round(Math.max(i,.1));let a=1;return e.roughness>=1&&(((r=e.randomizer)===null||r===void 0?void 0:r.next())||Math.random())>.7&&(a=i),t_e(t,i,n,a||1)}function zw(t){let e=t[0],r=t[1];return Math.sqrt(Math.pow(e[0]-r[0],2)+Math.pow(e[1]-r[1],2))}function OD(t,e){return t.type===e}function jD(t){let e=[],r=function(s){let l=new Array;for(;s!=="";)if(s.match(/^([ \t\r\n,]+)/))s=s.substr(RegExp.$1.length);else if(s.match(/^([aAcChHlLmMqQsStTvVzZ])/))l[l.length]={type:r_e,text:RegExp.$1},s=s.substr(RegExp.$1.length);else{if(!s.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))return[];l[l.length]={type:ID,text:`${parseFloat(RegExp.$1)}`},s=s.substr(RegExp.$1.length)}return l[l.length]={type:yK,text:""},l}(t),n="BOD",i=0,a=r[i];for(;!OD(a,yK);){let s=0,l=[];if(n==="BOD"){if(a.text!=="M"&&a.text!=="m")return jD("M0,0"+t);i++,s=Nw[a.text],n=a.text}else OD(a,ID)?s=Nw[n]:(i++,s=Nw[a.text],n=a.text);if(!(i+s<r.length))throw new Error("Path data ended short");for(let u=i;u<i+s;u++){let h=r[u];if(!OD(h,ID))throw new Error("Param not a number: "+n+","+h.text);l[l.length]=+h.text}if(typeof Nw[n]!="number")throw new Error("Bad segment: "+n);{let u={key:n,data:l};e.push(u),i+=s,a=r[i],n==="M"&&(n="L"),n==="m"&&(n="l")}}return e}function SK(t){let e=0,r=0,n=0,i=0,a=[];for(let{key:s,data:l}of t)switch(s){case"M":a.push({key:"M",data:[...l]}),[e,r]=l,[n,i]=l;break;case"m":e+=l[0],r+=l[1],a.push({key:"M",data:[e,r]}),n=e,i=r;break;case"L":a.push({key:"L",data:[...l]}),[e,r]=l;break;case"l":e+=l[0],r+=l[1],a.push({key:"L",data:[e,r]});break;case"C":a.push({key:"C",data:[...l]}),e=l[4],r=l[5];break;case"c":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"C",data:u}),e=u[4],r=u[5];break}case"Q":a.push({key:"Q",data:[...l]}),e=l[2],r=l[3];break;case"q":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"Q",data:u}),e=u[2],r=u[3];break}case"A":a.push({key:"A",data:[...l]}),e=l[5],r=l[6];break;case"a":e+=l[5],r+=l[6],a.push({key:"A",data:[l[0],l[1],l[2],l[3],l[4],e,r]});break;case"H":a.push({key:"H",data:[...l]}),e=l[0];break;case"h":e+=l[0],a.push({key:"H",data:[e]});break;case"V":a.push({key:"V",data:[...l]}),r=l[0];break;case"v":r+=l[0],a.push({key:"V",data:[r]});break;case"S":a.push({key:"S",data:[...l]}),e=l[2],r=l[3];break;case"s":{let u=l.map((h,f)=>f%2?h+r:h+e);a.push({key:"S",data:u}),e=u[2],r=u[3];break}case"T":a.push({key:"T",data:[...l]}),e=l[0],r=l[1];break;case"t":e+=l[0],r+=l[1],a.push({key:"T",data:[e,r]});break;case"Z":case"z":a.push({key:"Z",data:[]}),e=n,r=i}return a}function CK(t){let e=[],r="",n=0,i=0,a=0,s=0,l=0,u=0;for(let{key:h,data:f}of t){switch(h){case"M":e.push({key:"M",data:[...f]}),[n,i]=f,[a,s]=f;break;case"C":e.push({key:"C",data:[...f]}),n=f[4],i=f[5],l=f[2],u=f[3];break;case"L":e.push({key:"L",data:[...f]}),[n,i]=f;break;case"H":n=f[0],e.push({key:"L",data:[n,i]});break;case"V":i=f[0],e.push({key:"L",data:[n,i]});break;case"S":{let d=0,p=0;r==="C"||r==="S"?(d=n+(n-l),p=i+(i-u)):(d=n,p=i),e.push({key:"C",data:[d,p,...f]}),l=f[0],u=f[1],n=f[2],i=f[3];break}case"T":{let[d,p]=f,m=0,g=0;r==="Q"||r==="T"?(m=n+(n-l),g=i+(i-u)):(m=n,g=i);let y=n+2*(m-n)/3,v=i+2*(g-i)/3,x=d+2*(m-d)/3,b=p+2*(g-p)/3;e.push({key:"C",data:[y,v,x,b,d,p]}),l=m,u=g,n=d,i=p;break}case"Q":{let[d,p,m,g]=f,y=n+2*(d-n)/3,v=i+2*(p-i)/3,x=m+2*(d-m)/3,b=g+2*(p-g)/3;e.push({key:"C",data:[y,v,x,b,m,g]}),l=d,u=p,n=m,i=g;break}case"A":{let d=Math.abs(f[0]),p=Math.abs(f[1]),m=f[2],g=f[3],y=f[4],v=f[5],x=f[6];d===0||p===0?(e.push({key:"C",data:[n,i,v,x,v,x]}),n=v,i=x):(n!==v||i!==x)&&(AK(n,i,v,x,d,p,m,g,y).forEach(function(b){e.push({key:"C",data:b})}),n=v,i=x);break}case"Z":e.push({key:"Z",data:[]}),n=a,i=s}r=h}return e}function g2(t,e,r){return[t*Math.cos(r)-e*Math.sin(r),t*Math.sin(r)+e*Math.cos(r)]}function AK(t,e,r,n,i,a,s,l,u,h){let f=(d=s,Math.PI*d/180);var d;let p=[],m=0,g=0,y=0,v=0;if(h)[m,g,y,v]=h;else{[t,e]=g2(t,e,-f),[r,n]=g2(r,n,-f);let L=(t-r)/2,R=(e-n)/2,O=L*L/(i*i)+R*R/(a*a);O>1&&(O=Math.sqrt(O),i*=O,a*=O);let M=i*i,B=a*a,F=M*B-M*R*R-B*L*L,P=M*R*R+B*L*L,z=(l===u?-1:1)*Math.sqrt(Math.abs(F/P));y=z*i*R/a+(t+r)/2,v=z*-a*L/i+(e+n)/2,m=Math.asin(parseFloat(((e-v)/a).toFixed(9))),g=Math.asin(parseFloat(((n-v)/a).toFixed(9))),t<y&&(m=Math.PI-m),r<y&&(g=Math.PI-g),m<0&&(m=2*Math.PI+m),g<0&&(g=2*Math.PI+g),u&&m>g&&(m-=2*Math.PI),!u&&g>m&&(g-=2*Math.PI)}let x=g-m;if(Math.abs(x)>120*Math.PI/180){let L=g,R=r,O=n;g=u&&g>m?m+120*Math.PI/180*1:m+120*Math.PI/180*-1,p=AK(r=y+i*Math.cos(g),n=v+a*Math.sin(g),R,O,i,a,s,0,u,[g,L,y,v])}x=g-m;let b=Math.cos(m),w=Math.sin(m),C=Math.cos(g),T=Math.sin(g),E=Math.tan(x/4),A=4/3*i*E,S=4/3*a*E,_=[t,e],I=[t+A*w,e-S*b],D=[r+A*T,n-S*C],k=[r,n];if(I[0]=2*_[0]-I[0],I[1]=2*_[1]-I[1],h)return[I,D,k].concat(p);{p=[I,D,k].concat(p);let L=[];for(let R=0;R<p.length;R+=3){let O=g2(p[R][0],p[R][1],f),M=g2(p[R+1][0],p[R+1][1],f),B=g2(p[R+2][0],p[R+2][1],f);L.push([O[0],O[1],M[0],M[1],B[0],B[1]])}return L}}function _K(t,e,r,n,i){return{type:"path",ops:Uh(t,e,r,n,i)}}function Ow(t,e,r){let n=(t||[]).length;if(n>2){let i=[];for(let a=0;a<n-1;a++)i.push(...Uh(t[a][0],t[a][1],t[a+1][0],t[a+1][1],r));return e&&i.push(...Uh(t[n-1][0],t[n-1][1],t[0][0],t[0][1],r)),{type:"path",ops:i}}return n===2?_K(t[0][0],t[0][1],t[1][0],t[1][1],r):{type:"path",ops:[]}}function i_e(t,e,r,n,i){return function(a,s){return Ow(a,!0,s)}([[t,e],[t+r,e],[t+r,e+n],[t,e+n]],i)}function vK(t,e){if(t.length){let r=typeof t[0][0]=="number"?[t]:t,n=Mw(r[0],1*(1+.2*e.roughness),e),i=e.disableMultiStroke?[]:Mw(r[0],1.5*(1+.22*e.roughness),wK(e));for(let a=1;a<r.length;a++){let s=r[a];if(s.length){let l=Mw(s,1*(1+.2*e.roughness),e),u=e.disableMultiStroke?[]:Mw(s,1.5*(1+.22*e.roughness),wK(e));for(let h of l)h.op!=="move"&&n.push(h);for(let h of u)h.op!=="move"&&i.push(h)}}return{type:"path",ops:n.concat(i)}}return{type:"path",ops:[]}}function DK(t,e,r){let n=Math.sqrt(2*Math.PI*Math.sqrt((Math.pow(t/2,2)+Math.pow(e/2,2))/2)),i=Math.ceil(Math.max(r.curveStepCount,r.curveStepCount/Math.sqrt(200)*n)),a=2*Math.PI/i,s=Math.abs(t/2),l=Math.abs(e/2),u=1-r.curveFitting;return s+=nr(s*u,r),l+=nr(l*u,r),{increment:a,rx:s,ry:l}}function HD(t,e,r,n){let[i,a]=TK(n.increment,t,e,n.rx,n.ry,1,n.increment*Bw(.1,Bw(.4,1,r),r),r),s=Fw(i,null,r);if(!r.disableMultiStroke&&r.roughness!==0){let[l]=TK(n.increment,t,e,n.rx,n.ry,1.5,0,r),u=Fw(l,null,r);s=s.concat(u)}return{estimatedPoints:a,opset:{type:"path",ops:s}}}function xK(t,e,r,n,i,a,s,l,u){let h=t,f=e,d=Math.abs(r/2),p=Math.abs(n/2);d+=nr(.01*d,u),p+=nr(.01*p,u);let m=i,g=a;for(;m<0;)m+=2*Math.PI,g+=2*Math.PI;g-m>2*Math.PI&&(m=0,g=2*Math.PI);let y=2*Math.PI/u.curveStepCount,v=Math.min(y/2,(g-m)/2),x=kK(v,h,f,d,p,m,g,1,u);if(!u.disableMultiStroke){let b=kK(v,h,f,d,p,m,g,1.5,u);x.push(...b)}return s&&(l?x.push(...Uh(h,f,h+d*Math.cos(m),f+p*Math.sin(m),u),...Uh(h,f,h+d*Math.cos(g),f+p*Math.sin(g),u)):x.push({op:"lineTo",data:[h,f]},{op:"lineTo",data:[h+d*Math.cos(m),f+p*Math.sin(m)]})),{type:"path",ops:x}}function bK(t,e){let r=CK(SK(jD(t))),n=[],i=[0,0],a=[0,0];for(let{key:s,data:l}of r)switch(s){case"M":a=[l[0],l[1]],i=[l[0],l[1]];break;case"L":n.push(...Uh(a[0],a[1],l[0],l[1],e)),a=[l[0],l[1]];break;case"C":{let[u,h,f,d,p,m]=l;n.push(...a_e(u,h,f,d,p,m,a,e)),a=[p,m];break}case"Z":n.push(...Uh(a[0],a[1],i[0],i[1],e)),a=[i[0],i[1]]}return{type:"path",ops:n}}function PD(t,e){let r=[];for(let n of t)if(n.length){let i=e.maxRandomnessOffset||0,a=n.length;if(a>2){r.push({op:"move",data:[n[0][0]+nr(i,e),n[0][1]+nr(i,e)]});for(let s=1;s<a;s++)r.push({op:"lineTo",data:[n[s][0]+nr(i,e),n[s][1]+nr(i,e)]})}}return{type:"fillPath",ops:r}}function dm(t,e){return function(r,n){let i=r.fillStyle||"hachure";if(!Rs[i])switch(i){case"zigzag":Rs[i]||(Rs[i]=new FD(n));break;case"cross-hatch":Rs[i]||(Rs[i]=new $D(n));break;case"dots":Rs[i]||(Rs[i]=new zD(n));break;case"dashed":Rs[i]||(Rs[i]=new GD(n));break;case"zigzag-line":Rs[i]||(Rs[i]=new VD(n));break;default:i="hachure",Rs[i]||(Rs[i]=new v2(n))}return Rs[i]}(e,n_e).fillPolygons(t,e)}function wK(t){let e=Object.assign({},t);return e.randomizer=void 0,t.seed&&(e.seed=t.seed+1),e}function LK(t){return t.randomizer||(t.randomizer=new UD(t.seed||0)),t.randomizer.next()}function Bw(t,e,r,n=1){return r.roughness*n*(LK(r)*(e-t)+t)}function nr(t,e,r=1){return Bw(-t,t,e,r)}function Uh(t,e,r,n,i,a=!1){let s=a?i.disableMultiStrokeFill:i.disableMultiStroke,l=WD(t,e,r,n,i,!0,!1);if(s)return l;let u=WD(t,e,r,n,i,!0,!0);return l.concat(u)}function WD(t,e,r,n,i,a,s){let l=Math.pow(t-r,2)+Math.pow(e-n,2),u=Math.sqrt(l),h=1;h=u<200?1:u>500?.4:-.0016668*u+1.233334;let f=i.maxRandomnessOffset||0;f*f*100>l&&(f=u/10);let d=f/2,p=.2+.2*LK(i),m=i.bowing*i.maxRandomnessOffset*(n-e)/200,g=i.bowing*i.maxRandomnessOffset*(t-r)/200;m=nr(m,i,h),g=nr(g,i,h);let y=[],v=o(()=>nr(d,i,h),"M"),x=o(()=>nr(f,i,h),"k"),b=i.preserveVertices;return a&&(s?y.push({op:"move",data:[t+(b?0:v()),e+(b?0:v())]}):y.push({op:"move",data:[t+(b?0:nr(f,i,h)),e+(b?0:nr(f,i,h))]})),s?y.push({op:"bcurveTo",data:[m+t+(r-t)*p+v(),g+e+(n-e)*p+v(),m+t+2*(r-t)*p+v(),g+e+2*(n-e)*p+v(),r+(b?0:v()),n+(b?0:v())]}):y.push({op:"bcurveTo",data:[m+t+(r-t)*p+x(),g+e+(n-e)*p+x(),m+t+2*(r-t)*p+x(),g+e+2*(n-e)*p+x(),r+(b?0:x()),n+(b?0:x())]}),y}function Mw(t,e,r){if(!t.length)return[];let n=[];n.push([t[0][0]+nr(e,r),t[0][1]+nr(e,r)]),n.push([t[0][0]+nr(e,r),t[0][1]+nr(e,r)]);for(let i=1;i<t.length;i++)n.push([t[i][0]+nr(e,r),t[i][1]+nr(e,r)]),i===t.length-1&&n.push([t[i][0]+nr(e,r),t[i][1]+nr(e,r)]);return Fw(n,null,r)}function Fw(t,e,r){let n=t.length,i=[];if(n>3){let a=[],s=1-r.curveTightness;i.push({op:"move",data:[t[1][0],t[1][1]]});for(let l=1;l+2<n;l++){let u=t[l];a[0]=[u[0],u[1]],a[1]=[u[0]+(s*t[l+1][0]-s*t[l-1][0])/6,u[1]+(s*t[l+1][1]-s*t[l-1][1])/6],a[2]=[t[l+1][0]+(s*t[l][0]-s*t[l+2][0])/6,t[l+1][1]+(s*t[l][1]-s*t[l+2][1])/6],a[3]=[t[l+1][0],t[l+1][1]],i.push({op:"bcurveTo",data:[a[1][0],a[1][1],a[2][0],a[2][1],a[3][0],a[3][1]]})}if(e&&e.length===2){let l=r.maxRandomnessOffset;i.push({op:"lineTo",data:[e[0]+nr(l,r),e[1]+nr(l,r)]})}}else n===3?(i.push({op:"move",data:[t[1][0],t[1][1]]}),i.push({op:"bcurveTo",data:[t[1][0],t[1][1],t[2][0],t[2][1],t[2][0],t[2][1]]})):n===2&&i.push(...WD(t[0][0],t[0][1],t[1][0],t[1][1],r,!0,!0));return i}function TK(t,e,r,n,i,a,s,l){let u=[],h=[];if(l.roughness===0){t/=4,h.push([e+n*Math.cos(-t),r+i*Math.sin(-t)]);for(let f=0;f<=2*Math.PI;f+=t){let d=[e+n*Math.cos(f),r+i*Math.sin(f)];u.push(d),h.push(d)}h.push([e+n*Math.cos(0),r+i*Math.sin(0)]),h.push([e+n*Math.cos(t),r+i*Math.sin(t)])}else{let f=nr(.5,l)-Math.PI/2;h.push([nr(a,l)+e+.9*n*Math.cos(f-t),nr(a,l)+r+.9*i*Math.sin(f-t)]);let d=2*Math.PI+f-.01;for(let p=f;p<d;p+=t){let m=[nr(a,l)+e+n*Math.cos(p),nr(a,l)+r+i*Math.sin(p)];u.push(m),h.push(m)}h.push([nr(a,l)+e+n*Math.cos(f+2*Math.PI+.5*s),nr(a,l)+r+i*Math.sin(f+2*Math.PI+.5*s)]),h.push([nr(a,l)+e+.98*n*Math.cos(f+s),nr(a,l)+r+.98*i*Math.sin(f+s)]),h.push([nr(a,l)+e+.9*n*Math.cos(f+.5*s),nr(a,l)+r+.9*i*Math.sin(f+.5*s)])}return[h,u]}function kK(t,e,r,n,i,a,s,l,u){let h=a+nr(.1,u),f=[];f.push([nr(l,u)+e+.9*n*Math.cos(h-t),nr(l,u)+r+.9*i*Math.sin(h-t)]);for(let d=h;d<=s;d+=t)f.push([nr(l,u)+e+n*Math.cos(d),nr(l,u)+r+i*Math.sin(d)]);return f.push([e+n*Math.cos(s),r+i*Math.sin(s)]),f.push([e+n*Math.cos(s),r+i*Math.sin(s)]),Fw(f,null,u)}function a_e(t,e,r,n,i,a,s,l){let u=[],h=[l.maxRandomnessOffset||1,(l.maxRandomnessOffset||1)+.3],f=[0,0],d=l.disableMultiStroke?1:2,p=l.preserveVertices;for(let m=0;m<d;m++)m===0?u.push({op:"move",data:[s[0],s[1]]}):u.push({op:"move",data:[s[0]+(p?0:nr(h[0],l)),s[1]+(p?0:nr(h[0],l))]}),f=p?[i,a]:[i+nr(h[m],l),a+nr(h[m],l)],u.push({op:"bcurveTo",data:[t+nr(h[m],l),e+nr(h[m],l),r+nr(h[m],l),n+nr(h[m],l),f[0],f[1]]});return u}function y2(t){return[...t]}function EK(t,e=0){let r=t.length;if(r<3)throw new Error("A curve must have at least three points.");let n=[];if(r===3)n.push(y2(t[0]),y2(t[1]),y2(t[2]),y2(t[2]));else{let i=[];i.push(t[0],t[0]);for(let l=1;l<t.length;l++)i.push(t[l]),l===t.length-1&&i.push(t[l]);let a=[],s=1-e;n.push(y2(i[0]));for(let l=1;l+2<i.length;l++){let u=i[l];a[0]=[u[0],u[1]],a[1]=[u[0]+(s*i[l+1][0]-s*i[l-1][0])/6,u[1]+(s*i[l+1][1]-s*i[l-1][1])/6],a[2]=[i[l+1][0]+(s*i[l][0]-s*i[l+2][0])/6,i[l+1][1]+(s*i[l][1]-s*i[l+2][1])/6],a[3]=[i[l+1][0],i[l+1][1]],n.push(a[1],a[2],a[3])}}return n}function Pw(t,e){return Math.pow(t[0]-e[0],2)+Math.pow(t[1]-e[1],2)}function s_e(t,e,r){let n=Pw(e,r);if(n===0)return Pw(t,e);let i=((t[0]-e[0])*(r[0]-e[0])+(t[1]-e[1])*(r[1]-e[1]))/n;return i=Math.max(0,Math.min(1,i)),Pw(t,Od(e,r,i))}function Od(t,e,r){return[t[0]+(e[0]-t[0])*r,t[1]+(e[1]-t[1])*r]}function qD(t,e,r,n){let i=n||[];if(function(l,u){let h=l[u+0],f=l[u+1],d=l[u+2],p=l[u+3],m=3*f[0]-2*h[0]-p[0];m*=m;let g=3*f[1]-2*h[1]-p[1];g*=g;let y=3*d[0]-2*p[0]-h[0];y*=y;let v=3*d[1]-2*p[1]-h[1];return v*=v,m<y&&(m=y),g<v&&(g=v),m+g}(t,e)<r){let l=t[e+0];i.length?(a=i[i.length-1],s=l,Math.sqrt(Pw(a,s))>1&&i.push(l)):i.push(l),i.push(t[e+3])}else{let u=t[e+0],h=t[e+1],f=t[e+2],d=t[e+3],p=Od(u,h,.5),m=Od(h,f,.5),g=Od(f,d,.5),y=Od(p,m,.5),v=Od(m,g,.5),x=Od(y,v,.5);qD([u,p,y,x],0,r,i),qD([x,v,g,d],0,r,i)}var a,s;return i}function o_e(t,e){return $w(t,0,t.length,e)}function $w(t,e,r,n,i){let a=i||[],s=t[e],l=t[r-1],u=0,h=1;for(let f=e+1;f<r-1;++f){let d=s_e(t[f],s,l);d>u&&(u=d,h=f)}return Math.sqrt(u)>n?($w(t,e,h+1,n,a),$w(t,h,r,n,a)):(a.length||a.push(s),a.push(l)),a}function BD(t,e=.15,r){let n=[],i=(t.length-1)/3;for(let a=0;a<i;a++)qD(t,3*a,e,n);return r&&r>0?$w(n,0,n.length,r):n}var v2,FD,$D,zD,GD,VD,Rs,UD,r_e,ID,yK,Nw,n_e,ro,pm,YD,Iw,XD,Xe,Wt=N(()=>{"use strict";o(MD,"t");o(e_e,"e");o(t_e,"s");o(x2,"n");v2=class{static{o(this,"o")}constructor(e){this.helper=e}fillPolygons(e,r){return this._fillPolygons(e,r)}_fillPolygons(e,r){let n=x2(e,r);return{type:"fillSketch",ops:this.renderLines(n,r)}}renderLines(e,r){let n=[];for(let i of e)n.push(...this.helper.doubleLineOps(i[0][0],i[0][1],i[1][0],i[1][1],r));return n}};o(zw,"a");FD=class extends v2{static{o(this,"h")}fillPolygons(e,r){let n=r.hachureGap;n<0&&(n=4*r.strokeWidth),n=Math.max(n,.1);let i=x2(e,Object.assign({},r,{hachureGap:n})),a=Math.PI/180*r.hachureAngle,s=[],l=.5*n*Math.cos(a),u=.5*n*Math.sin(a);for(let[h,f]of i)zw([h,f])&&s.push([[h[0]-l,h[1]+u],[...f]],[[h[0]+l,h[1]-u],[...f]]);return{type:"fillSketch",ops:this.renderLines(s,r)}}},$D=class extends v2{static{o(this,"r")}fillPolygons(e,r){let n=this._fillPolygons(e,r),i=Object.assign({},r,{hachureAngle:r.hachureAngle+90}),a=this._fillPolygons(e,i);return n.ops=n.ops.concat(a.ops),n}},zD=class{static{o(this,"i")}constructor(e){this.helper=e}fillPolygons(e,r){let n=x2(e,r=Object.assign({},r,{hachureAngle:0}));return this.dotsOnLines(n,r)}dotsOnLines(e,r){let n=[],i=r.hachureGap;i<0&&(i=4*r.strokeWidth),i=Math.max(i,.1);let a=r.fillWeight;a<0&&(a=r.strokeWidth/2);let s=i/4;for(let l of e){let u=zw(l),h=u/i,f=Math.ceil(h)-1,d=u-f*i,p=(l[0][0]+l[1][0])/2-i/4,m=Math.min(l[0][1],l[1][1]);for(let g=0;g<f;g++){let y=m+d+g*i,v=p-s+2*Math.random()*s,x=y-s+2*Math.random()*s,b=this.helper.ellipse(v,x,a,a,r);n.push(...b.ops)}}return{type:"fillSketch",ops:n}}},GD=class{static{o(this,"c")}constructor(e){this.helper=e}fillPolygons(e,r){let n=x2(e,r);return{type:"fillSketch",ops:this.dashedLine(n,r)}}dashedLine(e,r){let n=r.dashOffset<0?r.hachureGap<0?4*r.strokeWidth:r.hachureGap:r.dashOffset,i=r.dashGap<0?r.hachureGap<0?4*r.strokeWidth:r.hachureGap:r.dashGap,a=[];return e.forEach(s=>{let l=zw(s),u=Math.floor(l/(n+i)),h=(l+i-u*(n+i))/2,f=s[0],d=s[1];f[0]>d[0]&&(f=s[1],d=s[0]);let p=Math.atan((d[1]-f[1])/(d[0]-f[0]));for(let m=0;m<u;m++){let g=m*(n+i),y=g+n,v=[f[0]+g*Math.cos(p)+h*Math.cos(p),f[1]+g*Math.sin(p)+h*Math.sin(p)],x=[f[0]+y*Math.cos(p)+h*Math.cos(p),f[1]+y*Math.sin(p)+h*Math.sin(p)];a.push(...this.helper.doubleLineOps(v[0],v[1],x[0],x[1],r))}}),a}},VD=class{static{o(this,"l")}constructor(e){this.helper=e}fillPolygons(e,r){let n=r.hachureGap<0?4*r.strokeWidth:r.hachureGap,i=r.zigzagOffset<0?n:r.zigzagOffset,a=x2(e,r=Object.assign({},r,{hachureGap:n+i}));return{type:"fillSketch",ops:this.zigzagLines(a,i,r)}}zigzagLines(e,r,n){let i=[];return e.forEach(a=>{let s=zw(a),l=Math.round(s/(2*r)),u=a[0],h=a[1];u[0]>h[0]&&(u=a[1],h=a[0]);let f=Math.atan((h[1]-u[1])/(h[0]-u[0]));for(let d=0;d<l;d++){let p=2*d*r,m=2*(d+1)*r,g=Math.sqrt(2*Math.pow(r,2)),y=[u[0]+p*Math.cos(f),u[1]+p*Math.sin(f)],v=[u[0]+m*Math.cos(f),u[1]+m*Math.sin(f)],x=[y[0]+g*Math.cos(f+Math.PI/4),y[1]+g*Math.sin(f+Math.PI/4)];i.push(...this.helper.doubleLineOps(y[0],y[1],x[0],x[1],n),...this.helper.doubleLineOps(x[0],x[1],v[0],v[1],n))}}),i}},Rs={},UD=class{static{o(this,"p")}constructor(e){this.seed=e}next(){return this.seed?(2**31-1&(this.seed=Math.imul(48271,this.seed)))/2**31:Math.random()}},r_e=0,ID=1,yK=2,Nw={A:7,a:7,C:6,c:6,H:1,h:1,L:2,l:2,M:2,m:2,Q:4,q:4,S:4,s:4,T:2,t:2,V:1,v:1,Z:0,z:0};o(OD,"k");o(jD,"b");o(SK,"y");o(CK,"m");o(g2,"w");o(AK,"x");n_e={randOffset:o(function(t,e){return nr(t,e)},"randOffset"),randOffsetWithRange:o(function(t,e,r){return Bw(t,e,r)},"randOffsetWithRange"),ellipse:o(function(t,e,r,n,i){let a=DK(r,n,i);return HD(t,e,i,a).opset},"ellipse"),doubleLineOps:o(function(t,e,r,n,i){return Uh(t,e,r,n,i,!0)},"doubleLineOps")};o(_K,"v");o(Ow,"S");o(i_e,"O");o(vK,"L");o(DK,"T");o(HD,"D");o(xK,"A");o(bK,"_");o(PD,"I");o(dm,"C");o(wK,"z");o(LK,"W");o(Bw,"E");o(nr,"G");o(Uh,"$");o(WD,"R");o(Mw,"j");o(Fw,"q");o(TK,"F");o(kK,"V");o(a_e,"Z");o(y2,"Q");o(EK,"H");o(Pw,"N");o(s_e,"B");o(Od,"J");o(qD,"K");o(o_e,"U");o($w,"X");o(BD,"Y");ro="none",pm=class{static{o(this,"et")}constructor(e){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:"#000",strokeWidth:1,curveTightness:0,curveFitting:.95,curveStepCount:9,fillStyle:"hachure",fillWeight:-1,hachureAngle:-41,hachureGap:-1,dashOffset:-1,dashGap:-1,zigzagOffset:-1,seed:0,disableMultiStroke:!1,disableMultiStrokeFill:!1,preserveVertices:!1,fillShapeRoughnessGain:.8},this.config=e||{},this.config.options&&(this.defaultOptions=this._o(this.config.options))}static newSeed(){return Math.floor(Math.random()*2**31)}_o(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}_d(e,r,n){return{shape:e,sets:r||[],options:n||this.defaultOptions}}line(e,r,n,i,a){let s=this._o(a);return this._d("line",[_K(e,r,n,i,s)],s)}rectangle(e,r,n,i,a){let s=this._o(a),l=[],u=i_e(e,r,n,i,s);if(s.fill){let h=[[e,r],[e+n,r],[e+n,r+i],[e,r+i]];s.fillStyle==="solid"?l.push(PD([h],s)):l.push(dm([h],s))}return s.stroke!==ro&&l.push(u),this._d("rectangle",l,s)}ellipse(e,r,n,i,a){let s=this._o(a),l=[],u=DK(n,i,s),h=HD(e,r,s,u);if(s.fill)if(s.fillStyle==="solid"){let f=HD(e,r,s,u).opset;f.type="fillPath",l.push(f)}else l.push(dm([h.estimatedPoints],s));return s.stroke!==ro&&l.push(h.opset),this._d("ellipse",l,s)}circle(e,r,n,i){let a=this.ellipse(e,r,n,n,i);return a.shape="circle",a}linearPath(e,r){let n=this._o(r);return this._d("linearPath",[Ow(e,!1,n)],n)}arc(e,r,n,i,a,s,l=!1,u){let h=this._o(u),f=[],d=xK(e,r,n,i,a,s,l,!0,h);if(l&&h.fill)if(h.fillStyle==="solid"){let p=Object.assign({},h);p.disableMultiStroke=!0;let m=xK(e,r,n,i,a,s,!0,!1,p);m.type="fillPath",f.push(m)}else f.push(function(p,m,g,y,v,x,b){let w=p,C=m,T=Math.abs(g/2),E=Math.abs(y/2);T+=nr(.01*T,b),E+=nr(.01*E,b);let A=v,S=x;for(;A<0;)A+=2*Math.PI,S+=2*Math.PI;S-A>2*Math.PI&&(A=0,S=2*Math.PI);let _=(S-A)/b.curveStepCount,I=[];for(let D=A;D<=S;D+=_)I.push([w+T*Math.cos(D),C+E*Math.sin(D)]);return I.push([w+T*Math.cos(S),C+E*Math.sin(S)]),I.push([w,C]),dm([I],b)}(e,r,n,i,a,s,h));return h.stroke!==ro&&f.push(d),this._d("arc",f,h)}curve(e,r){let n=this._o(r),i=[],a=vK(e,n);if(n.fill&&n.fill!==ro)if(n.fillStyle==="solid"){let s=vK(e,Object.assign(Object.assign({},n),{disableMultiStroke:!0,roughness:n.roughness?n.roughness+n.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(s.ops)})}else{let s=[],l=e;if(l.length){let u=typeof l[0][0]=="number"?[l]:l;for(let h of u)h.length<3?s.push(...h):h.length===3?s.push(...BD(EK([h[0],h[0],h[1],h[2]]),10,(1+n.roughness)/2)):s.push(...BD(EK(h),10,(1+n.roughness)/2))}s.length&&i.push(dm([s],n))}return n.stroke!==ro&&i.push(a),this._d("curve",i,n)}polygon(e,r){let n=this._o(r),i=[],a=Ow(e,!0,n);return n.fill&&(n.fillStyle==="solid"?i.push(PD([e],n)):i.push(dm([e],n))),n.stroke!==ro&&i.push(a),this._d("polygon",i,n)}path(e,r){let n=this._o(r),i=[];if(!e)return this._d("path",i,n);e=(e||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");let a=n.fill&&n.fill!=="transparent"&&n.fill!==ro,s=n.stroke!==ro,l=!!(n.simplification&&n.simplification<1),u=function(f,d,p){let m=CK(SK(jD(f))),g=[],y=[],v=[0,0],x=[],b=o(()=>{x.length>=4&&y.push(...BD(x,d)),x=[]},"i"),w=o(()=>{b(),y.length&&(g.push(y),y=[])},"c");for(let{key:T,data:E}of m)switch(T){case"M":w(),v=[E[0],E[1]],y.push(v);break;case"L":b(),y.push([E[0],E[1]]);break;case"C":if(!x.length){let A=y.length?y[y.length-1]:v;x.push([A[0],A[1]])}x.push([E[0],E[1]]),x.push([E[2],E[3]]),x.push([E[4],E[5]]);break;case"Z":b(),y.push([v[0],v[1]])}if(w(),!p)return g;let C=[];for(let T of g){let E=o_e(T,p);E.length&&C.push(E)}return C}(e,1,l?4-4*(n.simplification||1):(1+n.roughness)/2),h=bK(e,n);if(a)if(n.fillStyle==="solid")if(u.length===1){let f=bK(e,Object.assign(Object.assign({},n),{disableMultiStroke:!0,roughness:n.roughness?n.roughness+n.fillShapeRoughnessGain:0}));i.push({type:"fillPath",ops:this._mergedShape(f.ops)})}else i.push(PD(u,n));else i.push(dm(u,n));return s&&(l?u.forEach(f=>{i.push(Ow(f,!1,n))}):i.push(h)),this._d("path",i,n)}opsToPath(e,r){let n="";for(let i of e.ops){let a=typeof r=="number"&&r>=0?i.data.map(s=>+s.toFixed(r)):i.data;switch(i.op){case"move":n+=`M${a[0]} ${a[1]} `;break;case"bcurveTo":n+=`C${a[0]} ${a[1]}, ${a[2]} ${a[3]}, ${a[4]} ${a[5]} `;break;case"lineTo":n+=`L${a[0]} ${a[1]} `}}return n.trim()}toPaths(e){let r=e.sets||[],n=e.options||this.defaultOptions,i=[];for(let a of r){let s=null;switch(a.type){case"path":s={d:this.opsToPath(a),stroke:n.stroke,strokeWidth:n.strokeWidth,fill:ro};break;case"fillPath":s={d:this.opsToPath(a),stroke:ro,strokeWidth:0,fill:n.fill||ro};break;case"fillSketch":s=this.fillSketch(a,n)}s&&i.push(s)}return i}fillSketch(e,r){let n=r.fillWeight;return n<0&&(n=r.strokeWidth/2),{d:this.opsToPath(e),stroke:r.fill||ro,strokeWidth:n,fill:ro}}_mergedShape(e){return e.filter((r,n)=>n===0||r.op!=="move")}},YD=class{static{o(this,"st")}constructor(e,r){this.canvas=e,this.ctx=this.canvas.getContext("2d"),this.gen=new pm(r)}draw(e){let r=e.sets||[],n=e.options||this.getDefaultOptions(),i=this.ctx,a=e.options.fixedDecimalPlaceDigits;for(let s of r)switch(s.type){case"path":i.save(),i.strokeStyle=n.stroke==="none"?"transparent":n.stroke,i.lineWidth=n.strokeWidth,n.strokeLineDash&&i.setLineDash(n.strokeLineDash),n.strokeLineDashOffset&&(i.lineDashOffset=n.strokeLineDashOffset),this._drawToContext(i,s,a),i.restore();break;case"fillPath":{i.save(),i.fillStyle=n.fill||"";let l=e.shape==="curve"||e.shape==="polygon"||e.shape==="path"?"evenodd":"nonzero";this._drawToContext(i,s,a,l),i.restore();break}case"fillSketch":this.fillSketch(i,s,n)}}fillSketch(e,r,n){let i=n.fillWeight;i<0&&(i=n.strokeWidth/2),e.save(),n.fillLineDash&&e.setLineDash(n.fillLineDash),n.fillLineDashOffset&&(e.lineDashOffset=n.fillLineDashOffset),e.strokeStyle=n.fill||"",e.lineWidth=i,this._drawToContext(e,r,n.fixedDecimalPlaceDigits),e.restore()}_drawToContext(e,r,n,i="nonzero"){e.beginPath();for(let a of r.ops){let s=typeof n=="number"&&n>=0?a.data.map(l=>+l.toFixed(n)):a.data;switch(a.op){case"move":e.moveTo(s[0],s[1]);break;case"bcurveTo":e.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5]);break;case"lineTo":e.lineTo(s[0],s[1])}}r.type==="fillPath"?e.fill(i):e.stroke()}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(e,r,n,i,a){let s=this.gen.line(e,r,n,i,a);return this.draw(s),s}rectangle(e,r,n,i,a){let s=this.gen.rectangle(e,r,n,i,a);return this.draw(s),s}ellipse(e,r,n,i,a){let s=this.gen.ellipse(e,r,n,i,a);return this.draw(s),s}circle(e,r,n,i){let a=this.gen.circle(e,r,n,i);return this.draw(a),a}linearPath(e,r){let n=this.gen.linearPath(e,r);return this.draw(n),n}polygon(e,r){let n=this.gen.polygon(e,r);return this.draw(n),n}arc(e,r,n,i,a,s,l=!1,u){let h=this.gen.arc(e,r,n,i,a,s,l,u);return this.draw(h),h}curve(e,r){let n=this.gen.curve(e,r);return this.draw(n),n}path(e,r){let n=this.gen.path(e,r);return this.draw(n),n}},Iw="http://www.w3.org/2000/svg",XD=class{static{o(this,"ot")}constructor(e,r){this.svg=e,this.gen=new pm(r)}draw(e){let r=e.sets||[],n=e.options||this.getDefaultOptions(),i=this.svg.ownerDocument||window.document,a=i.createElementNS(Iw,"g"),s=e.options.fixedDecimalPlaceDigits;for(let l of r){let u=null;switch(l.type){case"path":u=i.createElementNS(Iw,"path"),u.setAttribute("d",this.opsToPath(l,s)),u.setAttribute("stroke",n.stroke),u.setAttribute("stroke-width",n.strokeWidth+""),u.setAttribute("fill","none"),n.strokeLineDash&&u.setAttribute("stroke-dasharray",n.strokeLineDash.join(" ").trim()),n.strokeLineDashOffset&&u.setAttribute("stroke-dashoffset",`${n.strokeLineDashOffset}`);break;case"fillPath":u=i.createElementNS(Iw,"path"),u.setAttribute("d",this.opsToPath(l,s)),u.setAttribute("stroke","none"),u.setAttribute("stroke-width","0"),u.setAttribute("fill",n.fill||""),e.shape!=="curve"&&e.shape!=="polygon"||u.setAttribute("fill-rule","evenodd");break;case"fillSketch":u=this.fillSketch(i,l,n)}u&&a.appendChild(u)}return a}fillSketch(e,r,n){let i=n.fillWeight;i<0&&(i=n.strokeWidth/2);let a=e.createElementNS(Iw,"path");return a.setAttribute("d",this.opsToPath(r,n.fixedDecimalPlaceDigits)),a.setAttribute("stroke",n.fill||""),a.setAttribute("stroke-width",i+""),a.setAttribute("fill","none"),n.fillLineDash&&a.setAttribute("stroke-dasharray",n.fillLineDash.join(" ").trim()),n.fillLineDashOffset&&a.setAttribute("stroke-dashoffset",`${n.fillLineDashOffset}`),a}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(e,r){return this.gen.opsToPath(e,r)}line(e,r,n,i,a){let s=this.gen.line(e,r,n,i,a);return this.draw(s)}rectangle(e,r,n,i,a){let s=this.gen.rectangle(e,r,n,i,a);return this.draw(s)}ellipse(e,r,n,i,a){let s=this.gen.ellipse(e,r,n,i,a);return this.draw(s)}circle(e,r,n,i){let a=this.gen.circle(e,r,n,i);return this.draw(a)}linearPath(e,r){let n=this.gen.linearPath(e,r);return this.draw(n)}polygon(e,r){let n=this.gen.polygon(e,r);return this.draw(n)}arc(e,r,n,i,a,s,l=!1,u){let h=this.gen.arc(e,r,n,i,a,s,l,u);return this.draw(h)}curve(e,r){let n=this.gen.curve(e,r);return this.draw(n)}path(e,r){let n=this.gen.path(e,r);return this.draw(n)}},Xe={canvas:o((t,e)=>new YD(t,e),"canvas"),svg:o((t,e)=>new XD(t,e),"svg"),generator:o(t=>new pm(t),"generator"),newSeed:o(()=>pm.newSeed(),"newSeed")}});function RK(t,e){let{labelStyles:r}=Qe(e);e.labelStyle=r;let n=ht(e),i=n;n||(i="anchor");let a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),s=1,{cssStyles:l}=e,u=Xe.svg(a),h=Ke(e,{fill:"black",stroke:"none",fillStyle:"solid"});e.look!=="handDrawn"&&(h.roughness=0);let f=u.circle(0,0,s*2,h),d=a.insert(()=>f,":first-child");return d.attr("class","anchor").attr("style",$n(l)),je(e,d),e.intersect=function(p){return Y.info("Circle intersect",e,s,p),Ye.circle(e,s,p)},a}var NK=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();ir();o(RK,"anchor")});function MK(t,e,r,n,i,a,s){let u=(t+r)/2,h=(e+n)/2,f=Math.atan2(n-e,r-t),d=(r-t)/2,p=(n-e)/2,m=d/i,g=p/a,y=Math.sqrt(m**2+g**2);if(y>1)throw new Error("The given radii are too small to create an arc between the points.");let v=Math.sqrt(1-y**2),x=u+v*a*Math.sin(f)*(s?-1:1),b=h-v*i*Math.cos(f)*(s?-1:1),w=Math.atan2((e-b)/a,(t-x)/i),T=Math.atan2((n-b)/a,(r-x)/i)-w;s&&T<0&&(T+=2*Math.PI),!s&&T>0&&(T-=2*Math.PI);let E=[];for(let A=0;A<20;A++){let S=A/19,_=w+S*T,I=x+i*Math.cos(_),D=b+a*Math.sin(_);E.push({x:I,y:D})}return E}async function IK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=a.width+e.padding+20,l=a.height+e.padding,u=l/2,h=u/(2.5+l/50),{cssStyles:f}=e,d=[{x:s/2,y:-l/2},{x:-s/2,y:-l/2},...MK(-s/2,-l/2,-s/2,l/2,h,u,!1),{x:s/2,y:l/2},...MK(s/2,l/2,s/2,-l/2,h,u,!0)],p=Xe.svg(i),m=Ke(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=Xt(d),y=p.path(g,m),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),f&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(${h/2}, 0)`),je(e,v),e.intersect=function(x){return Ye.polygon(e,d,x)},i}var OK=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(MK,"generateArcPoints");o(IK,"bowTieRect")});function La(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map(function(i){return i.x+","+i.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}var _u=N(()=>{"use strict";o(La,"insertPolygonShape")});async function PK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=a.height+e.padding,l=12,u=a.width+e.padding+l,h=0,f=u,d=-s,p=0,m=[{x:h+l,y:d},{x:f,y:d},{x:f,y:p},{x:h,y:p},{x:h,y:d+l},{x:h+l,y:d}],g,{cssStyles:y}=e;if(e.look==="handDrawn"){let v=Xe.svg(i),x=Ke(e,{}),b=Xt(m),w=v.path(b,x);g=i.insert(()=>w,":first-child").attr("transform",`translate(${-u/2}, ${s/2})`),y&&g.attr("style",y)}else g=La(i,u,s,m);return n&&g.attr("style",n),je(e,g),e.intersect=function(v){return Ye.polygon(e,m,v)},i}var BK=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();Ft();o(PK,"card")});function FK(t,e){let{nodeStyles:r}=Qe(e);e.label="";let n=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:i}=e,a=Math.max(28,e.width??0),s=[{x:0,y:a/2},{x:a/2,y:0},{x:0,y:-a/2},{x:-a/2,y:0}],l=Xe.svg(n),u=Ke(e,{});e.look!=="handDrawn"&&(u.roughness=0,u.fillStyle="solid");let h=Xt(s),f=l.path(h,u),d=n.insert(()=>f,":first-child");return i&&e.look!=="handDrawn"&&d.selectAll("path").attr("style",i),r&&e.look!=="handDrawn"&&d.selectAll("path").attr("style",r),e.width=28,e.height=28,e.intersect=function(p){return Ye.polygon(e,s,p)},n}var $K=N(()=>{"use strict";Ht();Wt();Ut();Ft();o(FK,"choice")});async function zK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,halfPadding:s}=await pt(t,e,ht(e)),l=a.width/2+s,u,{cssStyles:h}=e;if(e.look==="handDrawn"){let f=Xe.svg(i),d=Ke(e,{}),p=f.circle(0,0,l*2,d);u=i.insert(()=>p,":first-child"),u.attr("class","basic label-container").attr("style",$n(h))}else u=i.insert("circle",":first-child").attr("class","basic label-container").attr("style",n).attr("r",l).attr("cx",0).attr("cy",0);return je(e,u),e.intersect=function(f){return Y.info("Circle intersect",e,l,f),Ye.circle(e,l,f)},i}var GK=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();ir();o(zK,"circle")});function l_e(t){let e=Math.cos(Math.PI/4),r=Math.sin(Math.PI/4),n=t*2,i={x:n/2*e,y:n/2*r},a={x:-(n/2)*e,y:n/2*r},s={x:-(n/2)*e,y:-(n/2)*r},l={x:n/2*e,y:-(n/2)*r};return`M ${a.x},${a.y} L ${l.x},${l.y}
+ M ${i.x},${i.y} L ${s.x},${s.y}`}function VK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r,e.label="";let i=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),a=Math.max(30,e?.width??0),{cssStyles:s}=e,l=Xe.svg(i),u=Ke(e,{});e.look!=="handDrawn"&&(u.roughness=0,u.fillStyle="solid");let h=l.circle(0,0,a*2,u),f=l_e(a),d=l.path(f,u),p=i.insert(()=>h,":first-child");return p.insert(()=>d),s&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",s),n&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",n),je(e,p),e.intersect=function(m){return Y.info("crossedCircle intersect",e,{radius:a,point:m}),Ye.circle(e,a,m)},i}var UK=N(()=>{"use strict";vt();Ft();Ut();Wt();Ht();o(l_e,"createLine");o(VK,"crossedCircle")});function Hh(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d<n;d++){let p=l+d*f,m=t+r*Math.cos(p),g=e+r*Math.sin(p);s.push({x:-m,y:-g})}return s}async function HK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=a.width+(e.padding??0),u=a.height+(e.padding??0),h=Math.max(5,u*.1),{cssStyles:f}=e,d=[...Hh(l/2,-u/2,h,30,-90,0),{x:-l/2-h,y:h},...Hh(l/2+h*2,-h,h,20,-180,-270),...Hh(l/2+h*2,h,h,20,-90,-180),{x:-l/2-h,y:-u/2},...Hh(l/2,u/2,h,20,0,90)],p=[{x:l/2,y:-u/2-h},{x:-l/2,y:-u/2-h},...Hh(l/2,-u/2,h,20,-90,0),{x:-l/2-h,y:-h},...Hh(l/2+l*.1,-h,h,20,-180,-270),...Hh(l/2+l*.1,h,h,20,-90,-180),{x:-l/2-h,y:u/2},...Hh(l/2,u/2,h,20,0,90),{x:-l/2,y:u/2+h},{x:l/2,y:u/2+h}],m=Xe.svg(i),g=Ke(e,{fill:"none"});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let v=Xt(d).replace("Z",""),x=m.path(v,g),b=Xt(p),w=m.path(b,{...g}),C=i.insert("g",":first-child");return C.insert(()=>w,":first-child").attr("stroke-opacity",0),C.insert(()=>x,":first-child"),C.attr("class","text"),f&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(${h}, 0)`),s.attr("transform",`translate(${-l/2+h-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),je(e,C),e.intersect=function(T){return Ye.polygon(e,p,T)},i}var WK=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(Hh,"generateCirclePoints");o(HK,"curlyBraceLeft")});function Wh(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d<n;d++){let p=l+d*f,m=t+r*Math.cos(p),g=e+r*Math.sin(p);s.push({x:m,y:g})}return s}async function qK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=a.width+(e.padding??0),u=a.height+(e.padding??0),h=Math.max(5,u*.1),{cssStyles:f}=e,d=[...Wh(l/2,-u/2,h,20,-90,0),{x:l/2+h,y:-h},...Wh(l/2+h*2,-h,h,20,-180,-270),...Wh(l/2+h*2,h,h,20,-90,-180),{x:l/2+h,y:u/2},...Wh(l/2,u/2,h,20,0,90)],p=[{x:-l/2,y:-u/2-h},{x:l/2,y:-u/2-h},...Wh(l/2,-u/2,h,20,-90,0),{x:l/2+h,y:-h},...Wh(l/2+h*2,-h,h,20,-180,-270),...Wh(l/2+h*2,h,h,20,-90,-180),{x:l/2+h,y:u/2},...Wh(l/2,u/2,h,20,0,90),{x:l/2,y:u/2+h},{x:-l/2,y:u/2+h}],m=Xe.svg(i),g=Ke(e,{fill:"none"});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let v=Xt(d).replace("Z",""),x=m.path(v,g),b=Xt(p),w=m.path(b,{...g}),C=i.insert("g",":first-child");return C.insert(()=>w,":first-child").attr("stroke-opacity",0),C.insert(()=>x,":first-child"),C.attr("class","text"),f&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(${-h}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),je(e,C),e.intersect=function(T){return Ye.polygon(e,p,T)},i}var YK=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(Wh,"generateCirclePoints");o(qK,"curlyBraceRight")});function Ra(t,e,r,n=100,i=0,a=180){let s=[],l=i*Math.PI/180,f=(a*Math.PI/180-l)/(n-1);for(let d=0;d<n;d++){let p=l+d*f,m=t+r*Math.cos(p),g=e+r*Math.sin(p);s.push({x:-m,y:-g})}return s}async function XK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=a.width+(e.padding??0),u=a.height+(e.padding??0),h=Math.max(5,u*.1),{cssStyles:f}=e,d=[...Ra(l/2,-u/2,h,30,-90,0),{x:-l/2-h,y:h},...Ra(l/2+h*2,-h,h,20,-180,-270),...Ra(l/2+h*2,h,h,20,-90,-180),{x:-l/2-h,y:-u/2},...Ra(l/2,u/2,h,20,0,90)],p=[...Ra(-l/2+h+h/2,-u/2,h,20,-90,-180),{x:l/2-h/2,y:h},...Ra(-l/2-h/2,-h,h,20,0,90),...Ra(-l/2-h/2,h,h,20,-90,0),{x:l/2-h/2,y:-h},...Ra(-l/2+h+h/2,u/2,h,30,-180,-270)],m=[{x:l/2,y:-u/2-h},{x:-l/2,y:-u/2-h},...Ra(l/2,-u/2,h,20,-90,0),{x:-l/2-h,y:-h},...Ra(l/2+h*2,-h,h,20,-180,-270),...Ra(l/2+h*2,h,h,20,-90,-180),{x:-l/2-h,y:u/2},...Ra(l/2,u/2,h,20,0,90),{x:-l/2,y:u/2+h},{x:l/2-h-h/2,y:u/2+h},...Ra(-l/2+h+h/2,-u/2,h,20,-90,-180),{x:l/2-h/2,y:h},...Ra(-l/2-h/2,-h,h,20,0,90),...Ra(-l/2-h/2,h,h,20,-90,0),{x:l/2-h/2,y:-h},...Ra(-l/2+h+h/2,u/2,h,30,-180,-270)],g=Xe.svg(i),y=Ke(e,{fill:"none"});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let x=Xt(d).replace("Z",""),b=g.path(x,y),C=Xt(p).replace("Z",""),T=g.path(C,y),E=Xt(m),A=g.path(E,{...y}),S=i.insert("g",":first-child");return S.insert(()=>A,":first-child").attr("stroke-opacity",0),S.insert(()=>b,":first-child"),S.insert(()=>T,":first-child"),S.attr("class","text"),f&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",f),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(${h-h/4}, 0)`),s.attr("transform",`translate(${-l/2+(e.padding??0)/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)/2-(a.y-(a.top??0))})`),je(e,S),e.intersect=function(_){return Ye.polygon(e,m,_)},i}var jK=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(Ra,"generateCirclePoints");o(XK,"curlyBraces")});async function KK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=80,l=20,u=Math.max(s,(a.width+(e.padding??0)*2)*1.25,e?.width??0),h=Math.max(l,a.height+(e.padding??0)*2,e?.height??0),f=h/2,{cssStyles:d}=e,p=Xe.svg(i),m=Ke(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=u,y=h,v=g-f,x=y/4,b=[{x:v,y:0},{x,y:0},{x:0,y:y/2},{x,y},{x:v,y},...Lw(-v,-y/2,f,50,270,90)],w=Xt(b),C=p.path(w,m),T=i.insert(()=>C,":first-child");return T.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&T.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&T.selectChildren("path").attr("style",n),T.attr("transform",`translate(${-u/2}, ${-h/2})`),je(e,T),e.intersect=function(E){return Ye.polygon(e,b,E)},i}var QK=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(KK,"curvedTrapezoid")});async function ZK(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+e.padding,e.width??0),u=l/2,h=u/(2.5+l/50),f=Math.max(a.height+h+e.padding,e.height??0),d,{cssStyles:p}=e;if(e.look==="handDrawn"){let m=Xe.svg(i),g=u_e(0,0,l,f,u,h),y=h_e(0,h,l,f,u,h),v=m.path(g,Ke(e,{})),x=m.path(y,Ke(e,{fill:"none"}));d=i.insert(()=>x,":first-child"),d=i.insert(()=>v,":first-child"),d.attr("class","basic label-container"),p&&d.attr("style",p)}else{let m=c_e(0,0,l,f,u,h);d=i.insert("path",":first-child").attr("d",m).attr("class","basic label-container").attr("style",$n(p)).attr("style",n)}return d.attr("label-offset-y",h),d.attr("transform",`translate(${-l/2}, ${-(f/2+h)})`),je(e,d),s.attr("transform",`translate(${-(a.width/2)-(a.x-(a.left??0))}, ${-(a.height/2)+(e.padding??0)/1.5-(a.y-(a.top??0))})`),e.intersect=function(m){let g=Ye.rect(e,m),y=g.x-(e.x??0);if(u!=0&&(Math.abs(y)<(e.width??0)/2||Math.abs(y)==(e.width??0)/2&&Math.abs(g.y-(e.y??0))>(e.height??0)/2-h)){let v=h*h*(1-y*y/(u*u));v>0&&(v=Math.sqrt(v)),v=h-v,m.y-(e.y??0)>0&&(v=-v),g.y+=v}return g},i}var c_e,u_e,h_e,JK=N(()=>{"use strict";Ft();Ht();Ut();Wt();ir();c_e=o((t,e,r,n,i,a)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`].join(" "),"createCylinderPathD"),u_e=o((t,e,r,n,i,a)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`].join(" "),"createOuterCylinderPathD"),h_e=o((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");o(ZK,"cylinder")});async function eQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=a.width+e.padding,u=a.height+e.padding,h=u*.2,f=-l/2,d=-u/2-h/2,{cssStyles:p}=e,m=Xe.svg(i),g=Ke(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=[{x:f,y:d+h},{x:-f,y:d+h},{x:-f,y:-d},{x:f,y:-d},{x:f,y:d},{x:-f,y:d},{x:-f,y:d+h}],v=m.polygon(y.map(b=>[b.x,b.y]),g),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),s.attr("transform",`translate(${f+(e.padding??0)/2-(a.x-(a.left??0))}, ${d+h+(e.padding??0)/2-(a.y-(a.top??0))})`),je(e,x),e.intersect=function(b){return Ye.rect(e,b)},i}var tQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(eQ,"dividedRectangle")});async function rQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,halfPadding:s}=await pt(t,e,ht(e)),u=a.width/2+s+5,h=a.width/2+s,f,{cssStyles:d}=e;if(e.look==="handDrawn"){let p=Xe.svg(i),m=Ke(e,{roughness:.2,strokeWidth:2.5}),g=Ke(e,{roughness:.2,strokeWidth:1.5}),y=p.circle(0,0,u*2,m),v=p.circle(0,0,h*2,g);f=i.insert("g",":first-child"),f.attr("class",$n(e.cssClasses)).attr("style",$n(d)),f.node()?.appendChild(y),f.node()?.appendChild(v)}else{f=i.insert("g",":first-child");let p=f.insert("circle",":first-child"),m=f.insert("circle");f.attr("class","basic label-container").attr("style",n),p.attr("class","outer-circle").attr("style",n).attr("r",u).attr("cx",0).attr("cy",0),m.attr("class","inner-circle").attr("style",n).attr("r",h).attr("cx",0).attr("cy",0)}return je(e,f),e.intersect=function(p){return Y.info("DoubleCircle intersect",e,u,p),Ye.circle(e,u,p)},i}var nQ=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();ir();o(rQ,"doublecircle")});function iQ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Qe(e);e.label="",e.labelStyle=n;let a=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),s=7,{cssStyles:l}=e,u=Xe.svg(a),{nodeBorder:h}=r,f=Ke(e,{fillStyle:"solid"});e.look!=="handDrawn"&&(f.roughness=0);let d=u.circle(0,0,s*2,f),p=a.insert(()=>d,":first-child");return p.selectAll("path").attr("style",`fill: ${h} !important;`),l&&l.length>0&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",l),i&&e.look!=="handDrawn"&&p.selectAll("path").attr("style",i),je(e,p),e.intersect=function(m){return Y.info("filledCircle intersect",e,{radius:s,point:m}),Ye.circle(e,s,m)},a}var aQ=N(()=>{"use strict";Wt();vt();Ht();Ut();Ft();o(iQ,"filledCircle")});async function sQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=a.width+(e.padding??0),u=l+a.height,h=l+a.height,f=[{x:0,y:-u},{x:h,y:-u},{x:h/2,y:0}],{cssStyles:d}=e,p=Xe.svg(i),m=Ke(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=Xt(f),y=p.path(g,m),v=i.insert(()=>y,":first-child").attr("transform",`translate(${-u/2}, ${u/2})`);return d&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",n),e.width=l,e.height=u,je(e,v),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${-u/2+(e.padding??0)/2+(a.y-(a.top??0))})`),e.intersect=function(x){return Y.info("Triangle intersect",e,f,x),Ye.polygon(e,f,x)},i}var oQ=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();Ft();o(sQ,"flippedTriangle")});function lQ(t,e,{dir:r,config:{state:n,themeVariables:i}}){let{nodeStyles:a}=Qe(e);e.label="";let s=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:l}=e,u=Math.max(70,e?.width??0),h=Math.max(10,e?.height??0);r==="LR"&&(u=Math.max(10,e?.width??0),h=Math.max(70,e?.height??0));let f=-1*u/2,d=-1*h/2,p=Xe.svg(s),m=Ke(e,{stroke:i.lineColor,fill:i.lineColor});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=p.rectangle(f,d,u,h,m),y=s.insert(()=>g,":first-child");l&&e.look!=="handDrawn"&&y.selectAll("path").attr("style",l),a&&e.look!=="handDrawn"&&y.selectAll("path").attr("style",a),je(e,y);let v=n?.padding??0;return e.width&&e.height&&(e.width+=v/2||0,e.height+=v/2||0),e.intersect=function(x){return Ye.rect(e,x)},s}var cQ=N(()=>{"use strict";Wt();Ht();Ut();Ft();o(lQ,"forkJoin")});async function uQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let i=80,a=50,{shapeSvg:s,bbox:l}=await pt(t,e,ht(e)),u=Math.max(i,l.width+(e.padding??0)*2,e?.width??0),h=Math.max(a,l.height+(e.padding??0)*2,e?.height??0),f=h/2,{cssStyles:d}=e,p=Xe.svg(s),m=Ke(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:-u/2,y:-h/2},{x:u/2-f,y:-h/2},...Lw(-u/2+f,0,f,50,90,270),{x:u/2-f,y:h/2},{x:-u/2,y:h/2}],y=Xt(g),v=p.path(y,m),x=s.insert(()=>v,":first-child");return x.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),je(e,x),e.intersect=function(b){return Y.info("Pill intersect",e,{radius:f,point:b}),Ye.polygon(e,g,b)},s}var hQ=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();o(uQ,"halfRoundedRectangle")});async function fQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=4,l=a.height+e.padding,u=l/s,h=a.width+2*u+e.padding,f=[{x:u,y:0},{x:h-u,y:0},{x:h,y:-l/2},{x:h-u,y:-l},{x:u,y:-l},{x:0,y:-l/2}],d,{cssStyles:p}=e;if(e.look==="handDrawn"){let m=Xe.svg(i),g=Ke(e,{}),y=f_e(0,0,h,l,u),v=m.path(y,g);d=i.insert(()=>v,":first-child").attr("transform",`translate(${-h/2}, ${l/2})`),p&&d.attr("style",p)}else d=La(i,h,l,f);return n&&d.attr("style",n),e.width=h,e.height=l,je(e,d),e.intersect=function(m){return Ye.polygon(e,f,m)},i}var f_e,dQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();f_e=o((t,e,r,n,i)=>[`M${t+i},${e}`,`L${t+r-i},${e}`,`L${t+r},${e-n/2}`,`L${t+r-i},${e-n}`,`L${t+i},${e-n}`,`L${t},${e-n/2}`,"Z"].join(" "),"createHexagonPathD");o(fQ,"hexagon")});async function pQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.label="",e.labelStyle=r;let{shapeSvg:i}=await pt(t,e,ht(e)),a=Math.max(30,e?.width??0),s=Math.max(30,e?.height??0),{cssStyles:l}=e,u=Xe.svg(i),h=Ke(e,{});e.look!=="handDrawn"&&(h.roughness=0,h.fillStyle="solid");let f=[{x:0,y:0},{x:a,y:0},{x:0,y:s},{x:a,y:s}],d=Xt(f),p=u.path(d,h),m=i.insert(()=>p,":first-child");return m.attr("class","basic label-container"),l&&e.look!=="handDrawn"&&m.selectChildren("path").attr("style",l),n&&e.look!=="handDrawn"&&m.selectChildren("path").attr("style",n),m.attr("transform",`translate(${-a/2}, ${-s/2})`),je(e,m),e.intersect=function(g){return Y.info("Pill intersect",e,{points:f}),Ye.polygon(e,f,g)},i}var mQ=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();o(pQ,"hourglass")});async function gQ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Qe(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,label:d}=await pt(t,e,"icon-shape default"),p=e.pos==="t",m=l,g=l,{nodeBorder:y}=r,{stylesMap:v}=mc(e),x=-g/2,b=-m/2,w=e.label?8:0,C=Xe.svg(h),T=Ke(e,{stroke:"none",fill:"none"});e.look!=="handDrawn"&&(T.roughness=0,T.fillStyle="solid");let E=C.rectangle(x,b,g,m,T),A=Math.max(g,f.width),S=m+f.height+w,_=C.rectangle(-A/2,-S/2,A,S,{...T,fill:"transparent",stroke:"none"}),I=h.insert(()=>E,":first-child"),D=h.insert(()=>_);if(e.icon){let k=h.append("g");k.html(`<g>${await wo(e.icon,{height:l,width:l,fallbackPrefix:""})}</g>`);let L=k.node().getBBox(),R=L.width,O=L.height,M=L.x,B=L.y;k.attr("transform",`translate(${-R/2-M},${p?f.height/2+w/2-O/2-B:-f.height/2-w/2-O/2-B})`),k.attr("style",`color: ${v.get("stroke")??y};`)}return d.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${p?-S/2:S/2-f.height})`),I.attr("transform",`translate(0,${p?f.height/2+w/2:-f.height/2-w/2})`),je(e,D),e.intersect=function(k){if(Y.info("iconSquare intersect",e,k),!e.label)return Ye.rect(e,k);let L=e.x??0,R=e.y??0,O=e.height??0,M=[];return p?M=[{x:L-f.width/2,y:R-O/2},{x:L+f.width/2,y:R-O/2},{x:L+f.width/2,y:R-O/2+f.height+w},{x:L+g/2,y:R-O/2+f.height+w},{x:L+g/2,y:R+O/2},{x:L-g/2,y:R+O/2},{x:L-g/2,y:R-O/2+f.height+w},{x:L-f.width/2,y:R-O/2+f.height+w}]:M=[{x:L-g/2,y:R-O/2},{x:L+g/2,y:R-O/2},{x:L+g/2,y:R-O/2+m},{x:L+f.width/2,y:R-O/2+m},{x:L+f.width/2/2,y:R+O/2},{x:L-f.width/2,y:R+O/2},{x:L-f.width/2,y:R-O/2+m},{x:L-g/2,y:R-O/2+m}],Ye.polygon(e,M,k)},h}var yQ=N(()=>{"use strict";Wt();vt();tu();Ht();Ut();Ft();o(gQ,"icon")});async function vQ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Qe(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,label:d}=await pt(t,e,"icon-shape default"),p=20,m=e.label?8:0,g=e.pos==="t",{nodeBorder:y,mainBkg:v}=r,{stylesMap:x}=mc(e),b=Xe.svg(h),w=Ke(e,{});e.look!=="handDrawn"&&(w.roughness=0,w.fillStyle="solid");let C=x.get("fill");w.stroke=C??v;let T=h.append("g");e.icon&&T.html(`<g>${await wo(e.icon,{height:l,width:l,fallbackPrefix:""})}</g>`);let E=T.node().getBBox(),A=E.width,S=E.height,_=E.x,I=E.y,D=Math.max(A,S)*Math.SQRT2+p*2,k=b.circle(0,0,D,w),L=Math.max(D,f.width),R=D+f.height+m,O=b.rectangle(-L/2,-R/2,L,R,{...w,fill:"transparent",stroke:"none"}),M=h.insert(()=>k,":first-child"),B=h.insert(()=>O);return T.attr("transform",`translate(${-A/2-_},${g?f.height/2+m/2-S/2-I:-f.height/2-m/2-S/2-I})`),T.attr("style",`color: ${x.get("stroke")??y};`),d.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${g?-R/2:R/2-f.height})`),M.attr("transform",`translate(0,${g?f.height/2+m/2:-f.height/2-m/2})`),je(e,B),e.intersect=function(F){return Y.info("iconSquare intersect",e,F),Ye.rect(e,F)},h}var xQ=N(()=>{"use strict";Wt();vt();tu();Ht();Ut();Ft();o(vQ,"iconCircle")});var Na,qh=N(()=>{"use strict";Na=o((t,e,r,n,i)=>["M",t+i,e,"H",t+r-i,"A",i,i,0,0,1,t+r,e+i,"V",e+n-i,"A",i,i,0,0,1,t+r-i,e+n,"H",t+i,"A",i,i,0,0,1,t,e+n-i,"V",e+i,"A",i,i,0,0,1,t+i,e,"Z"].join(" "),"createRoundedRectPathD")});async function bQ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Qe(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,halfPadding:d,label:p}=await pt(t,e,"icon-shape default"),m=e.pos==="t",g=l+d*2,y=l+d*2,{nodeBorder:v,mainBkg:x}=r,{stylesMap:b}=mc(e),w=-y/2,C=-g/2,T=e.label?8:0,E=Xe.svg(h),A=Ke(e,{});e.look!=="handDrawn"&&(A.roughness=0,A.fillStyle="solid");let S=b.get("fill");A.stroke=S??x;let _=E.path(Na(w,C,y,g,5),A),I=Math.max(y,f.width),D=g+f.height+T,k=E.rectangle(-I/2,-D/2,I,D,{...A,fill:"transparent",stroke:"none"}),L=h.insert(()=>_,":first-child").attr("class","icon-shape2"),R=h.insert(()=>k);if(e.icon){let O=h.append("g");O.html(`<g>${await wo(e.icon,{height:l,width:l,fallbackPrefix:""})}</g>`);let M=O.node().getBBox(),B=M.width,F=M.height,P=M.x,z=M.y;O.attr("transform",`translate(${-B/2-P},${m?f.height/2+T/2-F/2-z:-f.height/2-T/2-F/2-z})`),O.attr("style",`color: ${b.get("stroke")??v};`)}return p.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${m?-D/2:D/2-f.height})`),L.attr("transform",`translate(0,${m?f.height/2+T/2:-f.height/2-T/2})`),je(e,R),e.intersect=function(O){if(Y.info("iconSquare intersect",e,O),!e.label)return Ye.rect(e,O);let M=e.x??0,B=e.y??0,F=e.height??0,P=[];return m?P=[{x:M-f.width/2,y:B-F/2},{x:M+f.width/2,y:B-F/2},{x:M+f.width/2,y:B-F/2+f.height+T},{x:M+y/2,y:B-F/2+f.height+T},{x:M+y/2,y:B+F/2},{x:M-y/2,y:B+F/2},{x:M-y/2,y:B-F/2+f.height+T},{x:M-f.width/2,y:B-F/2+f.height+T}]:P=[{x:M-y/2,y:B-F/2},{x:M+y/2,y:B-F/2},{x:M+y/2,y:B-F/2+g},{x:M+f.width/2,y:B-F/2+g},{x:M+f.width/2/2,y:B+F/2},{x:M-f.width/2,y:B+F/2},{x:M-f.width/2,y:B-F/2+g},{x:M-y/2,y:B-F/2+g}],Ye.polygon(e,P,O)},h}var wQ=N(()=>{"use strict";Wt();vt();tu();Ht();Ut();qh();Ft();o(bQ,"iconRounded")});async function TQ(t,e,{config:{themeVariables:r,flowchart:n}}){let{labelStyles:i}=Qe(e);e.labelStyle=i;let a=e.assetHeight??48,s=e.assetWidth??48,l=Math.max(a,s),u=n?.wrappingWidth;e.width=Math.max(l,u??0);let{shapeSvg:h,bbox:f,halfPadding:d,label:p}=await pt(t,e,"icon-shape default"),m=e.pos==="t",g=l+d*2,y=l+d*2,{nodeBorder:v,mainBkg:x}=r,{stylesMap:b}=mc(e),w=-y/2,C=-g/2,T=e.label?8:0,E=Xe.svg(h),A=Ke(e,{});e.look!=="handDrawn"&&(A.roughness=0,A.fillStyle="solid");let S=b.get("fill");A.stroke=S??x;let _=E.path(Na(w,C,y,g,.1),A),I=Math.max(y,f.width),D=g+f.height+T,k=E.rectangle(-I/2,-D/2,I,D,{...A,fill:"transparent",stroke:"none"}),L=h.insert(()=>_,":first-child"),R=h.insert(()=>k);if(e.icon){let O=h.append("g");O.html(`<g>${await wo(e.icon,{height:l,width:l,fallbackPrefix:""})}</g>`);let M=O.node().getBBox(),B=M.width,F=M.height,P=M.x,z=M.y;O.attr("transform",`translate(${-B/2-P},${m?f.height/2+T/2-F/2-z:-f.height/2-T/2-F/2-z})`),O.attr("style",`color: ${b.get("stroke")??v};`)}return p.attr("transform",`translate(${-f.width/2-(f.x-(f.left??0))},${m?-D/2:D/2-f.height})`),L.attr("transform",`translate(0,${m?f.height/2+T/2:-f.height/2-T/2})`),je(e,R),e.intersect=function(O){if(Y.info("iconSquare intersect",e,O),!e.label)return Ye.rect(e,O);let M=e.x??0,B=e.y??0,F=e.height??0,P=[];return m?P=[{x:M-f.width/2,y:B-F/2},{x:M+f.width/2,y:B-F/2},{x:M+f.width/2,y:B-F/2+f.height+T},{x:M+y/2,y:B-F/2+f.height+T},{x:M+y/2,y:B+F/2},{x:M-y/2,y:B+F/2},{x:M-y/2,y:B-F/2+f.height+T},{x:M-f.width/2,y:B-F/2+f.height+T}]:P=[{x:M-y/2,y:B-F/2},{x:M+y/2,y:B-F/2},{x:M+y/2,y:B-F/2+g},{x:M+f.width/2,y:B-F/2+g},{x:M+f.width/2/2,y:B+F/2},{x:M-f.width/2,y:B+F/2},{x:M-f.width/2,y:B-F/2+g},{x:M-y/2,y:B-F/2+g}],Ye.polygon(e,P,O)},h}var kQ=N(()=>{"use strict";Wt();vt();tu();Ht();qh();Ut();Ft();o(TQ,"iconSquare")});async function EQ(t,e,{config:{flowchart:r}}){let n=new Image;n.src=e?.img??"",await n.decode();let i=Number(n.naturalWidth.toString().replace("px","")),a=Number(n.naturalHeight.toString().replace("px",""));e.imageAspectRatio=i/a;let{labelStyles:s}=Qe(e);e.labelStyle=s;let l=r?.wrappingWidth;e.defaultWidth=r?.wrappingWidth;let u=Math.max(e.label?l??0:0,e?.assetWidth??i),h=e.constraint==="on"&&e?.assetHeight?e.assetHeight*e.imageAspectRatio:u,f=e.constraint==="on"?h/e.imageAspectRatio:e?.assetHeight??a;e.width=Math.max(h,l??0);let{shapeSvg:d,bbox:p,label:m}=await pt(t,e,"image-shape default"),g=e.pos==="t",y=-h/2,v=-f/2,x=e.label?8:0,b=Xe.svg(d),w=Ke(e,{});e.look!=="handDrawn"&&(w.roughness=0,w.fillStyle="solid");let C=b.rectangle(y,v,h,f,w),T=Math.max(h,p.width),E=f+p.height+x,A=b.rectangle(-T/2,-E/2,T,E,{...w,fill:"none",stroke:"none"}),S=d.insert(()=>C,":first-child"),_=d.insert(()=>A);if(e.img){let I=d.append("image");I.attr("href",e.img),I.attr("width",h),I.attr("height",f),I.attr("preserveAspectRatio","none"),I.attr("transform",`translate(${-h/2},${g?E/2-f:-E/2})`)}return m.attr("transform",`translate(${-p.width/2-(p.x-(p.left??0))},${g?-f/2-p.height/2-x/2:f/2-p.height/2+x/2})`),S.attr("transform",`translate(0,${g?p.height/2+x/2:-p.height/2-x/2})`),je(e,_),e.intersect=function(I){if(Y.info("iconSquare intersect",e,I),!e.label)return Ye.rect(e,I);let D=e.x??0,k=e.y??0,L=e.height??0,R=[];return g?R=[{x:D-p.width/2,y:k-L/2},{x:D+p.width/2,y:k-L/2},{x:D+p.width/2,y:k-L/2+p.height+x},{x:D+h/2,y:k-L/2+p.height+x},{x:D+h/2,y:k+L/2},{x:D-h/2,y:k+L/2},{x:D-h/2,y:k-L/2+p.height+x},{x:D-p.width/2,y:k-L/2+p.height+x}]:R=[{x:D-h/2,y:k-L/2},{x:D+h/2,y:k-L/2},{x:D+h/2,y:k-L/2+f},{x:D+p.width/2,y:k-L/2+f},{x:D+p.width/2/2,y:k+L/2},{x:D-p.width/2,y:k+L/2},{x:D-p.width/2,y:k-L/2+f},{x:D-h/2,y:k-L/2+f}],Ye.polygon(e,R,I)},d}var SQ=N(()=>{"use strict";Wt();vt();Ht();Ut();Ft();o(EQ,"imageSquare")});async function CQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0)*2,e?.width??0),l=Math.max(a.height+(e.padding??0)*2,e?.height??0),u=[{x:0,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:-3*l/6,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=Xe.svg(i),p=Ke(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=La(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,je(e,h),e.intersect=function(d){return Ye.polygon(e,u,d)},i}var AQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();o(CQ,"inv_trapezoid")});async function Du(t,e,r){let{labelStyles:n,nodeStyles:i}=Qe(e);e.labelStyle=n;let{shapeSvg:a,bbox:s}=await pt(t,e,ht(e)),l=Math.max(s.width+r.labelPaddingX*2,e?.width||0),u=Math.max(s.height+r.labelPaddingY*2,e?.height||0),h=-l/2,f=-u/2,d,{rx:p,ry:m}=e,{cssStyles:g}=e;if(r?.rx&&r.ry&&(p=r.rx,m=r.ry),e.look==="handDrawn"){let y=Xe.svg(a),v=Ke(e,{}),x=p||m?y.path(Na(h,f,l,u,p||0),v):y.rectangle(h,f,l,u,v);d=a.insert(()=>x,":first-child"),d.attr("class","basic label-container").attr("style",$n(g))}else d=a.insert("rect",":first-child"),d.attr("class","basic label-container").attr("style",i).attr("rx",$n(p)).attr("ry",$n(m)).attr("x",h).attr("y",f).attr("width",l).attr("height",u);return je(e,d),e.intersect=function(y){return Ye.rect(e,y)},a}var mm=N(()=>{"use strict";Ft();Ht();qh();Ut();Wt();ir();o(Du,"drawRect")});async function _Q(t,e){let{shapeSvg:r,bbox:n,label:i}=await pt(t,e,"label"),a=r.insert("rect",":first-child");return a.attr("width",.1).attr("height",.1),r.attr("class","label edgeLabel"),i.attr("transform",`translate(${-(n.width/2)-(n.x-(n.left??0))}, ${-(n.height/2)-(n.y-(n.top??0))})`),je(e,a),e.intersect=function(u){return Ye.rect(e,u)},r}var DQ=N(()=>{"use strict";mm();Ft();Ht();o(_Q,"labelRect")});async function LQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0),e?.width??0),l=Math.max(a.height+(e.padding??0),e?.height??0),u=[{x:0,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:-(3*l)/6,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=Xe.svg(i),p=Ke(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=La(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,je(e,h),e.intersect=function(d){return Ye.polygon(e,u,d)},i}var RQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();o(LQ,"lean_left")});async function NQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0),e?.width??0),l=Math.max(a.height+(e.padding??0),e?.height??0),u=[{x:-3*l/6,y:0},{x:s,y:0},{x:s+3*l/6,y:-l},{x:0,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=Xe.svg(i),p=Ke(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=La(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,je(e,h),e.intersect=function(d){return Ye.polygon(e,u,d)},i}var MQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();o(NQ,"lean_right")});function IQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.label="",e.labelStyle=r;let i=t.insert("g").attr("class",ht(e)).attr("id",e.domId??e.id),{cssStyles:a}=e,s=Math.max(35,e?.width??0),l=Math.max(35,e?.height??0),u=7,h=[{x:s,y:0},{x:0,y:l+u/2},{x:s-2*u,y:l+u/2},{x:0,y:2*l},{x:s,y:l-u/2},{x:2*u,y:l-u/2}],f=Xe.svg(i),d=Ke(e,{});e.look!=="handDrawn"&&(d.roughness=0,d.fillStyle="solid");let p=Xt(h),m=f.path(p,d),g=i.insert(()=>m,":first-child");return a&&e.look!=="handDrawn"&&g.selectAll("path").attr("style",a),n&&e.look!=="handDrawn"&&g.selectAll("path").attr("style",n),g.attr("transform",`translate(-${s/2},${-l})`),je(e,g),e.intersect=function(y){return Y.info("lightningBolt intersect",e,y),Ye.polygon(e,h,y)},i}var OQ=N(()=>{"use strict";vt();Ft();Ut();Wt();Ht();Ft();o(IQ,"lightningBolt")});async function PQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0),e.width??0),u=l/2,h=u/(2.5+l/50),f=Math.max(a.height+h+(e.padding??0),e.height??0),d=f*.1,p,{cssStyles:m}=e;if(e.look==="handDrawn"){let g=Xe.svg(i),y=p_e(0,0,l,f,u,h,d),v=m_e(0,h,l,f,u,h),x=Ke(e,{}),b=g.path(y,x),w=g.path(v,x);i.insert(()=>w,":first-child").attr("class","line"),p=i.insert(()=>b,":first-child"),p.attr("class","basic label-container"),m&&p.attr("style",m)}else{let g=d_e(0,0,l,f,u,h,d);p=i.insert("path",":first-child").attr("d",g).attr("class","basic label-container").attr("style",$n(m)).attr("style",n)}return p.attr("label-offset-y",h),p.attr("transform",`translate(${-l/2}, ${-(f/2+h)})`),je(e,p),s.attr("transform",`translate(${-(a.width/2)-(a.x-(a.left??0))}, ${-(a.height/2)+h-(a.y-(a.top??0))})`),e.intersect=function(g){let y=Ye.rect(e,g),v=y.x-(e.x??0);if(u!=0&&(Math.abs(v)<(e.width??0)/2||Math.abs(v)==(e.width??0)/2&&Math.abs(y.y-(e.y??0))>(e.height??0)/2-h)){let x=h*h*(1-v*v/(u*u));x>0&&(x=Math.sqrt(x)),x=h-x,g.y-(e.y??0)>0&&(x=-x),y.y+=x}return y},i}var d_e,p_e,m_e,BQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();ir();d_e=o((t,e,r,n,i,a,s)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`,`M${t},${e+a+s}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createCylinderPathD"),p_e=o((t,e,r,n,i,a,s)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,`l0,${-n}`,`M${t},${e+a+s}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createOuterCylinderPathD"),m_e=o((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" "),"createInnerCylinderPathD");o(PQ,"linedCylinder")});async function FQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=u+h,{cssStyles:d}=e,p=Xe.svg(i),m=Ke(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:-l/2-l/2*.1,y:-f/2},{x:-l/2-l/2*.1,y:f/2},...Fo(-l/2-l/2*.1,f/2,l/2+l/2*.1,f/2,h,.8),{x:l/2+l/2*.1,y:-f/2},{x:-l/2-l/2*.1,y:-f/2},{x:-l/2,y:-f/2},{x:-l/2,y:f/2*1.1},{x:-l/2,y:-f/2}],y=p.polygon(g.map(x=>[x.x,x.y]),m),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",d),n&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)+l/2*.1/2-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h/2-(a.y-(a.top??0))})`),je(e,v),e.intersect=function(x){return Ye.polygon(e,g,x)},i}var $Q=N(()=>{"use strict";Ft();Ht();Wt();Ut();o(FQ,"linedWaveEdgedRect")});async function zQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=5,f=-l/2,d=-u/2,{cssStyles:p}=e,m=Xe.svg(i),g=Ke(e,{}),y=[{x:f-h,y:d+h},{x:f-h,y:d+u+h},{x:f+l-h,y:d+u+h},{x:f+l-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d+u-h},{x:f+l+h,y:d+u-h},{x:f+l+h,y:d-h},{x:f+h,y:d-h},{x:f+h,y:d},{x:f,y:d},{x:f,y:d+h}],v=[{x:f,y:d+h},{x:f+l-h,y:d+h},{x:f+l-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d},{x:f,y:d}];e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=Xt(y),b=m.path(x,g),w=Xt(v),C=m.path(w,{...g,fill:"none"}),T=i.insert(()=>C,":first-child");return T.insert(()=>b,":first-child"),T.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&T.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&T.selectAll("path").attr("style",n),s.attr("transform",`translate(${-(a.width/2)-h-(a.x-(a.left??0))}, ${-(a.height/2)+h-(a.y-(a.top??0))})`),je(e,T),e.intersect=function(E){return Ye.polygon(e,y,E)},i}var GQ=N(()=>{"use strict";Ft();Ut();Wt();Ht();o(zQ,"multiRect")});async function VQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=u+h,d=-l/2,p=-f/2,m=5,{cssStyles:g}=e,y=Fo(d-m,p+f+m,d+l-m,p+f+m,h,.8),v=y?.[y.length-1],x=[{x:d-m,y:p+m},{x:d-m,y:p+f+m},...y,{x:d+l-m,y:v.y-m},{x:d+l,y:v.y-m},{x:d+l,y:v.y-2*m},{x:d+l+m,y:v.y-2*m},{x:d+l+m,y:p-m},{x:d+m,y:p-m},{x:d+m,y:p},{x:d,y:p},{x:d,y:p+m}],b=[{x:d,y:p+m},{x:d+l-m,y:p+m},{x:d+l-m,y:v.y-m},{x:d+l,y:v.y-m},{x:d+l,y:p},{x:d,y:p}],w=Xe.svg(i),C=Ke(e,{});e.look!=="handDrawn"&&(C.roughness=0,C.fillStyle="solid");let T=Xt(x),E=w.path(T,C),A=Xt(b),S=w.path(A,C),_=i.insert(()=>E,":first-child");return _.insert(()=>S),_.attr("class","basic label-container"),g&&e.look!=="handDrawn"&&_.selectAll("path").attr("style",g),n&&e.look!=="handDrawn"&&_.selectAll("path").attr("style",n),_.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-(a.width/2)-m-(a.x-(a.left??0))}, ${-(a.height/2)+m-h/2-(a.y-(a.top??0))})`),je(e,_),e.intersect=function(I){return Ye.polygon(e,x,I)},i}var UQ=N(()=>{"use strict";Ft();Ht();Wt();Ut();o(VQ,"multiWaveEdgedRectangle")});async function HQ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Qe(e);e.labelStyle=n,e.useHtmlLabels||cr().flowchart?.htmlLabels!==!1||(e.centerLabel=!0);let{shapeSvg:s,bbox:l}=await pt(t,e,ht(e)),u=Math.max(l.width+(e.padding??0)*2,e?.width??0),h=Math.max(l.height+(e.padding??0)*2,e?.height??0),f=-u/2,d=-h/2,{cssStyles:p}=e,m=Xe.svg(s),g=Ke(e,{fill:r.noteBkgColor,stroke:r.noteBorderColor});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=m.rectangle(f,d,u,h,g),v=s.insert(()=>y,":first-child");return v.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",p),i&&e.look!=="handDrawn"&&v.selectAll("path").attr("style",i),je(e,v),e.intersect=function(x){return Ye.rect(e,x)},s}var WQ=N(()=>{"use strict";Wt();Ht();Ut();Ft();ji();o(HQ,"note")});async function qQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=a.width+e.padding,l=a.height+e.padding,u=s+l,h=[{x:u/2,y:0},{x:u,y:-u/2},{x:u/2,y:-u},{x:0,y:-u/2}],f,{cssStyles:d}=e;if(e.look==="handDrawn"){let p=Xe.svg(i),m=Ke(e,{}),g=g_e(0,0,u),y=p.path(g,m);f=i.insert(()=>y,":first-child").attr("transform",`translate(${-u/2}, ${u/2})`),d&&f.attr("style",d)}else f=La(i,u,u,h);return n&&f.attr("style",n),je(e,f),e.intersect=function(p){return Y.debug(`APA12 Intersect called SPLIT
+point:`,p,`
+node:
+`,e,`
+res:`,Ye.polygon(e,h,p)),Ye.polygon(e,h,p)},i}var g_e,YQ=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();_u();g_e=o((t,e,r)=>[`M${t+r/2},${e}`,`L${t+r},${e-r/2}`,`L${t+r/2},${e-r}`,`L${t},${e-r/2}`,"Z"].join(" "),"createDecisionBoxPathD");o(qQ,"question")});async function XQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0),e?.width??0),u=Math.max(a.height+(e.padding??0),e?.height??0),h=-l/2,f=-u/2,d=f/2,p=[{x:h+d,y:f},{x:h,y:0},{x:h+d,y:-f},{x:-h,y:-f},{x:-h,y:f}],{cssStyles:m}=e,g=Xe.svg(i),y=Ke(e,{});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=Xt(p),x=g.path(v,y),b=i.insert(()=>x,":first-child");return b.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",m),n&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",n),b.attr("transform",`translate(${-d/2},0)`),s.attr("transform",`translate(${-d/2-a.width/2-(a.x-(a.left??0))}, ${-(a.height/2)-(a.y-(a.top??0))})`),je(e,b),e.intersect=function(w){return Ye.polygon(e,p,w)},i}var jQ=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(XQ,"rect_left_inv_arrow")});function y_e(t,e){e&&t.attr("style",e)}async function v_e(t){let e=Ge(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),n=t.label;t.label&&pi(t.label)&&(n=await mh(t.label.replace(Ze.lineBreakRegex,`
+`),me()));let i=t.isNode?"nodeLabel":"edgeLabel";return r.html('<span class="'+i+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+n+"</span>"),y_e(r,t.labelStyle),r.style("display","inline-block"),r.style("padding-right","1px"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}var x_e,gc,Gw=N(()=>{"use strict";dr();vt();zt();gr();ir();o(y_e,"applyStyle");o(v_e,"addHtmlLabel");x_e=o(async(t,e,r,n)=>{let i=t||"";if(typeof i=="object"&&(i=i[0]),fr(me().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"<br />"),Y.info("vertexText"+i);let a={isNode:n,label:na(i).replace(/fa[blrs]?:fa-[\w-]+/g,l=>`<i class='${l.replace(":"," ")}'></i>`),labelStyle:e&&e.replace("fill:","color:")};return await v_e(a)}else{let a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));let s=[];typeof i=="string"?s=i.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(i)?s=i:s=[];for(let l of s){let u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),r?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=l.trim(),a.appendChild(u)}return a}},"createLabel"),gc=x_e});async function KQ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let i;e.cssClasses?i="node "+e.cssClasses:i="node default";let a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),s=a.insert("g"),l=a.insert("g").attr("class","label").attr("style",n),u=e.description,h=e.label,f=l.node().appendChild(await gc(h,e.labelStyle,!0,!0)),d={width:0,height:0};if(fr(me()?.flowchart?.htmlLabels)){let S=f.children[0],_=Ge(f);d=S.getBoundingClientRect(),_.attr("width",d.width),_.attr("height",d.height)}Y.info("Text 2",u);let p=u||[],m=f.getBBox(),g=l.node().appendChild(await gc(p.join?p.join("<br/>"):p,e.labelStyle,!0,!0)),y=g.children[0],v=Ge(g);d=y.getBoundingClientRect(),v.attr("width",d.width),v.attr("height",d.height);let x=(e.padding||0)/2;Ge(g).attr("transform","translate( "+(d.width>m.width?0:(m.width-d.width)/2)+", "+(m.height+x+5)+")"),Ge(f).attr("transform","translate( "+(d.width<m.width?0:-(m.width-d.width)/2)+", 0)"),d=l.node().getBBox(),l.attr("transform","translate("+-d.width/2+", "+(-d.height/2-x+3)+")");let b=d.width+(e.padding||0),w=d.height+(e.padding||0),C=-d.width/2-x,T=-d.height/2-x,E,A;if(e.look==="handDrawn"){let S=Xe.svg(a),_=Ke(e,{}),I=S.path(Na(C,T,b,w,e.rx||0),_),D=S.line(-d.width/2-x,-d.height/2-x+m.height+x,d.width/2+x,-d.height/2-x+m.height+x,_);A=a.insert(()=>(Y.debug("Rough node insert CXC",I),D),":first-child"),E=a.insert(()=>(Y.debug("Rough node insert CXC",I),I),":first-child")}else E=s.insert("rect",":first-child"),A=s.insert("line"),E.attr("class","outer title-state").attr("style",n).attr("x",-d.width/2-x).attr("y",-d.height/2-x).attr("width",d.width+(e.padding||0)).attr("height",d.height+(e.padding||0)),A.attr("class","divider").attr("x1",-d.width/2-x).attr("x2",d.width/2+x).attr("y1",-d.height/2-x+m.height+x).attr("y2",-d.height/2-x+m.height+x);return je(e,E),e.intersect=function(S){return Ye.rect(e,S)},a}var QQ=N(()=>{"use strict";dr();gr();Ft();Gw();Ht();Ut();Wt();zt();qh();vt();o(KQ,"rectWithTitle")});async function ZQ(t,e){let r={rx:5,ry:5,classes:"",labelPaddingX:(e?.padding||0)*1,labelPaddingY:(e?.padding||0)*1};return Du(t,e,r)}var JQ=N(()=>{"use strict";mm();o(ZQ,"roundedRect")});async function eZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=e?.padding??0,u=Math.max(a.width+(e.padding??0)*2,e?.width??0),h=Math.max(a.height+(e.padding??0)*2,e?.height??0),f=-a.width/2-l,d=-a.height/2-l,{cssStyles:p}=e,m=Xe.svg(i),g=Ke(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=[{x:f,y:d},{x:f+u+8,y:d},{x:f+u+8,y:d+h},{x:f-8,y:d+h},{x:f-8,y:d},{x:f,y:d},{x:f,y:d+h}],v=m.polygon(y.map(b=>[b.x,b.y]),g),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container").attr("style",$n(p)),n&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),p&&e.look!=="handDrawn"&&x.selectAll("path").attr("style",n),s.attr("transform",`translate(${-u/2+4+(e.padding??0)-(a.x-(a.left??0))},${-h/2+(e.padding??0)-(a.y-(a.top??0))})`),je(e,x),e.intersect=function(b){return Ye.rect(e,b)},i}var tZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();ir();o(eZ,"shadedProcess")});async function rZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=-l/2,f=-u/2,{cssStyles:d}=e,p=Xe.svg(i),m=Ke(e,{});e.look!=="handDrawn"&&(m.roughness=0,m.fillStyle="solid");let g=[{x:h,y:f},{x:h,y:f+u},{x:h+l,y:f+u},{x:h+l,y:f-u/2}],y=Xt(g),v=p.path(y,m),x=i.insert(()=>v,":first-child");return x.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",d),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),x.attr("transform",`translate(0, ${u/4})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))}, ${-u/4+(e.padding??0)-(a.y-(a.top??0))})`),je(e,x),e.intersect=function(b){return Ye.polygon(e,g,b)},i}var nZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(rZ,"slopedRect")});async function iZ(t,e){let r={rx:0,ry:0,classes:"",labelPaddingX:(e?.padding||0)*2,labelPaddingY:(e?.padding||0)*1};return Du(t,e,r)}var aZ=N(()=>{"use strict";mm();o(iZ,"squareRect")});async function sZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=a.height+e.padding,l=a.width+s/4+e.padding,u,{cssStyles:h}=e;if(e.look==="handDrawn"){let f=Xe.svg(i),d=Ke(e,{}),p=Na(-l/2,-s/2,l,s,s/2),m=f.path(p,d);u=i.insert(()=>m,":first-child"),u.attr("class","basic label-container").attr("style",$n(h))}else u=i.insert("rect",":first-child"),u.attr("class","basic label-container").attr("style",n).attr("rx",s/2).attr("ry",s/2).attr("x",-l/2).attr("y",-s/2).attr("width",l).attr("height",s);return je(e,u),e.intersect=function(f){return Ye.rect(e,f)},i}var oZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();qh();ir();o(sZ,"stadium")});async function lZ(t,e){return Du(t,e,{rx:5,ry:5,classes:"flowchart-node"})}var cZ=N(()=>{"use strict";mm();o(lZ,"state")});function uZ(t,e,{config:{themeVariables:r}}){let{labelStyles:n,nodeStyles:i}=Qe(e);e.labelStyle=n;let{cssStyles:a}=e,{lineColor:s,stateBorder:l,nodeBorder:u}=r,h=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),f=Xe.svg(h),d=Ke(e,{});e.look!=="handDrawn"&&(d.roughness=0,d.fillStyle="solid");let p=f.circle(0,0,14,{...d,stroke:s,strokeWidth:2}),m=l??u,g=f.circle(0,0,5,{...d,fill:m,stroke:m,strokeWidth:2,fillStyle:"solid"}),y=h.insert(()=>p,":first-child");return y.insert(()=>g),a&&y.selectAll("path").attr("style",a),i&&y.selectAll("path").attr("style",i),je(e,y),e.intersect=function(v){return Ye.circle(e,7,v)},h}var hZ=N(()=>{"use strict";Wt();Ht();Ut();Ft();o(uZ,"stateEnd")});function fZ(t,e,{config:{themeVariables:r}}){let{lineColor:n}=r,i=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a;if(e.look==="handDrawn"){let l=Xe.svg(i).circle(0,0,14,gK(n));a=i.insert(()=>l),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14)}else a=i.insert("circle",":first-child"),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14);return je(e,a),e.intersect=function(s){return Ye.circle(e,7,s)},i}var dZ=N(()=>{"use strict";Wt();Ht();Ut();Ft();o(fZ,"stateStart")});async function pZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=(e?.padding||0)/2,l=a.width+e.padding,u=a.height+e.padding,h=-a.width/2-s,f=-a.height/2-s,d=[{x:0,y:0},{x:l,y:0},{x:l,y:-u},{x:0,y:-u},{x:0,y:0},{x:-8,y:0},{x:l+8,y:0},{x:l+8,y:-u},{x:-8,y:-u},{x:-8,y:0}];if(e.look==="handDrawn"){let p=Xe.svg(i),m=Ke(e,{}),g=p.rectangle(h-8,f,l+16,u,m),y=p.line(h,f,h,f+u,m),v=p.line(h+l,f,h+l,f+u,m);i.insert(()=>y,":first-child"),i.insert(()=>v,":first-child");let x=i.insert(()=>g,":first-child"),{cssStyles:b}=e;x.attr("class","basic label-container").attr("style",$n(b)),je(e,x)}else{let p=La(i,l,u,d);n&&p.attr("style",n),je(e,p)}return e.intersect=function(p){return Ye.polygon(e,d,p)},i}var mZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();ir();o(pZ,"subroutine")});async function gZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=Math.max(a.width+(e.padding??0)*2,e?.width??0),l=Math.max(a.height+(e.padding??0)*2,e?.height??0),u=-s/2,h=-l/2,f=.2*l,d=.2*l,{cssStyles:p}=e,m=Xe.svg(i),g=Ke(e,{}),y=[{x:u-f/2,y:h},{x:u+s+f/2,y:h},{x:u+s+f/2,y:h+l},{x:u-f/2,y:h+l}],v=[{x:u+s-f/2,y:h+l},{x:u+s+f/2,y:h+l},{x:u+s+f/2,y:h+l-d}];e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=Xt(y),b=m.path(x,g),w=Xt(v),C=m.path(w,{...g,fillStyle:"solid"}),T=i.insert(()=>C,":first-child");return T.insert(()=>b,":first-child"),T.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&T.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&T.selectAll("path").attr("style",n),je(e,T),e.intersect=function(E){return Ye.polygon(e,y,E)},i}var yZ=N(()=>{"use strict";Ft();Ut();Wt();Ht();o(gZ,"taggedRect")});async function vZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/4,f=.2*l,d=.2*u,p=u+h,{cssStyles:m}=e,g=Xe.svg(i),y=Ke(e,{});e.look!=="handDrawn"&&(y.roughness=0,y.fillStyle="solid");let v=[{x:-l/2-l/2*.1,y:p/2},...Fo(-l/2-l/2*.1,p/2,l/2+l/2*.1,p/2,h,.8),{x:l/2+l/2*.1,y:-p/2},{x:-l/2-l/2*.1,y:-p/2}],x=-l/2+l/2*.1,b=-p/2-d*.4,w=[{x:x+l-f,y:(b+u)*1.4},{x:x+l,y:b+u-d},{x:x+l,y:(b+u)*.9},...Fo(x+l,(b+u)*1.3,x+l-f,(b+u)*1.5,-u*.03,.5)],C=Xt(v),T=g.path(C,y),E=Xt(w),A=g.path(E,{...y,fillStyle:"solid"}),S=i.insert(()=>A,":first-child");return S.insert(()=>T,":first-child"),S.attr("class","basic label-container"),m&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",m),n&&e.look!=="handDrawn"&&S.selectAll("path").attr("style",n),S.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h/2-(a.y-(a.top??0))})`),je(e,S),e.intersect=function(_){return Ye.polygon(e,v,_)},i}var xZ=N(()=>{"use strict";Ft();Ht();Wt();Ut();o(vZ,"taggedWaveEdgedRectangle")});async function bZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=Math.max(a.width+e.padding,e?.width||0),l=Math.max(a.height+e.padding,e?.height||0),u=-s/2,h=-l/2,f=i.insert("rect",":first-child");return f.attr("class","text").attr("style",n).attr("rx",0).attr("ry",0).attr("x",u).attr("y",h).attr("width",s).attr("height",l),je(e,f),e.intersect=function(d){return Ye.rect(e,d)},i}var wZ=N(()=>{"use strict";Ft();Ht();Ut();o(bZ,"text")});async function TZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s,halfPadding:l}=await pt(t,e,ht(e)),u=e.look==="neo"?l*2:l,h=a.height+u,f=h/2,d=f/(2.5+h/50),p=a.width+d+u,{cssStyles:m}=e,g;if(e.look==="handDrawn"){let y=Xe.svg(i),v=w_e(0,0,p,h,d,f),x=T_e(0,0,p,h,d,f),b=y.path(v,Ke(e,{})),w=y.path(x,Ke(e,{fill:"none"}));g=i.insert(()=>w,":first-child"),g=i.insert(()=>b,":first-child"),g.attr("class","basic label-container"),m&&g.attr("style",m)}else{let y=b_e(0,0,p,h,d,f);g=i.insert("path",":first-child").attr("d",y).attr("class","basic label-container").attr("style",$n(m)).attr("style",n),g.attr("class","basic label-container"),m&&g.selectAll("path").attr("style",m),n&&g.selectAll("path").attr("style",n)}return g.attr("label-offset-x",d),g.attr("transform",`translate(${-p/2}, ${h/2} )`),s.attr("transform",`translate(${-(a.width/2)-d-(a.x-(a.left??0))}, ${-(a.height/2)-(a.y-(a.top??0))})`),je(e,g),e.intersect=function(y){let v=Ye.rect(e,y),x=v.y-(e.y??0);if(f!=0&&(Math.abs(x)<(e.height??0)/2||Math.abs(x)==(e.height??0)/2&&Math.abs(v.x-(e.x??0))>(e.width??0)/2-d)){let b=d*d*(1-x*x/(f*f));b!=0&&(b=Math.sqrt(Math.abs(b))),b=d-b,y.x-(e.x??0)>0&&(b=-b),v.x+=b}return v},i}var b_e,w_e,T_e,kZ=N(()=>{"use strict";Ft();Ut();Wt();Ht();ir();b_e=o((t,e,r,n,i,a)=>`M${t},${e}
+ a${i},${a} 0,0,1 0,${-n}
+ l${r},0
+ a${i},${a} 0,0,1 0,${n}
+ M${r},${-n}
+ a${i},${a} 0,0,0 0,${n}
+ l${-r},0`,"createCylinderPathD"),w_e=o((t,e,r,n,i,a)=>[`M${t},${e}`,`M${t+r},${e}`,`a${i},${a} 0,0,0 0,${-n}`,`l${-r},0`,`a${i},${a} 0,0,0 0,${n}`,`l${r},0`].join(" "),"createOuterCylinderPathD"),T_e=o((t,e,r,n,i,a)=>[`M${t+r/2},${-n/2}`,`a${i},${a} 0,0,0 0,${n}`].join(" "),"createInnerCylinderPathD");o(TZ,"tiltedCylinder")});async function EZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=a.width+e.padding,l=a.height+e.padding,u=[{x:-3*l/6,y:0},{x:s+3*l/6,y:0},{x:s,y:-l},{x:0,y:-l}],h,{cssStyles:f}=e;if(e.look==="handDrawn"){let d=Xe.svg(i),p=Ke(e,{}),m=Xt(u),g=d.path(m,p);h=i.insert(()=>g,":first-child").attr("transform",`translate(${-s/2}, ${l/2})`),f&&h.attr("style",f)}else h=La(i,s,l,u);return n&&h.attr("style",n),e.width=s,e.height=l,je(e,h),e.intersect=function(d){return Ye.polygon(e,u,d)},i}var SZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();_u();o(EZ,"trapezoid")});async function CZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=60,l=20,u=Math.max(s,a.width+(e.padding??0)*2,e?.width??0),h=Math.max(l,a.height+(e.padding??0)*2,e?.height??0),{cssStyles:f}=e,d=Xe.svg(i),p=Ke(e,{});e.look!=="handDrawn"&&(p.roughness=0,p.fillStyle="solid");let m=[{x:-u/2*.8,y:-h/2},{x:u/2*.8,y:-h/2},{x:u/2,y:-h/2*.6},{x:u/2,y:h/2},{x:-u/2,y:h/2},{x:-u/2,y:-h/2*.6}],g=Xt(m),y=d.path(g,p),v=i.insert(()=>y,":first-child");return v.attr("class","basic label-container"),f&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",f),n&&e.look!=="handDrawn"&&v.selectChildren("path").attr("style",n),je(e,v),e.intersect=function(x){return Ye.polygon(e,m,x)},i}var AZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(CZ,"trapezoidalPentagon")});async function _Z(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=fr(me().flowchart?.htmlLabels),u=a.width+(e.padding??0),h=u+a.height,f=u+a.height,d=[{x:0,y:0},{x:f,y:0},{x:f/2,y:-h}],{cssStyles:p}=e,m=Xe.svg(i),g=Ke(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=Xt(d),v=m.path(y,g),x=i.insert(()=>v,":first-child").attr("transform",`translate(${-h/2}, ${h/2})`);return p&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",p),n&&e.look!=="handDrawn"&&x.selectChildren("path").attr("style",n),e.width=u,e.height=h,je(e,x),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${h/2-(a.height+(e.padding??0)/(l?2:1)-(a.y-(a.top??0)))})`),e.intersect=function(b){return Y.info("Triangle intersect",e,d,b),Ye.polygon(e,d,b)},i}var DZ=N(()=>{"use strict";vt();Ft();Ht();Ut();Wt();Ft();gr();zt();o(_Z,"triangle")});async function LZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=u/8,f=u+h,{cssStyles:d}=e,m=70-l,g=m>0?m/2:0,y=Xe.svg(i),v=Ke(e,{});e.look!=="handDrawn"&&(v.roughness=0,v.fillStyle="solid");let x=[{x:-l/2-g,y:f/2},...Fo(-l/2-g,f/2,l/2+g,f/2,h,.8),{x:l/2+g,y:-f/2},{x:-l/2-g,y:-f/2}],b=Xt(x),w=y.path(b,v),C=i.insert(()=>w,":first-child");return C.attr("class","basic label-container"),d&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",d),n&&e.look!=="handDrawn"&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(0,${-h/2})`),s.attr("transform",`translate(${-l/2+(e.padding??0)-(a.x-(a.left??0))},${-u/2+(e.padding??0)-h-(a.y-(a.top??0))})`),je(e,C),e.intersect=function(T){return Ye.polygon(e,x,T)},i}var RZ=N(()=>{"use strict";Ft();Ht();Wt();Ut();o(LZ,"waveEdgedRectangle")});async function NZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a}=await pt(t,e,ht(e)),s=100,l=50,u=Math.max(a.width+(e.padding??0)*2,e?.width??0),h=Math.max(a.height+(e.padding??0)*2,e?.height??0),f=u/h,d=u,p=h;d>p*f?p=d/f:d=p*f,d=Math.max(d,s),p=Math.max(p,l);let m=Math.min(p*.2,p/4),g=p+m*2,{cssStyles:y}=e,v=Xe.svg(i),x=Ke(e,{});e.look!=="handDrawn"&&(x.roughness=0,x.fillStyle="solid");let b=[{x:-d/2,y:g/2},...Fo(-d/2,g/2,d/2,g/2,m,1),{x:d/2,y:-g/2},...Fo(d/2,-g/2,-d/2,-g/2,m,-1)],w=Xt(b),C=v.path(w,x),T=i.insert(()=>C,":first-child");return T.attr("class","basic label-container"),y&&e.look!=="handDrawn"&&T.selectAll("path").attr("style",y),n&&e.look!=="handDrawn"&&T.selectAll("path").attr("style",n),je(e,T),e.intersect=function(E){return Ye.polygon(e,b,E)},i}var MZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();o(NZ,"waveRectangle")});async function IZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let{shapeSvg:i,bbox:a,label:s}=await pt(t,e,ht(e)),l=Math.max(a.width+(e.padding??0)*2,e?.width??0),u=Math.max(a.height+(e.padding??0)*2,e?.height??0),h=5,f=-l/2,d=-u/2,{cssStyles:p}=e,m=Xe.svg(i),g=Ke(e,{}),y=[{x:f-h,y:d-h},{x:f-h,y:d+u},{x:f+l,y:d+u},{x:f+l,y:d-h}],v=`M${f-h},${d-h} L${f+l},${d-h} L${f+l},${d+u} L${f-h},${d+u} L${f-h},${d-h}
+ M${f-h},${d} L${f+l},${d}
+ M${f},${d-h} L${f},${d+u}`;e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let x=m.path(v,g),b=i.insert(()=>x,":first-child");return b.attr("transform",`translate(${h/2}, ${h/2})`),b.attr("class","basic label-container"),p&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",p),n&&e.look!=="handDrawn"&&b.selectAll("path").attr("style",n),s.attr("transform",`translate(${-(a.width/2)+h/2-(a.x-(a.left??0))}, ${-(a.height/2)+h/2-(a.y-(a.top??0))})`),je(e,b),e.intersect=function(w){return Ye.polygon(e,y,w)},i}var OZ=N(()=>{"use strict";Ft();Ut();Wt();Ht();o(IZ,"windowPane")});async function KD(t,e){let r=e;if(r.alias&&(e.label=r.alias),e.look==="handDrawn"){let{themeVariables:P}=cr(),{background:z}=P,$={...e,id:e.id+"-background",look:"default",cssStyles:["stroke: none",`fill: ${z}`]};await KD(t,$)}let n=cr();e.useHtmlLabels=n.htmlLabels;let i=n.er?.diagramPadding??10,a=n.er?.entityPadding??6,{cssStyles:s}=e,{labelStyles:l}=Qe(e);if(r.attributes.length===0&&e.label){let P={rx:0,ry:0,labelPaddingX:i,labelPaddingY:i*1.5,classes:""};ra(e.label,n)+P.labelPaddingX*2<n.er.minEntityWidth&&(e.width=n.er.minEntityWidth);let z=await Du(t,e,P);if(!fr(n.htmlLabels)){let $=z.select("text"),H=$.node()?.getBBox();$.attr("transform",`translate(${-H.width/2}, 0)`)}return z}n.htmlLabels||(i*=1.25,a*=1.25);let u=ht(e);u||(u="node default");let h=t.insert("g").attr("class",u).attr("id",e.domId||e.id),f=await b2(h,e.label??"",n,0,0,["name"],l);f.height+=a;let d=0,p=[],m=0,g=0,y=0,v=0,x=!0,b=!0;for(let P of r.attributes){let z=await b2(h,P.type,n,0,d,["attribute-type"],l);m=Math.max(m,z.width+i);let $=await b2(h,P.name,n,0,d,["attribute-name"],l);g=Math.max(g,$.width+i);let H=await b2(h,P.keys.join(),n,0,d,["attribute-keys"],l);y=Math.max(y,H.width+i);let Q=await b2(h,P.comment,n,0,d,["attribute-comment"],l);v=Math.max(v,Q.width+i),d+=Math.max(z.height,$.height,H.height,Q.height)+a,p.push(d)}p.pop();let w=4;y<=i&&(x=!1,y=0,w--),v<=i&&(b=!1,v=0,w--);let C=h.node().getBBox();if(f.width+i*2-(m+g+y+v)>0){let P=f.width+i*2-(m+g+y+v);m+=P/w,g+=P/w,y>0&&(y+=P/w),v>0&&(v+=P/w)}let T=m+g+y+v,E=Xe.svg(h),A=Ke(e,{});e.look!=="handDrawn"&&(A.roughness=0,A.fillStyle="solid");let S=Math.max(C.width+i*2,e?.width||0,T),_=Math.max(C.height+(p[0]||d)+a,e?.height||0),I=-S/2,D=-_/2;h.selectAll("g:not(:first-child)").each((P,z,$)=>{let H=Ge($[z]),Q=H.attr("transform"),j=0,ie=0;if(Q){let le=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(Q);le&&(j=parseFloat(le[1]),ie=parseFloat(le[2]),H.attr("class").includes("attribute-name")?j+=m:H.attr("class").includes("attribute-keys")?j+=m+g:H.attr("class").includes("attribute-comment")&&(j+=m+g+y))}H.attr("transform",`translate(${I+i/2+j}, ${ie+D+f.height+a/2})`)}),h.select(".name").attr("transform","translate("+-f.width/2+", "+(D+a/2)+")");let k=E.rectangle(I,D,S,_,A),L=h.insert(()=>k,":first-child").attr("style",s.join("")),{themeVariables:R}=cr(),{rowEven:O,rowOdd:M,nodeBorder:B}=R;p.push(0);for(let[P,z]of p.entries()){if(P===0&&p.length>1)continue;let $=P%2===0&&z!==0,H=E.rectangle(I,f.height+D+z,S,f.height,{...A,fill:$?O:M,stroke:B});h.insert(()=>H,"g.label").attr("style",s.join("")).attr("class",`row-rect-${P%2===0?"even":"odd"}`)}let F=E.line(I,f.height+D,S+I,f.height+D,A);h.insert(()=>F).attr("class","divider"),F=E.line(m+I,f.height+D,m+I,_+D,A),h.insert(()=>F).attr("class","divider"),x&&(F=E.line(m+g+I,f.height+D,m+g+I,_+D,A),h.insert(()=>F).attr("class","divider")),b&&(F=E.line(m+g+y+I,f.height+D,m+g+y+I,_+D,A),h.insert(()=>F).attr("class","divider"));for(let P of p)F=E.line(I,f.height+D+P,S+I,f.height+D+P,A),h.insert(()=>F).attr("class","divider");return je(e,L),e.intersect=function(P){return Ye.rect(e,P)},h}async function b2(t,e,r,n=0,i=0,a=[],s=""){let l=t.insert("g").attr("class",`label ${a.join(" ")}`).attr("transform",`translate(${n}, ${i})`).attr("style",s);e!==ec(e)&&(e=ec(e),e=e.replaceAll("<","&lt;").replaceAll(">","&gt;"));let u=l.node().appendChild(await Hn(l,e,{width:ra(e,r)+100,style:s,useHtmlLabels:r.htmlLabels},r));if(e.includes("&lt;")||e.includes("&gt;")){let f=u.children[0];for(f.textContent=f.textContent.replaceAll("&lt;","<").replaceAll("&gt;",">");f.childNodes[0];)f=f.childNodes[0],f.textContent=f.textContent.replaceAll("&lt;","<").replaceAll("&gt;",">")}let h=u.getBBox();if(fr(r.htmlLabels)){let f=u.children[0];f.style.textAlign="start";let d=Ge(u);h=f.getBoundingClientRect(),d.attr("width",h.width),d.attr("height",h.height)}return h}var PZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();mm();ji();to();gr();dr();ir();o(KD,"erBox");o(b2,"addText")});async function BZ(t,e,r,n,i=r.class.padding??12){let a=n?0:3,s=t.insert("g").attr("class",ht(e)).attr("id",e.domId||e.id),l=null,u=null,h=null,f=null,d=0,p=0,m=0;if(l=s.insert("g").attr("class","annotation-group text"),e.annotations.length>0){let b=e.annotations[0];await Vw(l,{text:`\xAB${b}\xBB`},0),d=l.node().getBBox().height}u=s.insert("g").attr("class","label-group text"),await Vw(u,e,0,["font-weight: bolder"]);let g=u.node().getBBox();p=g.height,h=s.insert("g").attr("class","members-group text");let y=0;for(let b of e.members){let w=await Vw(h,b,y,[b.parseClassifier()]);y+=w+a}m=h.node().getBBox().height,m<=0&&(m=i/2),f=s.insert("g").attr("class","methods-group text");let v=0;for(let b of e.methods){let w=await Vw(f,b,v,[b.parseClassifier()]);v+=w+a}let x=s.node().getBBox();if(l!==null){let b=l.node().getBBox();l.attr("transform",`translate(${-b.width/2})`)}return u.attr("transform",`translate(${-g.width/2}, ${d})`),x=s.node().getBBox(),h.attr("transform",`translate(0, ${d+p+i*2})`),x=s.node().getBBox(),f.attr("transform",`translate(0, ${d+p+(m?m+i*4:i*2)})`),x=s.node().getBBox(),{shapeSvg:s,bbox:x}}async function Vw(t,e,r,n=[]){let i=t.insert("g").attr("class","label").attr("style",n.join("; ")),a=cr(),s="useHtmlLabels"in e?e.useHtmlLabels:fr(a.htmlLabels)??!0,l="";"text"in e?l=e.text:l=e.label,!s&&l.startsWith("\\")&&(l=l.substring(1)),pi(l)&&(s=!0);let u=await Hn(i,Xy(na(l)),{width:ra(l,a)+50,classes:"markdown-node-label",useHtmlLabels:s},a),h,f=1;if(s){let d=u.children[0],p=Ge(u);f=d.innerHTML.split("<br>").length,d.innerHTML.includes("</math>")&&(f+=d.innerHTML.split("<mrow>").length-1);let m=d.getElementsByTagName("img");if(m){let g=l.replace(/<img[^>]*>/g,"").trim()==="";await Promise.all([...m].map(y=>new Promise(v=>{function x(){if(y.style.display="flex",y.style.flexDirection="column",g){let b=a.fontSize?.toString()??window.getComputedStyle(document.body).fontSize,C=parseInt(b,10)*5+"px";y.style.minWidth=C,y.style.maxWidth=C}else y.style.width="100%";v(y)}o(x,"setupImage"),setTimeout(()=>{y.complete&&x()}),y.addEventListener("error",x),y.addEventListener("load",x)})))}h=d.getBoundingClientRect(),p.attr("width",h.width),p.attr("height",h.height)}else{n.includes("font-weight: bolder")&&Ge(u).selectAll("tspan").attr("font-weight",""),f=u.children.length;let d=u.children[0];(u.textContent===""||u.textContent.includes("&gt"))&&(d.textContent=l[0]+l.substring(1).replaceAll("&gt;",">").replaceAll("&lt;","<").trim(),l[1]===" "&&(d.textContent=d.textContent[0]+" "+d.textContent.substring(1))),d.textContent==="undefined"&&(d.textContent=""),h=u.getBBox()}return i.attr("transform","translate(0,"+(-h.height/(2*f)+r)+")"),h.height}var FZ=N(()=>{"use strict";dr();ji();Ft();ir();zt();to();gr();o(BZ,"textHelper");o(Vw,"addText")});async function $Z(t,e){let r=me(),n=r.class.padding??12,i=n,a=e.useHtmlLabels??fr(r.htmlLabels)??!0,s=e;s.annotations=s.annotations??[],s.members=s.members??[],s.methods=s.methods??[];let{shapeSvg:l,bbox:u}=await BZ(t,e,r,a,i),{labelStyles:h,nodeStyles:f}=Qe(e);e.labelStyle=h,e.cssStyles=s.styles||"";let d=s.styles?.join(";")||f||"";e.cssStyles||(e.cssStyles=d.replaceAll("!important","").split(";"));let p=s.members.length===0&&s.methods.length===0&&!r.class?.hideEmptyMembersBox,m=Xe.svg(l),g=Ke(e,{});e.look!=="handDrawn"&&(g.roughness=0,g.fillStyle="solid");let y=u.width,v=u.height;s.members.length===0&&s.methods.length===0?v+=i:s.members.length>0&&s.methods.length===0&&(v+=i*2);let x=-y/2,b=-v/2,w=m.rectangle(x-n,b-n-(p?n:s.members.length===0&&s.methods.length===0?-n/2:0),y+2*n,v+2*n+(p?n*2:s.members.length===0&&s.methods.length===0?-n:0),g),C=l.insert(()=>w,":first-child");C.attr("class","basic label-container");let T=C.node().getBBox();l.selectAll(".text").each((_,I,D)=>{let k=Ge(D[I]),L=k.attr("transform"),R=0;if(L){let F=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(L);F&&(R=parseFloat(F[2]))}let O=R+b+n-(p?n:s.members.length===0&&s.methods.length===0?-n/2:0);a||(O-=4);let M=x;(k.attr("class").includes("label-group")||k.attr("class").includes("annotation-group"))&&(M=-k.node()?.getBBox().width/2||0,l.selectAll("text").each(function(B,F,P){window.getComputedStyle(P[F]).textAnchor==="middle"&&(M=0)})),k.attr("transform",`translate(${M}, ${O})`)});let E=l.select(".annotation-group").node().getBBox().height-(p?n/2:0)||0,A=l.select(".label-group").node().getBBox().height-(p?n/2:0)||0,S=l.select(".members-group").node().getBBox().height-(p?n/2:0)||0;if(s.members.length>0||s.methods.length>0||p){let _=m.line(T.x,E+A+b+n,T.x+T.width,E+A+b+n,g);l.insert(()=>_).attr("class","divider").attr("style",d)}if(p||s.members.length>0||s.methods.length>0){let _=m.line(T.x,E+A+S+b+i*2+n,T.x+T.width,E+A+S+b+n+i*2,g);l.insert(()=>_).attr("class","divider").attr("style",d)}if(s.look!=="handDrawn"&&l.selectAll("path").attr("style",d),C.select(":nth-child(2)").attr("style",d),l.selectAll(".divider").select("path").attr("style",d),e.labelStyle?l.selectAll("span").attr("style",e.labelStyle):l.selectAll("span").attr("style",d),!a){let _=RegExp(/color\s*:\s*([^;]*)/),I=_.exec(d);if(I){let D=I[0].replace("color","fill");l.selectAll("tspan").attr("style",D)}else if(h){let D=_.exec(h);if(D){let k=D[0].replace("color","fill");l.selectAll("tspan").attr("style",k)}}}return je(e,C),e.intersect=function(_){return Ye.rect(e,_)},l}var zZ=N(()=>{"use strict";Ft();zt();dr();Wt();Ut();Ht();FZ();gr();o($Z,"classBox")});async function GZ(t,e){let{labelStyles:r,nodeStyles:n}=Qe(e);e.labelStyle=r;let i=e,a=e,s=20,l=20,u="verifyMethod"in e,h=ht(e),f=t.insert("g").attr("class",h).attr("id",e.domId??e.id),d;u?d=await Lu(f,`&lt;&lt;${i.type}&gt;&gt;`,0,e.labelStyle):d=await Lu(f,"&lt;&lt;Element&gt;&gt;",0,e.labelStyle);let p=d,m=await Lu(f,i.name,p,e.labelStyle+"; font-weight: bold;");if(p+=m+l,u){let E=await Lu(f,`${i.requirementId?`Id: ${i.requirementId}`:""}`,p,e.labelStyle);p+=E;let A=await Lu(f,`${i.text?`Text: ${i.text}`:""}`,p,e.labelStyle);p+=A;let S=await Lu(f,`${i.risk?`Risk: ${i.risk}`:""}`,p,e.labelStyle);p+=S,await Lu(f,`${i.verifyMethod?`Verification: ${i.verifyMethod}`:""}`,p,e.labelStyle)}else{let E=await Lu(f,`${a.type?`Type: ${a.type}`:""}`,p,e.labelStyle);p+=E,await Lu(f,`${a.docRef?`Doc Ref: ${a.docRef}`:""}`,p,e.labelStyle)}let g=(f.node()?.getBBox().width??200)+s,y=(f.node()?.getBBox().height??200)+s,v=-g/2,x=-y/2,b=Xe.svg(f),w=Ke(e,{});e.look!=="handDrawn"&&(w.roughness=0,w.fillStyle="solid");let C=b.rectangle(v,x,g,y,w),T=f.insert(()=>C,":first-child");if(T.attr("class","basic label-container").attr("style",n),f.selectAll(".label").each((E,A,S)=>{let _=Ge(S[A]),I=_.attr("transform"),D=0,k=0;if(I){let M=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(I);M&&(D=parseFloat(M[1]),k=parseFloat(M[2]))}let L=k-y/2,R=v+s/2;(A===0||A===1)&&(R=D),_.attr("transform",`translate(${R}, ${L+s})`)}),p>d+m+l){let E=b.line(v,x+d+m+l,v+g,x+d+m+l,w);f.insert(()=>E).attr("style",n)}return je(e,T),e.intersect=function(E){return Ye.rect(e,E)},f}async function Lu(t,e,r,n=""){if(e==="")return 0;let i=t.insert("g").attr("class","label").attr("style",n),a=me(),s=a.htmlLabels??!0,l=await Hn(i,Xy(na(e)),{width:ra(e,a)+50,classes:"markdown-node-label",useHtmlLabels:s,style:n},a),u;if(s){let h=l.children[0],f=Ge(l);u=h.getBoundingClientRect(),f.attr("width",u.width),f.attr("height",u.height)}else{let h=l.children[0];for(let f of h.children)f.textContent=f.textContent.replaceAll("&gt;",">").replaceAll("&lt;","<"),n&&f.setAttribute("style",n);u=l.getBBox(),u.height+=6}return i.attr("transform",`translate(${-u.width/2},${-u.height/2+r})`),u.height}var VZ=N(()=>{"use strict";Ft();Ht();Ut();Wt();ir();zt();to();dr();o(GZ,"requirementBox");o(Lu,"addText")});async function UZ(t,e,{config:r}){let{labelStyles:n,nodeStyles:i}=Qe(e);e.labelStyle=n||"";let a=10,s=e.width;e.width=(e.width??200)-10;let{shapeSvg:l,bbox:u,label:h}=await pt(t,e,ht(e)),f=e.padding||10,d="",p;"ticket"in e&&e.ticket&&r?.kanban?.ticketBaseUrl&&(d=r?.kanban?.ticketBaseUrl.replace("#TICKET#",e.ticket),p=l.insert("svg:a",":first-child").attr("class","kanban-ticket-link").attr("xlink:href",d).attr("target","_blank"));let m={useHtmlLabels:e.useHtmlLabels,labelStyle:e.labelStyle||"",width:e.width,img:e.img,padding:e.padding||8,centerLabel:!1},g,y;p?{label:g,bbox:y}=await Dw(p,"ticket"in e&&e.ticket||"",m):{label:g,bbox:y}=await Dw(l,"ticket"in e&&e.ticket||"",m);let{label:v,bbox:x}=await Dw(l,"assigned"in e&&e.assigned||"",m);e.width=s;let b=10,w=e?.width||0,C=Math.max(y.height,x.height)/2,T=Math.max(u.height+b*2,e?.height||0)+C,E=-w/2,A=-T/2;h.attr("transform","translate("+(f-w/2)+", "+(-C-u.height/2)+")"),g.attr("transform","translate("+(f-w/2)+", "+(-C+u.height/2)+")"),v.attr("transform","translate("+(f+w/2-x.width-2*a)+", "+(-C+u.height/2)+")");let S,{rx:_,ry:I}=e,{cssStyles:D}=e;if(e.look==="handDrawn"){let k=Xe.svg(l),L=Ke(e,{}),R=_||I?k.path(Na(E,A,w,T,_||0),L):k.rectangle(E,A,w,T,L);S=l.insert(()=>R,":first-child"),S.attr("class","basic label-container").attr("style",D||null)}else{S=l.insert("rect",":first-child"),S.attr("class","basic label-container __APA__").attr("style",i).attr("rx",_??5).attr("ry",I??5).attr("x",E).attr("y",A).attr("width",w).attr("height",T);let k="priority"in e&&e.priority;if(k){let L=l.append("line"),R=E+2,O=A+Math.floor((_??0)/2),M=A+T-Math.floor((_??0)/2);L.attr("x1",R).attr("y1",O).attr("x2",R).attr("y2",M).attr("stroke-width","4").attr("stroke",k_e(k))}}return je(e,S),e.height=T,e.intersect=function(k){return Ye.rect(e,k)},l}var k_e,HZ=N(()=>{"use strict";Ft();Ht();qh();Ut();Wt();k_e=o(t=>{switch(t){case"Very High":return"red";case"High":return"orange";case"Medium":return null;case"Low":return"blue";case"Very Low":return"lightblue"}},"colorFromPriority");o(UZ,"kanbanItem")});function WZ(t){return t in QD}var E_e,S_e,QD,ZD=N(()=>{"use strict";NK();OK();BK();$K();GK();UK();WK();YK();jK();QK();JK();tQ();nQ();aQ();oQ();cQ();hQ();dQ();mQ();yQ();xQ();wQ();kQ();SQ();AQ();DQ();RQ();MQ();OQ();BQ();$Q();GQ();UQ();WQ();YQ();jQ();QQ();JQ();tZ();nZ();aZ();oZ();cZ();hZ();dZ();mZ();yZ();xZ();wZ();kZ();SZ();AZ();DZ();RZ();MZ();OZ();PZ();zZ();VZ();HZ();E_e=[{semanticName:"Process",name:"Rectangle",shortName:"rect",description:"Standard process shape",aliases:["proc","process","rectangle"],internalAliases:["squareRect"],handler:iZ},{semanticName:"Event",name:"Rounded Rectangle",shortName:"rounded",description:"Represents an event",aliases:["event"],internalAliases:["roundedRect"],handler:ZQ},{semanticName:"Terminal Point",name:"Stadium",shortName:"stadium",description:"Terminal point",aliases:["terminal","pill"],handler:sZ},{semanticName:"Subprocess",name:"Framed Rectangle",shortName:"fr-rect",description:"Subprocess",aliases:["subprocess","subproc","framed-rectangle","subroutine"],handler:pZ},{semanticName:"Database",name:"Cylinder",shortName:"cyl",description:"Database storage",aliases:["db","database","cylinder"],handler:ZK},{semanticName:"Start",name:"Circle",shortName:"circle",description:"Starting point",aliases:["circ"],handler:zK},{semanticName:"Decision",name:"Diamond",shortName:"diam",description:"Decision-making step",aliases:["decision","diamond","question"],handler:qQ},{semanticName:"Prepare Conditional",name:"Hexagon",shortName:"hex",description:"Preparation or condition step",aliases:["hexagon","prepare"],handler:fQ},{semanticName:"Data Input/Output",name:"Lean Right",shortName:"lean-r",description:"Represents input or output",aliases:["lean-right","in-out"],internalAliases:["lean_right"],handler:NQ},{semanticName:"Data Input/Output",name:"Lean Left",shortName:"lean-l",description:"Represents output or input",aliases:["lean-left","out-in"],internalAliases:["lean_left"],handler:LQ},{semanticName:"Priority Action",name:"Trapezoid Base Bottom",shortName:"trap-b",description:"Priority action",aliases:["priority","trapezoid-bottom","trapezoid"],handler:EZ},{semanticName:"Manual Operation",name:"Trapezoid Base Top",shortName:"trap-t",description:"Represents a manual task",aliases:["manual","trapezoid-top","inv-trapezoid"],internalAliases:["inv_trapezoid"],handler:CQ},{semanticName:"Stop",name:"Double Circle",shortName:"dbl-circ",description:"Represents a stop point",aliases:["double-circle"],internalAliases:["doublecircle"],handler:rQ},{semanticName:"Text Block",name:"Text Block",shortName:"text",description:"Text block",handler:bZ},{semanticName:"Card",name:"Notched Rectangle",shortName:"notch-rect",description:"Represents a card",aliases:["card","notched-rectangle"],handler:PK},{semanticName:"Lined/Shaded Process",name:"Lined Rectangle",shortName:"lin-rect",description:"Lined process shape",aliases:["lined-rectangle","lined-process","lin-proc","shaded-process"],handler:eZ},{semanticName:"Start",name:"Small Circle",shortName:"sm-circ",description:"Small starting point",aliases:["start","small-circle"],internalAliases:["stateStart"],handler:fZ},{semanticName:"Stop",name:"Framed Circle",shortName:"fr-circ",description:"Stop point",aliases:["stop","framed-circle"],internalAliases:["stateEnd"],handler:uZ},{semanticName:"Fork/Join",name:"Filled Rectangle",shortName:"fork",description:"Fork or join in process flow",aliases:["join"],internalAliases:["forkJoin"],handler:lQ},{semanticName:"Collate",name:"Hourglass",shortName:"hourglass",description:"Represents a collate operation",aliases:["hourglass","collate"],handler:pQ},{semanticName:"Comment",name:"Curly Brace",shortName:"brace",description:"Adds a comment",aliases:["comment","brace-l"],handler:HK},{semanticName:"Comment Right",name:"Curly Brace",shortName:"brace-r",description:"Adds a comment",handler:qK},{semanticName:"Comment with braces on both sides",name:"Curly Braces",shortName:"braces",description:"Adds a comment",handler:XK},{semanticName:"Com Link",name:"Lightning Bolt",shortName:"bolt",description:"Communication link",aliases:["com-link","lightning-bolt"],handler:IQ},{semanticName:"Document",name:"Document",shortName:"doc",description:"Represents a document",aliases:["doc","document"],handler:LZ},{semanticName:"Delay",name:"Half-Rounded Rectangle",shortName:"delay",description:"Represents a delay",aliases:["half-rounded-rectangle"],handler:uQ},{semanticName:"Direct Access Storage",name:"Horizontal Cylinder",shortName:"h-cyl",description:"Direct access storage",aliases:["das","horizontal-cylinder"],handler:TZ},{semanticName:"Disk Storage",name:"Lined Cylinder",shortName:"lin-cyl",description:"Disk storage",aliases:["disk","lined-cylinder"],handler:PQ},{semanticName:"Display",name:"Curved Trapezoid",shortName:"curv-trap",description:"Represents a display",aliases:["curved-trapezoid","display"],handler:KK},{semanticName:"Divided Process",name:"Divided Rectangle",shortName:"div-rect",description:"Divided process shape",aliases:["div-proc","divided-rectangle","divided-process"],handler:eQ},{semanticName:"Extract",name:"Triangle",shortName:"tri",description:"Extraction process",aliases:["extract","triangle"],handler:_Z},{semanticName:"Internal Storage",name:"Window Pane",shortName:"win-pane",description:"Internal storage",aliases:["internal-storage","window-pane"],handler:IZ},{semanticName:"Junction",name:"Filled Circle",shortName:"f-circ",description:"Junction point",aliases:["junction","filled-circle"],handler:iQ},{semanticName:"Loop Limit",name:"Trapezoidal Pentagon",shortName:"notch-pent",description:"Loop limit step",aliases:["loop-limit","notched-pentagon"],handler:CZ},{semanticName:"Manual File",name:"Flipped Triangle",shortName:"flip-tri",description:"Manual file operation",aliases:["manual-file","flipped-triangle"],handler:sQ},{semanticName:"Manual Input",name:"Sloped Rectangle",shortName:"sl-rect",description:"Manual input step",aliases:["manual-input","sloped-rectangle"],handler:rZ},{semanticName:"Multi-Document",name:"Stacked Document",shortName:"docs",description:"Multiple documents",aliases:["documents","st-doc","stacked-document"],handler:VQ},{semanticName:"Multi-Process",name:"Stacked Rectangle",shortName:"st-rect",description:"Multiple processes",aliases:["procs","processes","stacked-rectangle"],handler:zQ},{semanticName:"Stored Data",name:"Bow Tie Rectangle",shortName:"bow-rect",description:"Stored data",aliases:["stored-data","bow-tie-rectangle"],handler:IK},{semanticName:"Summary",name:"Crossed Circle",shortName:"cross-circ",description:"Summary",aliases:["summary","crossed-circle"],handler:VK},{semanticName:"Tagged Document",name:"Tagged Document",shortName:"tag-doc",description:"Tagged document",aliases:["tag-doc","tagged-document"],handler:vZ},{semanticName:"Tagged Process",name:"Tagged Rectangle",shortName:"tag-rect",description:"Tagged process",aliases:["tagged-rectangle","tag-proc","tagged-process"],handler:gZ},{semanticName:"Paper Tape",name:"Flag",shortName:"flag",description:"Paper tape",aliases:["paper-tape"],handler:NZ},{semanticName:"Odd",name:"Odd",shortName:"odd",description:"Odd shape",internalAliases:["rect_left_inv_arrow"],handler:XQ},{semanticName:"Lined Document",name:"Lined Document",shortName:"lin-doc",description:"Lined document",aliases:["lined-document"],handler:FQ}],S_e=o(()=>{let e=[...Object.entries({state:lZ,choice:FK,note:HQ,rectWithTitle:KQ,labelRect:_Q,iconSquare:TQ,iconCircle:vQ,icon:gQ,iconRounded:bQ,imageSquare:EQ,anchor:RK,kanbanItem:UZ,classBox:$Z,erBox:KD,requirementBox:GZ}),...E_e.flatMap(r=>[r.shortName,..."aliases"in r?r.aliases:[],..."internalAliases"in r?r.internalAliases:[]].map(i=>[i,r.handler]))];return Object.fromEntries(e)},"generateShapeMap"),QD=S_e();o(WZ,"isValidShape")});var C_e,Uw,qZ=N(()=>{"use strict";dr();Ew();zt();vt();ZD();ir();gr();mi();C_e="flowchart-",Uw=class{constructor(){this.vertexCounter=0;this.config=me();this.vertices=new Map;this.edges=[];this.classes=new Map;this.subGraphs=[];this.subGraphLookup=new Map;this.tooltips=new Map;this.subCount=0;this.firstGraphFlag=!0;this.secCount=-1;this.posCrossRef=[];this.funs=[];this.setAccTitle=Lr;this.setAccDescription=Nr;this.setDiagramTitle=$r;this.getAccTitle=Rr;this.getAccDescription=Mr;this.getDiagramTitle=Ir;this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}static{o(this,"FlowDB")}sanitizeText(e){return Ze.sanitizeText(e,this.config)}lookUpDomId(e){for(let r of this.vertices.values())if(r.id===e)return r.domId;return e}addVertex(e,r,n,i,a,s,l={},u){if(!e||e.trim().length===0)return;let h;if(u!==void 0){let m;u.includes(`
+`)?m=u+`
+`:m=`{
+`+u+`
+}`,h=cm(m,{schema:lm})}let f=this.edges.find(m=>m.id===e);if(f){let m=h;m?.animate!==void 0&&(f.animate=m.animate),m?.animation!==void 0&&(f.animation=m.animation);return}let d,p=this.vertices.get(e);if(p===void 0&&(p={id:e,labelType:"text",domId:C_e+e+"-"+this.vertexCounter,styles:[],classes:[]},this.vertices.set(e,p)),this.vertexCounter++,r!==void 0?(this.config=me(),d=this.sanitizeText(r.text.trim()),p.labelType=r.type,d.startsWith('"')&&d.endsWith('"')&&(d=d.substring(1,d.length-1)),p.text=d):p.text===void 0&&(p.text=e),n!==void 0&&(p.type=n),i?.forEach(m=>{p.styles.push(m)}),a?.forEach(m=>{p.classes.push(m)}),s!==void 0&&(p.dir=s),p.props===void 0?p.props=l:l!==void 0&&Object.assign(p.props,l),h!==void 0){if(h.shape){if(h.shape!==h.shape.toLowerCase()||h.shape.includes("_"))throw new Error(`No such shape: ${h.shape}. Shape names should be lowercase.`);if(!WZ(h.shape))throw new Error(`No such shape: ${h.shape}.`);p.type=h?.shape}h?.label&&(p.text=h?.label),h?.icon&&(p.icon=h?.icon,!h.label?.trim()&&p.text===e&&(p.text="")),h?.form&&(p.form=h?.form),h?.pos&&(p.pos=h?.pos),h?.img&&(p.img=h?.img,!h.label?.trim()&&p.text===e&&(p.text="")),h?.constraint&&(p.constraint=h.constraint),h.w&&(p.assetWidth=Number(h.w)),h.h&&(p.assetHeight=Number(h.h))}}addSingleLink(e,r,n,i){let l={start:e,end:r,type:void 0,text:"",labelType:"text",classes:[],isUserDefinedId:!1,interpolate:this.edges.defaultInterpolate};Y.info("abc78 Got edge...",l);let u=n.text;if(u!==void 0&&(l.text=this.sanitizeText(u.text.trim()),l.text.startsWith('"')&&l.text.endsWith('"')&&(l.text=l.text.substring(1,l.text.length-1)),l.labelType=u.type),n!==void 0&&(l.type=n.type,l.stroke=n.stroke,l.length=n.length>10?10:n.length),i&&!this.edges.some(h=>h.id===i))l.id=i,l.isUserDefinedId=!0;else{let h=this.edges.filter(f=>f.start===l.start&&f.end===l.end);h.length===0?l.id=$h(l.start,l.end,{counter:0,prefix:"L"}):l.id=$h(l.start,l.end,{counter:h.length+1,prefix:"L"})}if(this.edges.length<(this.config.maxEdges??500))Y.info("Pushing edge..."),this.edges.push(l);else throw new Error(`Edge limit exceeded. ${this.edges.length} edges found, but the limit is ${this.config.maxEdges}.
+
+Initialize mermaid with maxEdges set to a higher number to allow more edges.
+You cannot set this config via configuration inside the diagram as it is a secure config.
+You have to call mermaid.initialize.`)}isLinkData(e){return e!==null&&typeof e=="object"&&"id"in e&&typeof e.id=="string"}addLink(e,r,n){let i=this.isLinkData(n)?n.id.replace("@",""):void 0;Y.info("addLink",e,r,i);for(let a of e)for(let s of r){let l=a===e[e.length-1],u=s===r[0];l&&u?this.addSingleLink(a,s,n,i):this.addSingleLink(a,s,n,void 0)}}updateLinkInterpolate(e,r){e.forEach(n=>{n==="default"?this.edges.defaultInterpolate=r:this.edges[n].interpolate=r})}updateLink(e,r){e.forEach(n=>{if(typeof n=="number"&&n>=this.edges.length)throw new Error(`The index ${n} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${this.edges.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);n==="default"?this.edges.defaultStyle=r:(this.edges[n].style=r,(this.edges[n]?.style?.length??0)>0&&!this.edges[n]?.style?.some(i=>i?.startsWith("fill"))&&this.edges[n]?.style?.push("fill:none"))})}addClass(e,r){let n=r.join().replace(/\\,/g,"\xA7\xA7\xA7").replace(/,/g,";").replace(/§§§/g,",").split(";");e.split(",").forEach(i=>{let a=this.classes.get(i);a===void 0&&(a={id:i,styles:[],textStyles:[]},this.classes.set(i,a)),n?.forEach(s=>{if(/color/.exec(s)){let l=s.replace("fill","bgFill");a.textStyles.push(l)}a.styles.push(s)})})}setDirection(e){this.direction=e,/.*</.exec(this.direction)&&(this.direction="RL"),/.*\^/.exec(this.direction)&&(this.direction="BT"),/.*>/.exec(this.direction)&&(this.direction="LR"),/.*v/.exec(this.direction)&&(this.direction="TB"),this.direction==="TD"&&(this.direction="TB")}setClass(e,r){for(let n of e.split(",")){let i=this.vertices.get(n);i&&i.classes.push(r);let a=this.edges.find(l=>l.id===n);a&&a.classes.push(r);let s=this.subGraphLookup.get(n);s&&s.classes.push(r)}}setTooltip(e,r){if(r!==void 0){r=this.sanitizeText(r);for(let n of e.split(","))this.tooltips.set(this.version==="gen-1"?this.lookUpDomId(n):n,r)}}setClickFun(e,r,n){let i=this.lookUpDomId(e);if(me().securityLevel!=="loose"||r===void 0)return;let a=[];if(typeof n=="string"){a=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let l=0;l<a.length;l++){let u=a[l].trim();u.startsWith('"')&&u.endsWith('"')&&(u=u.substr(1,u.length-2)),a[l]=u}}a.length===0&&a.push(e);let s=this.vertices.get(e);s&&(s.haveCallback=!0,this.funs.push(()=>{let l=document.querySelector(`[id="${i}"]`);l!==null&&l.addEventListener("click",()=>{Gt.runFunc(r,...a)},!1)}))}setLink(e,r,n){e.split(",").forEach(i=>{let a=this.vertices.get(i);a!==void 0&&(a.link=Gt.formatUrl(r,this.config),a.linkTarget=n)}),this.setClass(e,"clickable")}getTooltip(e){return this.tooltips.get(e)}setClickEvent(e,r,n){e.split(",").forEach(i=>{this.setClickFun(i,r,n)}),this.setClass(e,"clickable")}bindFunctions(e){this.funs.forEach(r=>{r(e)})}getDirection(){return this.direction?.trim()}getVertices(){return this.vertices}getEdges(){return this.edges}getClasses(){return this.classes}setupToolTips(e){let r=Ge(".mermaidTooltip");(r._groups||r)[0][0]===null&&(r=Ge("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Ge(e).select("svg").selectAll("g.node").on("mouseover",a=>{let s=Ge(a.currentTarget);if(s.attr("title")===null)return;let u=a.currentTarget?.getBoundingClientRect();r.transition().duration(200).style("opacity",".9"),r.text(s.attr("title")).style("left",window.scrollX+u.left+(u.right-u.left)/2+"px").style("top",window.scrollY+u.bottom+"px"),r.html(r.html().replace(/&lt;br\/&gt;/g,"<br/>")),s.classed("hover",!0)}).on("mouseout",a=>{r.transition().duration(500).style("opacity",0),Ge(a.currentTarget).classed("hover",!1)})}clear(e="gen-2"){this.vertices=new Map,this.classes=new Map,this.edges=[],this.funs=[this.setupToolTips.bind(this)],this.subGraphs=[],this.subGraphLookup=new Map,this.subCount=0,this.tooltips=new Map,this.firstGraphFlag=!0,this.version=e,this.config=me(),Ar()}setGen(e){this.version=e||"gen-2"}defaultStyle(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"}addSubGraph(e,r,n){let i=e.text.trim(),a=n.text;e===n&&/\s/.exec(n.text)&&(i=void 0);let s=o(f=>{let d={boolean:{},number:{},string:{}},p=[],m;return{nodeList:f.filter(function(y){let v=typeof y;return y.stmt&&y.stmt==="dir"?(m=y.value,!1):y.trim()===""?!1:v in d?d[v].hasOwnProperty(y)?!1:d[v][y]=!0:p.includes(y)?!1:p.push(y)}),dir:m}},"uniq"),{nodeList:l,dir:u}=s(r.flat());if(this.version==="gen-1")for(let f=0;f<l.length;f++)l[f]=this.lookUpDomId(l[f]);i=i??"subGraph"+this.subCount,a=a||"",a=this.sanitizeText(a),this.subCount=this.subCount+1;let h={id:i,nodes:l,title:a.trim(),classes:[],dir:u,labelType:n.type};return Y.info("Adding",h.id,h.nodes,h.dir),h.nodes=this.makeUniq(h,this.subGraphs).nodes,this.subGraphs.push(h),this.subGraphLookup.set(i,h),i}getPosForId(e){for(let[r,n]of this.subGraphs.entries())if(n.id===e)return r;return-1}indexNodes2(e,r){let n=this.subGraphs[r].nodes;if(this.secCount=this.secCount+1,this.secCount>2e3)return{result:!1,count:0};if(this.posCrossRef[this.secCount]=r,this.subGraphs[r].id===e)return{result:!0,count:0};let i=0,a=1;for(;i<n.length;){let s=this.getPosForId(n[i]);if(s>=0){let l=this.indexNodes2(e,s);if(l.result)return{result:!0,count:a+l.count};a=a+l.count}i=i+1}return{result:!1,count:a}}getDepthFirstPos(e){return this.posCrossRef[e]}indexNodes(){this.secCount=-1,this.subGraphs.length>0&&this.indexNodes2("none",this.subGraphs.length-1)}getSubGraphs(){return this.subGraphs}firstGraph(){return this.firstGraphFlag?(this.firstGraphFlag=!1,!0):!1}destructStartLink(e){let r=e.trim(),n="arrow_open";switch(r[0]){case"<":n="arrow_point",r=r.slice(1);break;case"x":n="arrow_cross",r=r.slice(1);break;case"o":n="arrow_circle",r=r.slice(1);break}let i="normal";return r.includes("=")&&(i="thick"),r.includes(".")&&(i="dotted"),{type:n,stroke:i}}countChar(e,r){let n=r.length,i=0;for(let a=0;a<n;++a)r[a]===e&&++i;return i}destructEndLink(e){let r=e.trim(),n=r.slice(0,-1),i="arrow_open";switch(r.slice(-1)){case"x":i="arrow_cross",r.startsWith("x")&&(i="double_"+i,n=n.slice(1));break;case">":i="arrow_point",r.startsWith("<")&&(i="double_"+i,n=n.slice(1));break;case"o":i="arrow_circle",r.startsWith("o")&&(i="double_"+i,n=n.slice(1));break}let a="normal",s=n.length-1;n.startsWith("=")&&(a="thick"),n.startsWith("~")&&(a="invisible");let l=this.countChar(".",n);return l&&(a="dotted",s=l),{type:i,stroke:a,length:s}}destructLink(e,r){let n=this.destructEndLink(e),i;if(r){if(i=this.destructStartLink(r),i.stroke!==n.stroke)return{type:"INVALID",stroke:"INVALID"};if(i.type==="arrow_open")i.type=n.type;else{if(i.type!==n.type)return{type:"INVALID",stroke:"INVALID"};i.type="double_"+i.type}return i.type==="double_arrow"&&(i.type="double_arrow_point"),i.length=n.length,i}return n}exists(e,r){for(let n of e)if(n.nodes.includes(r))return!0;return!1}makeUniq(e,r){let n=[];return e.nodes.forEach((i,a)=>{this.exists(r,i)||n.push(e.nodes[a])}),{nodes:n}}getTypeFromVertex(e){if(e.img)return"imageSquare";if(e.icon)return e.form==="circle"?"iconCircle":e.form==="square"?"iconSquare":e.form==="rounded"?"iconRounded":"icon";switch(e.type){case"square":case void 0:return"squareRect";case"round":return"roundedRect";case"ellipse":return"ellipse";default:return e.type}}findNode(e,r){return e.find(n=>n.id===r)}destructEdgeType(e){let r="none",n="arrow_point";switch(e){case"arrow_point":case"arrow_circle":case"arrow_cross":n=e;break;case"double_arrow_point":case"double_arrow_circle":case"double_arrow_cross":r=e.replace("double_",""),n=r;break}return{arrowTypeStart:r,arrowTypeEnd:n}}addNodeFromVertex(e,r,n,i,a,s){let l=n.get(e.id),u=i.get(e.id)??!1,h=this.findNode(r,e.id);if(h)h.cssStyles=e.styles,h.cssCompiledStyles=this.getCompiledStyles(e.classes),h.cssClasses=e.classes.join(" ");else{let f={id:e.id,label:e.text,labelStyle:"",parentId:l,padding:a.flowchart?.padding||8,cssStyles:e.styles,cssCompiledStyles:this.getCompiledStyles(["default","node",...e.classes]),cssClasses:"default "+e.classes.join(" "),dir:e.dir,domId:e.domId,look:s,link:e.link,linkTarget:e.linkTarget,tooltip:this.getTooltip(e.id),icon:e.icon,pos:e.pos,img:e.img,assetWidth:e.assetWidth,assetHeight:e.assetHeight,constraint:e.constraint};u?r.push({...f,isGroup:!0,shape:"rect"}):r.push({...f,isGroup:!1,shape:this.getTypeFromVertex(e)})}}getCompiledStyles(e){let r=[];for(let n of e){let i=this.classes.get(n);i?.styles&&(r=[...r,...i.styles??[]].map(a=>a.trim())),i?.textStyles&&(r=[...r,...i.textStyles??[]].map(a=>a.trim()))}return r}getData(){let e=me(),r=[],n=[],i=this.getSubGraphs(),a=new Map,s=new Map;for(let h=i.length-1;h>=0;h--){let f=i[h];f.nodes.length>0&&s.set(f.id,!0);for(let d of f.nodes)a.set(d,f.id)}for(let h=i.length-1;h>=0;h--){let f=i[h];r.push({id:f.id,label:f.title,labelStyle:"",parentId:a.get(f.id),padding:8,cssCompiledStyles:this.getCompiledStyles(f.classes),cssClasses:f.classes.join(" "),shape:"rect",dir:f.dir,isGroup:!0,look:e.look})}this.getVertices().forEach(h=>{this.addNodeFromVertex(h,r,a,s,e,e.look||"classic")});let u=this.getEdges();return u.forEach((h,f)=>{let{arrowTypeStart:d,arrowTypeEnd:p}=this.destructEdgeType(h.type),m=[...u.defaultStyle??[]];h.style&&m.push(...h.style);let g={id:$h(h.start,h.end,{counter:f,prefix:"L"},h.id),isUserDefinedId:h.isUserDefinedId,start:h.start,end:h.end,type:h.type??"normal",label:h.text,labelpos:"c",thickness:h.stroke,minlen:h.length,classes:h?.stroke==="invisible"?"":"edge-thickness-normal edge-pattern-solid flowchart-link",arrowTypeStart:h?.stroke==="invisible"||h?.type==="arrow_open"?"none":d,arrowTypeEnd:h?.stroke==="invisible"||h?.type==="arrow_open"?"none":p,arrowheadStyle:"fill: #333",cssCompiledStyles:this.getCompiledStyles(h.classes),labelStyle:m,style:m,pattern:h.stroke,look:e.look,animate:h.animate,animation:h.animation,curve:h.interpolate||this.edges.defaultInterpolate||e.flowchart?.curve};n.push(g)}),{nodes:r,edges:n,other:{},config:e}}defaultConfig(){return A3.flowchart}}});var yc,gm=N(()=>{"use strict";dr();yc=o((t,e)=>{let r;return e==="sandbox"&&(r=Ge("#i"+t)),(e==="sandbox"?Ge(r.nodes()[0].contentDocument.body):Ge("body")).select(`[id="${t}"]`)},"getDiagramElement")});var Ru,w2=N(()=>{"use strict";Ru=o(({flowchart:t})=>{let e=t?.subGraphTitleMargin?.top??0,r=t?.subGraphTitleMargin?.bottom??0,n=e+r;return{subGraphTitleTopMargin:e,subGraphTitleBottomMargin:r,subGraphTitleTotalMargin:n}},"getSubGraphTitleMargins")});var YZ,A_e,__e,D_e,L_e,R_e,N_e,XZ,ym,jZ,Hw=N(()=>{"use strict";zt();gr();vt();w2();dr();Wt();to();RD();Gw();qh();Ut();YZ=o(async(t,e)=>{Y.info("Creating subgraph rect for ",e.id,e);let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{clusterBkg:a,clusterBorder:s}=n,{labelStyles:l,nodeStyles:u,borderStyles:h,backgroundStyles:f}=Qe(e),d=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),p=fr(r.flowchart.htmlLabels),m=d.insert("g").attr("class","cluster-label "),g=await Hn(m,e.label,{style:e.labelStyle,useHtmlLabels:p,isNode:!0}),y=g.getBBox();if(fr(r.flowchart.htmlLabels)){let A=g.children[0],S=Ge(g);y=A.getBoundingClientRect(),S.attr("width",y.width),S.attr("height",y.height)}let v=e.width<=y.width+e.padding?y.width+e.padding:e.width;e.width<=y.width+e.padding?e.diff=(v-e.width)/2-e.padding:e.diff=-e.padding;let x=e.height,b=e.x-v/2,w=e.y-x/2;Y.trace("Data ",e,JSON.stringify(e));let C;if(e.look==="handDrawn"){let A=Xe.svg(d),S=Ke(e,{roughness:.7,fill:a,stroke:s,fillWeight:3,seed:i}),_=A.path(Na(b,w,v,x,0),S);C=d.insert(()=>(Y.debug("Rough node insert CXC",_),_),":first-child"),C.select("path:nth-child(2)").attr("style",h.join(";")),C.select("path").attr("style",f.join(";").replace("fill","stroke"))}else C=d.insert("rect",":first-child"),C.attr("style",u).attr("rx",e.rx).attr("ry",e.ry).attr("x",b).attr("y",w).attr("width",v).attr("height",x);let{subGraphTitleTopMargin:T}=Ru(r);if(m.attr("transform",`translate(${e.x-y.width/2}, ${e.y-e.height/2+T})`),l){let A=m.select("span");A&&A.attr("style",l)}let E=C.node().getBBox();return e.offsetX=0,e.width=E.width,e.height=E.height,e.offsetY=y.height-e.padding/2,e.intersect=function(A){return Vh(e,A)},{cluster:d,labelBBox:y}},"rect"),A_e=o((t,e)=>{let r=t.insert("g").attr("class","note-cluster").attr("id",e.id),n=r.insert("rect",":first-child"),i=0*e.padding,a=i/2;n.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+i).attr("height",e.height+i).attr("fill","none");let s=n.node().getBBox();return e.width=s.width,e.height=s.height,e.intersect=function(l){return Vh(e,l)},{cluster:r,labelBBox:{width:0,height:0}}},"noteGroup"),__e=o(async(t,e)=>{let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{altBackground:a,compositeBackground:s,compositeTitleBackground:l,nodeBorder:u}=n,h=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-id",e.id).attr("data-look",e.look),f=h.insert("g",":first-child"),d=h.insert("g").attr("class","cluster-label"),p=h.append("rect"),m=d.node().appendChild(await gc(e.label,e.labelStyle,void 0,!0)),g=m.getBBox();if(fr(r.flowchart.htmlLabels)){let _=m.children[0],I=Ge(m);g=_.getBoundingClientRect(),I.attr("width",g.width),I.attr("height",g.height)}let y=0*e.padding,v=y/2,x=(e.width<=g.width+e.padding?g.width+e.padding:e.width)+y;e.width<=g.width+e.padding?e.diff=(x-e.width)/2-e.padding:e.diff=-e.padding;let b=e.height+y,w=e.height+y-g.height-6,C=e.x-x/2,T=e.y-b/2;e.width=x;let E=e.y-e.height/2-v+g.height+2,A;if(e.look==="handDrawn"){let _=e.cssClasses.includes("statediagram-cluster-alt"),I=Xe.svg(h),D=e.rx||e.ry?I.path(Na(C,T,x,b,10),{roughness:.7,fill:l,fillStyle:"solid",stroke:u,seed:i}):I.rectangle(C,T,x,b,{seed:i});A=h.insert(()=>D,":first-child");let k=I.rectangle(C,E,x,w,{fill:_?a:s,fillStyle:_?"hachure":"solid",stroke:u,seed:i});A=h.insert(()=>D,":first-child"),p=h.insert(()=>k)}else A=f.insert("rect",":first-child"),A.attr("class","outer").attr("x",C).attr("y",T).attr("width",x).attr("height",b).attr("data-look",e.look),p.attr("class","inner").attr("x",C).attr("y",E).attr("width",x).attr("height",w);d.attr("transform",`translate(${e.x-g.width/2}, ${T+1-(fr(r.flowchart.htmlLabels)?0:3)})`);let S=A.node().getBBox();return e.height=S.height,e.offsetX=0,e.offsetY=g.height-e.padding/2,e.labelBBox=g,e.intersect=function(_){return Vh(e,_)},{cluster:h,labelBBox:g}},"roundedWithTitle"),D_e=o(async(t,e)=>{Y.info("Creating subgraph rect for ",e.id,e);let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{clusterBkg:a,clusterBorder:s}=n,{labelStyles:l,nodeStyles:u,borderStyles:h,backgroundStyles:f}=Qe(e),d=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),p=fr(r.flowchart.htmlLabels),m=d.insert("g").attr("class","cluster-label "),g=await Hn(m,e.label,{style:e.labelStyle,useHtmlLabels:p,isNode:!0,width:e.width}),y=g.getBBox();if(fr(r.flowchart.htmlLabels)){let A=g.children[0],S=Ge(g);y=A.getBoundingClientRect(),S.attr("width",y.width),S.attr("height",y.height)}let v=e.width<=y.width+e.padding?y.width+e.padding:e.width;e.width<=y.width+e.padding?e.diff=(v-e.width)/2-e.padding:e.diff=-e.padding;let x=e.height,b=e.x-v/2,w=e.y-x/2;Y.trace("Data ",e,JSON.stringify(e));let C;if(e.look==="handDrawn"){let A=Xe.svg(d),S=Ke(e,{roughness:.7,fill:a,stroke:s,fillWeight:4,seed:i}),_=A.path(Na(b,w,v,x,e.rx),S);C=d.insert(()=>(Y.debug("Rough node insert CXC",_),_),":first-child"),C.select("path:nth-child(2)").attr("style",h.join(";")),C.select("path").attr("style",f.join(";").replace("fill","stroke"))}else C=d.insert("rect",":first-child"),C.attr("style",u).attr("rx",e.rx).attr("ry",e.ry).attr("x",b).attr("y",w).attr("width",v).attr("height",x);let{subGraphTitleTopMargin:T}=Ru(r);if(m.attr("transform",`translate(${e.x-y.width/2}, ${e.y-e.height/2+T})`),l){let A=m.select("span");A&&A.attr("style",l)}let E=C.node().getBBox();return e.offsetX=0,e.width=E.width,e.height=E.height,e.offsetY=y.height-e.padding/2,e.intersect=function(A){return Vh(e,A)},{cluster:d,labelBBox:y}},"kanbanSection"),L_e=o((t,e)=>{let r=me(),{themeVariables:n,handDrawnSeed:i}=r,{nodeBorder:a}=n,s=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-look",e.look),l=s.insert("g",":first-child"),u=0*e.padding,h=e.width+u;e.diff=-e.padding;let f=e.height+u,d=e.x-h/2,p=e.y-f/2;e.width=h;let m;if(e.look==="handDrawn"){let v=Xe.svg(s).rectangle(d,p,h,f,{fill:"lightgrey",roughness:.5,strokeLineDash:[5],stroke:a,seed:i});m=s.insert(()=>v,":first-child")}else m=l.insert("rect",":first-child"),m.attr("class","divider").attr("x",d).attr("y",p).attr("width",h).attr("height",f).attr("data-look",e.look);let g=m.node().getBBox();return e.height=g.height,e.offsetX=0,e.offsetY=0,e.intersect=function(y){return Vh(e,y)},{cluster:s,labelBBox:{}}},"divider"),R_e=YZ,N_e={rect:YZ,squareRect:R_e,roundedWithTitle:__e,noteGroup:A_e,divider:L_e,kanbanSection:D_e},XZ=new Map,ym=o(async(t,e)=>{let r=e.shape||"rect",n=await N_e[r](t,e);return XZ.set(e.id,n),n},"insertCluster"),jZ=o(()=>{XZ=new Map},"clear")});function Ww(t,e){if(t===void 0||e===void 0)return{angle:0,deltaX:0,deltaY:0};t=Wn(t),e=Wn(e);let[r,n]=[t.x,t.y],[i,a]=[e.x,e.y],s=i-r,l=a-n;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}var $o,Wn,qw,JD=N(()=>{"use strict";$o={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:4};o(Ww,"calculateDeltaAndAngle");Wn=o(t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,"pointTransformer"),qw=o(t=>({x:o(function(e,r,n){let i=0,a=Wn(n[0]).x<Wn(n[n.length-1]).x?"left":"right";if(r===0&&Object.hasOwn($o,t.arrowTypeStart)){let{angle:m,deltaX:g}=Ww(n[0],n[1]);i=$o[t.arrowTypeStart]*Math.cos(m)*(g>=0?1:-1)}else if(r===n.length-1&&Object.hasOwn($o,t.arrowTypeEnd)){let{angle:m,deltaX:g}=Ww(n[n.length-1],n[n.length-2]);i=$o[t.arrowTypeEnd]*Math.cos(m)*(g>=0?1:-1)}let s=Math.abs(Wn(e).x-Wn(n[n.length-1]).x),l=Math.abs(Wn(e).y-Wn(n[n.length-1]).y),u=Math.abs(Wn(e).x-Wn(n[0]).x),h=Math.abs(Wn(e).y-Wn(n[0]).y),f=$o[t.arrowTypeStart],d=$o[t.arrowTypeEnd],p=1;if(s<d&&s>0&&l<d){let m=d+p-s;m*=a==="right"?-1:1,i-=m}if(u<f&&u>0&&h<f){let m=f+p-u;m*=a==="right"?-1:1,i+=m}return Wn(e).x+i},"x"),y:o(function(e,r,n){let i=0,a=Wn(n[0]).y<Wn(n[n.length-1]).y?"down":"up";if(r===0&&Object.hasOwn($o,t.arrowTypeStart)){let{angle:m,deltaY:g}=Ww(n[0],n[1]);i=$o[t.arrowTypeStart]*Math.abs(Math.sin(m))*(g>=0?1:-1)}else if(r===n.length-1&&Object.hasOwn($o,t.arrowTypeEnd)){let{angle:m,deltaY:g}=Ww(n[n.length-1],n[n.length-2]);i=$o[t.arrowTypeEnd]*Math.abs(Math.sin(m))*(g>=0?1:-1)}let s=Math.abs(Wn(e).y-Wn(n[n.length-1]).y),l=Math.abs(Wn(e).x-Wn(n[n.length-1]).x),u=Math.abs(Wn(e).y-Wn(n[0]).y),h=Math.abs(Wn(e).x-Wn(n[0]).x),f=$o[t.arrowTypeStart],d=$o[t.arrowTypeEnd],p=1;if(s<d&&s>0&&l<d){let m=d+p-s;m*=a==="up"?-1:1,i-=m}if(u<f&&u>0&&h<f){let m=f+p-u;m*=a==="up"?-1:1,i+=m}return Wn(e).y+i},"y")}),"getLineFunctionsWithOffset")});var QZ,M_e,KZ,ZZ=N(()=>{"use strict";vt();QZ=o((t,e,r,n,i,a)=>{e.arrowTypeStart&&KZ(t,"start",e.arrowTypeStart,r,n,i,a),e.arrowTypeEnd&&KZ(t,"end",e.arrowTypeEnd,r,n,i,a)},"addEdgeMarkers"),M_e={arrow_cross:{type:"cross",fill:!1},arrow_point:{type:"point",fill:!0},arrow_barb:{type:"barb",fill:!0},arrow_circle:{type:"circle",fill:!1},aggregation:{type:"aggregation",fill:!1},extension:{type:"extension",fill:!1},composition:{type:"composition",fill:!0},dependency:{type:"dependency",fill:!0},lollipop:{type:"lollipop",fill:!1},only_one:{type:"onlyOne",fill:!1},zero_or_one:{type:"zeroOrOne",fill:!1},one_or_more:{type:"oneOrMore",fill:!1},zero_or_more:{type:"zeroOrMore",fill:!1},requirement_arrow:{type:"requirement_arrow",fill:!1},requirement_contains:{type:"requirement_contains",fill:!1}},KZ=o((t,e,r,n,i,a,s)=>{let l=M_e[r];if(!l){Y.warn(`Unknown arrow type: ${r}`);return}let u=l.type,f=`${i}_${a}-${u}${e==="start"?"Start":"End"}`;if(s&&s.trim()!==""){let d=s.replace(/[^\dA-Za-z]/g,"_"),p=`${f}_${d}`;if(!document.getElementById(p)){let m=document.getElementById(f);if(m){let g=m.cloneNode(!0);g.id=p,g.querySelectorAll("path, circle, line").forEach(v=>{v.setAttribute("stroke",s),l.fill&&v.setAttribute("fill",s)}),m.parentNode?.appendChild(g)}}t.attr(`marker-${e}`,`url(${n}#${p})`)}else t.attr(`marker-${e}`,`url(${n}#${f})`)},"addEdgeMarker")});function Yw(t,e){me().flowchart.htmlLabels&&t&&(t.style.width=e.length*9+"px",t.style.height="12px")}function P_e(t){let e=[],r=[];for(let n=1;n<t.length-1;n++){let i=t[n-1],a=t[n],s=t[n+1];(i.x===a.x&&a.y===s.y&&Math.abs(a.x-s.x)>5&&Math.abs(a.y-i.y)>5||i.y===a.y&&a.x===s.x&&Math.abs(a.x-i.x)>5&&Math.abs(a.y-s.y)>5)&&(e.push(a),r.push(n))}return{cornerPoints:e,cornerPointPositions:r}}var Xw,pa,tJ,T2,jw,Kw,I_e,O_e,JZ,eJ,B_e,Qw,eL=N(()=>{"use strict";zt();gr();vt();to();ir();JD();w2();dr();Wt();Gw();ZZ();Ut();Xw=new Map,pa=new Map,tJ=o(()=>{Xw.clear(),pa.clear()},"clear"),T2=o(t=>t?t.reduce((r,n)=>r+";"+n,""):"","getLabelStyles"),jw=o(async(t,e)=>{let r=fr(me().flowchart.htmlLabels),n=await Hn(t,e.label,{style:T2(e.labelStyle),useHtmlLabels:r,addSvgBackground:!0,isNode:!1});Y.info("abc82",e,e.labelType);let i=t.insert("g").attr("class","edgeLabel"),a=i.insert("g").attr("class","label");a.node().appendChild(n);let s=n.getBBox();if(r){let u=n.children[0],h=Ge(n);s=u.getBoundingClientRect(),h.attr("width",s.width),h.attr("height",s.height)}a.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),Xw.set(e.id,i),e.width=s.width,e.height=s.height;let l;if(e.startLabelLeft){let u=await gc(e.startLabelLeft,T2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),pa.get(e.id)||pa.set(e.id,{}),pa.get(e.id).startLeft=h,Yw(l,e.startLabelLeft)}if(e.startLabelRight){let u=await gc(e.startLabelRight,T2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=h.node().appendChild(u),f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),pa.get(e.id)||pa.set(e.id,{}),pa.get(e.id).startRight=h,Yw(l,e.startLabelRight)}if(e.endLabelLeft){let u=await gc(e.endLabelLeft,T2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),h.node().appendChild(u),pa.get(e.id)||pa.set(e.id,{}),pa.get(e.id).endLeft=h,Yw(l,e.endLabelLeft)}if(e.endLabelRight){let u=await gc(e.endLabelRight,T2(e.labelStyle)),h=t.insert("g").attr("class","edgeTerminals"),f=h.insert("g").attr("class","inner");l=f.node().appendChild(u);let d=u.getBBox();f.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),h.node().appendChild(u),pa.get(e.id)||pa.set(e.id,{}),pa.get(e.id).endRight=h,Yw(l,e.endLabelRight)}return n},"insertEdgeLabel");o(Yw,"setTerminalWidth");Kw=o((t,e)=>{Y.debug("Moving label abc88 ",t.id,t.label,Xw.get(t.id),e);let r=e.updatedPath?e.updatedPath:e.originalPath,n=me(),{subGraphTitleTotalMargin:i}=Ru(n);if(t.label){let a=Xw.get(t.id),s=t.x,l=t.y;if(r){let u=Gt.calcLabelPosition(r);Y.debug("Moving label "+t.label+" from (",s,",",l,") to (",u.x,",",u.y,") abc88"),e.updatedPath&&(s=u.x,l=u.y)}a.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){let a=pa.get(t.id).startLeft,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.startLabelRight){let a=pa.get(t.id).startRight,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelLeft){let a=pa.get(t.id).endLeft,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelRight){let a=pa.get(t.id).endRight,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}},"positionEdgeLabel"),I_e=o((t,e)=>{let r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),s=t.width/2,l=t.height/2;return i>=s||a>=l},"outsideNode"),O_e=o((t,e,r)=>{Y.debug(`intersection calc abc89:
+ outsidePoint: ${JSON.stringify(e)}
+ insidePoint : ${JSON.stringify(r)}
+ node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);let n=t.x,i=t.y,a=Math.abs(n-r.x),s=t.width/2,l=r.x<e.x?s-a:s+a,u=t.height/2,h=Math.abs(e.y-r.y),f=Math.abs(e.x-r.x);if(Math.abs(i-e.y)*s>Math.abs(n-e.x)*u){let d=r.y<e.y?e.y-u-i:i-u-e.y;l=f*d/h;let p={x:r.x<e.x?r.x+l:r.x-f+l,y:r.y<e.y?r.y+h-d:r.y-h+d};return l===0&&(p.x=e.x,p.y=e.y),f===0&&(p.x=e.x),h===0&&(p.y=e.y),Y.debug(`abc89 top/bottom calc, Q ${h}, q ${d}, R ${f}, r ${l}`,p),p}else{r.x<e.x?l=e.x-s-n:l=n-s-e.x;let d=h*l/f,p=r.x<e.x?r.x+f-l:r.x-f+l,m=r.y<e.y?r.y+d:r.y-d;return Y.debug(`sides calc abc89, Q ${h}, q ${d}, R ${f}, r ${l}`,{_x:p,_y:m}),l===0&&(p=e.x,m=e.y),f===0&&(p=e.x),h===0&&(m=e.y),{x:p,y:m}}},"intersection"),JZ=o((t,e)=>{Y.warn("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach(a=>{if(Y.info("abc88 checking point",a,e),!I_e(e,a)&&!i){let s=O_e(e,n,a);Y.debug("abc88 inside",a,n,s),Y.debug("abc88 intersection",s,e);let l=!1;r.forEach(u=>{l=l||u.x===s.x&&u.y===s.y}),r.some(u=>u.x===s.x&&u.y===s.y)?Y.warn("abc88 no intersect",s,r):r.push(s),i=!0}else Y.warn("abc88 outside",a,n),n=a,i||r.push(a)}),Y.debug("returning points",r),r},"cutPathAtIntersect");o(P_e,"extractCornerPoints");eJ=o(function(t,e,r){let n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),s=r/a;return{x:e.x-s*n,y:e.y-s*i}},"findAdjacentPoint"),B_e=o(function(t){let{cornerPointPositions:e}=P_e(t),r=[];for(let n=0;n<t.length;n++)if(e.includes(n)){let i=t[n-1],a=t[n+1],s=t[n],l=eJ(i,s,5),u=eJ(a,s,5),h=u.x-l.x,f=u.y-l.y;r.push(l);let d=Math.sqrt(2)*2,p={x:s.x,y:s.y};if(Math.abs(a.x-i.x)>10&&Math.abs(a.y-i.y)>=10){Y.debug("Corner point fixing",Math.abs(a.x-i.x),Math.abs(a.y-i.y));let m=5;s.x===l.x?p={x:h<0?l.x-m+d:l.x+m-d,y:f<0?l.y-d:l.y+d}:p={x:h<0?l.x-d:l.x+d,y:f<0?l.y-m+d:l.y+m-d}}else Y.debug("Corner point skipping fixing",Math.abs(a.x-i.x),Math.abs(a.y-i.y));r.push(p,u)}else r.push(t[n]);return r},"fixCorners"),Qw=o(function(t,e,r,n,i,a,s){let{handDrawnSeed:l}=me(),u=e.points,h=!1,f=i;var d=a;let p=[];for(let _ in e.cssCompiledStyles)ND(_)||p.push(e.cssCompiledStyles[_]);d.intersect&&f.intersect&&(u=u.slice(1,e.points.length-1),u.unshift(f.intersect(u[0])),Y.debug("Last point APA12",e.start,"-->",e.end,u[u.length-1],d,d.intersect(u[u.length-1])),u.push(d.intersect(u[u.length-1]))),e.toCluster&&(Y.info("to cluster abc88",r.get(e.toCluster)),u=JZ(e.points,r.get(e.toCluster).node),h=!0),e.fromCluster&&(Y.debug("from cluster abc88",r.get(e.fromCluster),JSON.stringify(u,null,2)),u=JZ(u.reverse(),r.get(e.fromCluster).node).reverse(),h=!0);let m=u.filter(_=>!Number.isNaN(_.y));m=B_e(m);let g=Do;switch(g=wu,e.curve){case"linear":g=wu;break;case"basis":g=Do;break;case"cardinal":g=Pv;break;case"bumpX":g=Rv;break;case"bumpY":g=Nv;break;case"catmullRom":g=$v;break;case"monotoneX":g=zv;break;case"monotoneY":g=Gv;break;case"natural":g=F0;break;case"step":g=$0;break;case"stepAfter":g=Uv;break;case"stepBefore":g=Vv;break;default:g=Do}let{x:y,y:v}=qw(e),x=wl().x(y).y(v).curve(g),b;switch(e.thickness){case"normal":b="edge-thickness-normal";break;case"thick":b="edge-thickness-thick";break;case"invisible":b="edge-thickness-invisible";break;default:b="edge-thickness-normal"}switch(e.pattern){case"solid":b+=" edge-pattern-solid";break;case"dotted":b+=" edge-pattern-dotted";break;case"dashed":b+=" edge-pattern-dashed";break;default:b+=" edge-pattern-solid"}let w,C=x(m),T=Array.isArray(e.style)?e.style:[e.style],E=T.find(_=>_?.startsWith("stroke:"));if(e.look==="handDrawn"){let _=Xe.svg(t);Object.assign([],m);let I=_.path(C,{roughness:.3,seed:l});b+=" transition",w=Ge(I).select("path").attr("id",e.id).attr("class"," "+b+(e.classes?" "+e.classes:"")).attr("style",T?T.reduce((k,L)=>k+";"+L,""):"");let D=w.attr("d");w.attr("d",D),t.node().appendChild(w.node())}else{let _=p.join(";"),I=T?T.reduce((L,R)=>L+R+";",""):"",D="";e.animate&&(D=" edge-animation-fast"),e.animation&&(D=" edge-animation-"+e.animation);let k=_?_+";"+I+";":I;w=t.append("path").attr("d",C).attr("id",e.id).attr("class"," "+b+(e.classes?" "+e.classes:"")+(D??"")).attr("style",k),E=k.match(/stroke:([^;]+)/)?.[1]}let A="";(me().flowchart.arrowMarkerAbsolute||me().state.arrowMarkerAbsolute)&&(A=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,A=A.replace(/\(/g,"\\(").replace(/\)/g,"\\)")),Y.info("arrowTypeStart",e.arrowTypeStart),Y.info("arrowTypeEnd",e.arrowTypeEnd),QZ(w,e,A,s,n,E);let S={};return h&&(S.updatedPath=u),S.originalPath=e.points,S},"insertEdge")});var F_e,$_e,z_e,G_e,V_e,U_e,H_e,W_e,q_e,Y_e,X_e,j_e,K_e,Q_e,Z_e,J_e,e9e,Zw,tL=N(()=>{"use strict";vt();F_e=o((t,e,r,n)=>{e.forEach(i=>{e9e[i](t,r,n)})},"insertMarkers"),$_e=o((t,e,r)=>{Y.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),z_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),G_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),V_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),U_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),H_e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),W_e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),q_e=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),Y_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","userSpaceOnUse").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),X_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneStart").attr("class","marker onlyOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",r+"_"+e+"-onlyOneEnd").attr("class","marker onlyOne "+e).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("d","M3,0 L3,18 M9,0 L9,18")},"only_one"),j_e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneStart").attr("class","marker zeroOrOne "+e).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),n.append("path").attr("d","M9,0 L9,18");let i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrOneEnd").attr("class","marker zeroOrOne "+e).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),i.append("path").attr("d","M21,0 L21,18")},"zero_or_one"),K_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreStart").attr("class","marker oneOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",r+"_"+e+"-oneOrMoreEnd").attr("class","marker oneOrMore "+e).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18")},"one_or_more"),Q_e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreStart").attr("class","marker zeroOrMore "+e).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");n.append("circle").attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),n.append("path").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18");let i=t.append("defs").append("marker").attr("id",r+"_"+e+"-zeroOrMoreEnd").attr("class","marker zeroOrMore "+e).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto");i.append("circle").attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),i.append("path").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},"zero_or_more"),Z_e=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_arrowEnd").attr("refX",20).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("path").attr("d",`M0,0
+ L20,10
+ M20,10
+ L0,20`)},"requirement_arrow"),J_e=o((t,e,r)=>{let n=t.append("defs").append("marker").attr("id",r+"_"+e+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("g");n.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),n.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),n.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10)},"requirement_contains"),e9e={extension:$_e,composition:z_e,aggregation:G_e,dependency:V_e,lollipop:U_e,point:H_e,circle:W_e,cross:q_e,barb:Y_e,only_one:X_e,zero_or_one:j_e,one_or_more:K_e,zero_or_more:Q_e,requirement_arrow:Z_e,requirement_contains:J_e},Zw=F_e});async function vm(t,e,r){let n,i;e.shape==="rect"&&(e.rx&&e.ry?e.shape="roundedRect":e.shape="squareRect");let a=e.shape?QD[e.shape]:void 0;if(!a)throw new Error(`No such shape: ${e.shape}. Please check your syntax.`);if(e.link){let s;r.config.securityLevel==="sandbox"?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s??null),i=await a(n,e,r)}else i=await a(t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),Jw.set(e.id,n),e.haveCallback&&n.attr("class",n.attr("class")+" clickable"),n}var Jw,rJ,nJ,k2,eT=N(()=>{"use strict";vt();ZD();Jw=new Map;o(vm,"insertNode");rJ=o((t,e)=>{Jw.set(e.id,t)},"setNodeElem"),nJ=o(()=>{Jw.clear()},"clear"),k2=o(t=>{let e=Jw.get(t.id);Y.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");let r=8,n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-r)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},"positionNode")});var iJ,aJ=N(()=>{"use strict";ji();gr();vt();Hw();eL();tL();eT();Ft();ir();iJ={common:Ze,getConfig:cr,insertCluster:ym,insertEdge:Qw,insertEdgeLabel:jw,insertMarkers:Zw,insertNode:vm,interpolateToCurve:W9,labelHelper:pt,log:Y,positionEdgeLabel:Kw}});function r9e(t){return typeof t=="symbol"||ri(t)&&da(t)==t9e}var t9e,no,Pd=N(()=>{"use strict";ku();No();t9e="[object Symbol]";o(r9e,"isSymbol");no=r9e});function n9e(t,e){for(var r=-1,n=t==null?0:t.length,i=Array(n);++r<n;)i[r]=e(t[r],r,t);return i}var Ns,Bd=N(()=>{"use strict";o(n9e,"arrayMap");Ns=n9e});function lJ(t){if(typeof t=="string")return t;if(Pt(t))return Ns(t,lJ)+"";if(no(t))return oJ?oJ.call(t):"";var e=t+"";return e=="0"&&1/t==-i9e?"-0":e}var i9e,sJ,oJ,cJ,uJ=N(()=>{"use strict";Ed();Bd();Un();Pd();i9e=1/0,sJ=ea?ea.prototype:void 0,oJ=sJ?sJ.toString:void 0;o(lJ,"baseToString");cJ=lJ});function s9e(t){for(var e=t.length;e--&&a9e.test(t.charAt(e)););return e}var a9e,hJ,fJ=N(()=>{"use strict";a9e=/\s/;o(s9e,"trimmedEndIndex");hJ=s9e});function l9e(t){return t&&t.slice(0,hJ(t)+1).replace(o9e,"")}var o9e,dJ,pJ=N(()=>{"use strict";fJ();o9e=/^\s+/;o(l9e,"baseTrim");dJ=l9e});function d9e(t){if(typeof t=="number")return t;if(no(t))return mJ;if(bn(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=bn(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=dJ(t);var r=u9e.test(t);return r||h9e.test(t)?f9e(t.slice(2),r?2:8):c9e.test(t)?mJ:+t}var mJ,c9e,u9e,h9e,f9e,gJ,yJ=N(()=>{"use strict";pJ();Js();Pd();mJ=NaN,c9e=/^[-+]0x[0-9a-f]+$/i,u9e=/^0b[01]+$/i,h9e=/^0o[0-7]+$/i,f9e=parseInt;o(d9e,"toNumber");gJ=d9e});function m9e(t){if(!t)return t===0?t:0;if(t=gJ(t),t===vJ||t===-vJ){var e=t<0?-1:1;return e*p9e}return t===t?t:0}var vJ,p9e,xm,rL=N(()=>{"use strict";yJ();vJ=1/0,p9e=17976931348623157e292;o(m9e,"toFinite");xm=m9e});function g9e(t){var e=xm(t),r=e%1;return e===e?r?e-r:e:0}var vc,bm=N(()=>{"use strict";rL();o(g9e,"toInteger");vc=g9e});var y9e,tT,xJ=N(()=>{"use strict";Lh();Lo();y9e=Ss(li,"WeakMap"),tT=y9e});function v9e(){}var ni,nL=N(()=>{"use strict";o(v9e,"noop");ni=v9e});function x9e(t,e){for(var r=-1,n=t==null?0:t.length;++r<n&&e(t[r],r,t)!==!1;);return t}var rT,iL=N(()=>{"use strict";o(x9e,"arrayEach");rT=x9e});function b9e(t,e,r,n){for(var i=t.length,a=r+(n?1:-1);n?a--:++a<i;)if(e(t[a],a,t))return a;return-1}var nT,aL=N(()=>{"use strict";o(b9e,"baseFindIndex");nT=b9e});function w9e(t){return t!==t}var bJ,wJ=N(()=>{"use strict";o(w9e,"baseIsNaN");bJ=w9e});function T9e(t,e,r){for(var n=r-1,i=t.length;++n<i;)if(t[n]===e)return n;return-1}var TJ,kJ=N(()=>{"use strict";o(T9e,"strictIndexOf");TJ=T9e});function k9e(t,e,r){return e===e?TJ(t,e,r):nT(t,bJ,r)}var wm,iT=N(()=>{"use strict";aL();wJ();kJ();o(k9e,"baseIndexOf");wm=k9e});function E9e(t,e){var r=t==null?0:t.length;return!!r&&wm(t,e,0)>-1}var aT,sL=N(()=>{"use strict";iT();o(E9e,"arrayIncludes");aT=E9e});var S9e,EJ,SJ=N(()=>{"use strict";N9();S9e=nw(Object.keys,Object),EJ=S9e});function _9e(t){if(!uc(t))return EJ(t);var e=[];for(var r in Object(t))A9e.call(t,r)&&r!="constructor"&&e.push(r);return e}var C9e,A9e,Tm,sT=N(()=>{"use strict";Z0();SJ();C9e=Object.prototype,A9e=C9e.hasOwnProperty;o(_9e,"baseKeys");Tm=_9e});function D9e(t){return ci(t)?lw(t):Tm(t)}var zr,xc=N(()=>{"use strict";B9();sT();Mo();o(D9e,"keys");zr=D9e});var L9e,R9e,N9e,ma,CJ=N(()=>{"use strict";rm();Dd();G9();Mo();Z0();xc();L9e=Object.prototype,R9e=L9e.hasOwnProperty,N9e=hw(function(t,e){if(uc(e)||ci(e)){Po(e,zr(e),t);return}for(var r in e)R9e.call(e,r)&&hc(t,r,e[r])}),ma=N9e});function O9e(t,e){if(Pt(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||no(t)?!0:I9e.test(t)||!M9e.test(t)||e!=null&&t in Object(e)}var M9e,I9e,km,oT=N(()=>{"use strict";Un();Pd();M9e=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,I9e=/^\w*$/;o(O9e,"isKey");km=O9e});function B9e(t){var e=H0(t,function(n){return r.size===P9e&&r.clear(),n}),r=e.cache;return e}var P9e,AJ,_J=N(()=>{"use strict";S9();P9e=500;o(B9e,"memoizeCapped");AJ=B9e});var F9e,$9e,z9e,DJ,LJ=N(()=>{"use strict";_J();F9e=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,$9e=/\\(\\)?/g,z9e=AJ(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(F9e,function(r,n,i,a){e.push(i?a.replace($9e,"$1"):n||r)}),e}),DJ=z9e});function G9e(t){return t==null?"":cJ(t)}var lT,oL=N(()=>{"use strict";uJ();o(G9e,"toString");lT=G9e});function V9e(t,e){return Pt(t)?t:km(t,e)?[t]:DJ(lT(t))}var Yh,E2=N(()=>{"use strict";Un();oT();LJ();oL();o(V9e,"castPath");Yh=V9e});function H9e(t){if(typeof t=="string"||no(t))return t;var e=t+"";return e=="0"&&1/t==-U9e?"-0":e}var U9e,bc,Em=N(()=>{"use strict";Pd();U9e=1/0;o(H9e,"toKey");bc=H9e});function W9e(t,e){e=Yh(e,t);for(var r=0,n=e.length;t!=null&&r<n;)t=t[bc(e[r++])];return r&&r==n?t:void 0}var Xh,S2=N(()=>{"use strict";E2();Em();o(W9e,"baseGet");Xh=W9e});function q9e(t,e,r){var n=t==null?void 0:Xh(t,e);return n===void 0?r:n}var RJ,NJ=N(()=>{"use strict";S2();o(q9e,"get");RJ=q9e});function Y9e(t,e){for(var r=-1,n=e.length,i=t.length;++r<n;)t[i+r]=e[r];return t}var Sm,cT=N(()=>{"use strict";o(Y9e,"arrayPush");Sm=Y9e});function X9e(t){return Pt(t)||El(t)||!!(MJ&&t&&t[MJ])}var MJ,IJ,OJ=N(()=>{"use strict";Ed();J0();Un();MJ=ea?ea.isConcatSpreadable:void 0;o(X9e,"isFlattenable");IJ=X9e});function PJ(t,e,r,n,i){var a=-1,s=t.length;for(r||(r=IJ),i||(i=[]);++a<s;){var l=t[a];e>0&&r(l)?e>1?PJ(l,e-1,r,n,i):Sm(i,l):n||(i[i.length]=l)}return i}var wc,Cm=N(()=>{"use strict";cT();OJ();o(PJ,"baseFlatten");wc=PJ});function j9e(t){var e=t==null?0:t.length;return e?wc(t,1):[]}var qr,uT=N(()=>{"use strict";Cm();o(j9e,"flatten");qr=j9e});function K9e(t){return uw(cw(t,void 0,qr),t+"")}var BJ,FJ=N(()=>{"use strict";uT();F9();z9();o(K9e,"flatRest");BJ=K9e});function Q9e(t,e,r){var n=-1,i=t.length;e<0&&(e=-e>i?0:i+e),r=r>i?i:r,r<0&&(r+=i),i=e>r?0:r-e>>>0,e>>>=0;for(var a=Array(i);++n<i;)a[n]=t[n+e];return a}var hT,lL=N(()=>{"use strict";o(Q9e,"baseSlice");hT=Q9e});function sDe(t){return aDe.test(t)}var Z9e,J9e,eDe,tDe,rDe,nDe,iDe,aDe,$J,zJ=N(()=>{"use strict";Z9e="\\ud800-\\udfff",J9e="\\u0300-\\u036f",eDe="\\ufe20-\\ufe2f",tDe="\\u20d0-\\u20ff",rDe=J9e+eDe+tDe,nDe="\\ufe0e\\ufe0f",iDe="\\u200d",aDe=RegExp("["+iDe+Z9e+rDe+nDe+"]");o(sDe,"hasUnicode");$J=sDe});function oDe(t,e,r,n){var i=-1,a=t==null?0:t.length;for(n&&a&&(r=t[++i]);++i<a;)r=e(r,t[i],i,t);return r}var GJ,VJ=N(()=>{"use strict";o(oDe,"arrayReduce");GJ=oDe});function lDe(t,e){return t&&Po(e,zr(e),t)}var UJ,HJ=N(()=>{"use strict";Dd();xc();o(lDe,"baseAssign");UJ=lDe});function cDe(t,e){return t&&Po(e,Cs(e),t)}var WJ,qJ=N(()=>{"use strict";Dd();Bh();o(cDe,"baseAssignIn");WJ=cDe});function uDe(t,e){for(var r=-1,n=t==null?0:t.length,i=0,a=[];++r<n;){var s=t[r];e(s,r,t)&&(a[i++]=s)}return a}var Am,fT=N(()=>{"use strict";o(uDe,"arrayFilter");Am=uDe});function hDe(){return[]}var dT,cL=N(()=>{"use strict";o(hDe,"stubArray");dT=hDe});var fDe,dDe,YJ,pDe,_m,pT=N(()=>{"use strict";fT();cL();fDe=Object.prototype,dDe=fDe.propertyIsEnumerable,YJ=Object.getOwnPropertySymbols,pDe=YJ?function(t){return t==null?[]:(t=Object(t),Am(YJ(t),function(e){return dDe.call(t,e)}))}:dT,_m=pDe});function mDe(t,e){return Po(t,_m(t),e)}var XJ,jJ=N(()=>{"use strict";Dd();pT();o(mDe,"copySymbols");XJ=mDe});var gDe,yDe,mT,uL=N(()=>{"use strict";cT();iw();pT();cL();gDe=Object.getOwnPropertySymbols,yDe=gDe?function(t){for(var e=[];t;)Sm(e,_m(t)),t=Q0(t);return e}:dT,mT=yDe});function vDe(t,e){return Po(t,mT(t),e)}var KJ,QJ=N(()=>{"use strict";Dd();uL();o(vDe,"copySymbolsIn");KJ=vDe});function xDe(t,e,r){var n=e(t);return Pt(t)?n:Sm(n,r(t))}var gT,hL=N(()=>{"use strict";cT();Un();o(xDe,"baseGetAllKeys");gT=xDe});function bDe(t){return gT(t,zr,_m)}var C2,fL=N(()=>{"use strict";hL();pT();xc();o(bDe,"getAllKeys");C2=bDe});function wDe(t){return gT(t,Cs,mT)}var yT,dL=N(()=>{"use strict";hL();uL();Bh();o(wDe,"getAllKeysIn");yT=wDe});var TDe,vT,ZJ=N(()=>{"use strict";Lh();Lo();TDe=Ss(li,"DataView"),vT=TDe});var kDe,xT,JJ=N(()=>{"use strict";Lh();Lo();kDe=Ss(li,"Promise"),xT=kDe});var EDe,jh,pL=N(()=>{"use strict";Lh();Lo();EDe=Ss(li,"Set"),jh=EDe});var eee,SDe,tee,ree,nee,iee,CDe,ADe,_De,DDe,LDe,Fd,io,$d=N(()=>{"use strict";ZJ();K5();JJ();pL();xJ();ku();T9();eee="[object Map]",SDe="[object Object]",tee="[object Promise]",ree="[object Set]",nee="[object WeakMap]",iee="[object DataView]",CDe=Eu(vT),ADe=Eu(Mh),_De=Eu(xT),DDe=Eu(jh),LDe=Eu(tT),Fd=da;(vT&&Fd(new vT(new ArrayBuffer(1)))!=iee||Mh&&Fd(new Mh)!=eee||xT&&Fd(xT.resolve())!=tee||jh&&Fd(new jh)!=ree||tT&&Fd(new tT)!=nee)&&(Fd=o(function(t){var e=da(t),r=e==SDe?t.constructor:void 0,n=r?Eu(r):"";if(n)switch(n){case CDe:return iee;case ADe:return eee;case _De:return tee;case DDe:return ree;case LDe:return nee}return e},"getTag"));io=Fd});function MDe(t){var e=t.length,r=new t.constructor(e);return e&&typeof t[0]=="string"&&NDe.call(t,"index")&&(r.index=t.index,r.input=t.input),r}var RDe,NDe,aee,see=N(()=>{"use strict";RDe=Object.prototype,NDe=RDe.hasOwnProperty;o(MDe,"initCloneArray");aee=MDe});function IDe(t,e){var r=e?K0(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}var oee,lee=N(()=>{"use strict";ew();o(IDe,"cloneDataView");oee=IDe});function PDe(t){var e=new t.constructor(t.source,ODe.exec(t));return e.lastIndex=t.lastIndex,e}var ODe,cee,uee=N(()=>{"use strict";ODe=/\w*$/;o(PDe,"cloneRegExp");cee=PDe});function BDe(t){return fee?Object(fee.call(t)):{}}var hee,fee,dee,pee=N(()=>{"use strict";Ed();hee=ea?ea.prototype:void 0,fee=hee?hee.valueOf:void 0;o(BDe,"cloneSymbol");dee=BDe});function nLe(t,e,r){var n=t.constructor;switch(e){case qDe:return K0(t);case FDe:case $De:return new n(+t);case YDe:return oee(t,r);case XDe:case jDe:case KDe:case QDe:case ZDe:case JDe:case eLe:case tLe:case rLe:return tw(t,r);case zDe:return new n;case GDe:case HDe:return new n(t);case VDe:return cee(t);case UDe:return new n;case WDe:return dee(t)}}var FDe,$De,zDe,GDe,VDe,UDe,HDe,WDe,qDe,YDe,XDe,jDe,KDe,QDe,ZDe,JDe,eLe,tLe,rLe,mee,gee=N(()=>{"use strict";ew();lee();uee();pee();L9();FDe="[object Boolean]",$De="[object Date]",zDe="[object Map]",GDe="[object Number]",VDe="[object RegExp]",UDe="[object Set]",HDe="[object String]",WDe="[object Symbol]",qDe="[object ArrayBuffer]",YDe="[object DataView]",XDe="[object Float32Array]",jDe="[object Float64Array]",KDe="[object Int8Array]",QDe="[object Int16Array]",ZDe="[object Int32Array]",JDe="[object Uint8Array]",eLe="[object Uint8ClampedArray]",tLe="[object Uint16Array]",rLe="[object Uint32Array]";o(nLe,"initCloneByTag");mee=nLe});function aLe(t){return ri(t)&&io(t)==iLe}var iLe,yee,vee=N(()=>{"use strict";$d();No();iLe="[object Map]";o(aLe,"baseIsMap");yee=aLe});var xee,sLe,bee,wee=N(()=>{"use strict";vee();_d();t2();xee=Oo&&Oo.isMap,sLe=xee?Io(xee):yee,bee=sLe});function lLe(t){return ri(t)&&io(t)==oLe}var oLe,Tee,kee=N(()=>{"use strict";$d();No();oLe="[object Set]";o(lLe,"baseIsSet");Tee=lLe});var Eee,cLe,See,Cee=N(()=>{"use strict";kee();_d();t2();Eee=Oo&&Oo.isSet,cLe=Eee?Io(Eee):Tee,See=cLe});function bT(t,e,r,n,i,a){var s,l=e&uLe,u=e&hLe,h=e&fLe;if(r&&(s=i?r(t,n,i,a):r(t)),s!==void 0)return s;if(!bn(t))return t;var f=Pt(t);if(f){if(s=aee(t),!l)return rw(t,s)}else{var d=io(t),p=d==_ee||d==yLe;if(Sl(t))return J5(t,l);if(d==Dee||d==Aee||p&&!i){if(s=u||p?{}:aw(t),!l)return u?KJ(t,WJ(s,t)):XJ(t,UJ(s,t))}else{if(!_n[d])return i?t:{};s=mee(t,d,l)}}a||(a=new lc);var m=a.get(t);if(m)return m;a.set(t,s),See(t)?t.forEach(function(v){s.add(bT(v,e,r,v,t,a))}):bee(t)&&t.forEach(function(v,x){s.set(x,bT(v,e,r,x,t,a))});var g=h?u?yT:C2:u?Cs:zr,y=f?void 0:g(t);return rT(y||t,function(v,x){y&&(x=v,v=t[x]),hc(s,x,bT(v,e,r,x,t,a))}),s}var uLe,hLe,fLe,Aee,dLe,pLe,mLe,gLe,_ee,yLe,vLe,xLe,Dee,bLe,wLe,TLe,kLe,ELe,SLe,CLe,ALe,_Le,DLe,LLe,RLe,NLe,MLe,ILe,OLe,_n,wT,mL=N(()=>{"use strict";Zv();iL();rm();HJ();qJ();_9();R9();jJ();QJ();fL();dL();$d();see();gee();M9();Un();tm();wee();Js();Cee();xc();Bh();uLe=1,hLe=2,fLe=4,Aee="[object Arguments]",dLe="[object Array]",pLe="[object Boolean]",mLe="[object Date]",gLe="[object Error]",_ee="[object Function]",yLe="[object GeneratorFunction]",vLe="[object Map]",xLe="[object Number]",Dee="[object Object]",bLe="[object RegExp]",wLe="[object Set]",TLe="[object String]",kLe="[object Symbol]",ELe="[object WeakMap]",SLe="[object ArrayBuffer]",CLe="[object DataView]",ALe="[object Float32Array]",_Le="[object Float64Array]",DLe="[object Int8Array]",LLe="[object Int16Array]",RLe="[object Int32Array]",NLe="[object Uint8Array]",MLe="[object Uint8ClampedArray]",ILe="[object Uint16Array]",OLe="[object Uint32Array]",_n={};_n[Aee]=_n[dLe]=_n[SLe]=_n[CLe]=_n[pLe]=_n[mLe]=_n[ALe]=_n[_Le]=_n[DLe]=_n[LLe]=_n[RLe]=_n[vLe]=_n[xLe]=_n[Dee]=_n[bLe]=_n[wLe]=_n[TLe]=_n[kLe]=_n[NLe]=_n[MLe]=_n[ILe]=_n[OLe]=!0;_n[gLe]=_n[_ee]=_n[ELe]=!1;o(bT,"baseClone");wT=bT});function BLe(t){return wT(t,PLe)}var PLe,an,gL=N(()=>{"use strict";mL();PLe=4;o(BLe,"clone");an=BLe});function zLe(t){return wT(t,FLe|$Le)}var FLe,$Le,yL,Lee=N(()=>{"use strict";mL();FLe=1,$Le=4;o(zLe,"cloneDeep");yL=zLe});function GLe(t){for(var e=-1,r=t==null?0:t.length,n=0,i=[];++e<r;){var a=t[e];a&&(i[n++]=a)}return i}var Tc,Ree=N(()=>{"use strict";o(GLe,"compact");Tc=GLe});function ULe(t){return this.__data__.set(t,VLe),this}var VLe,Nee,Mee=N(()=>{"use strict";VLe="__lodash_hash_undefined__";o(ULe,"setCacheAdd");Nee=ULe});function HLe(t){return this.__data__.has(t)}var Iee,Oee=N(()=>{"use strict";o(HLe,"setCacheHas");Iee=HLe});function TT(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new Cd;++e<r;)this.add(t[e])}var Dm,kT=N(()=>{"use strict";Q5();Mee();Oee();o(TT,"SetCache");TT.prototype.add=TT.prototype.push=Nee;TT.prototype.has=Iee;Dm=TT});function WLe(t,e){for(var r=-1,n=t==null?0:t.length;++r<n;)if(e(t[r],r,t))return!0;return!1}var ET,vL=N(()=>{"use strict";o(WLe,"arraySome");ET=WLe});function qLe(t,e){return t.has(e)}var Lm,ST=N(()=>{"use strict";o(qLe,"cacheHas");Lm=qLe});function jLe(t,e,r,n,i,a){var s=r&YLe,l=t.length,u=e.length;if(l!=u&&!(s&&u>l))return!1;var h=a.get(t),f=a.get(e);if(h&&f)return h==e&&f==t;var d=-1,p=!0,m=r&XLe?new Dm:void 0;for(a.set(t,e),a.set(e,t);++d<l;){var g=t[d],y=e[d];if(n)var v=s?n(y,g,d,e,t,a):n(g,y,d,t,e,a);if(v!==void 0){if(v)continue;p=!1;break}if(m){if(!ET(e,function(x,b){if(!Lm(m,b)&&(g===x||i(g,x,r,n,a)))return m.push(b)})){p=!1;break}}else if(!(g===y||i(g,y,r,n,a))){p=!1;break}}return a.delete(t),a.delete(e),p}var YLe,XLe,CT,xL=N(()=>{"use strict";kT();vL();ST();YLe=1,XLe=2;o(jLe,"equalArrays");CT=jLe});function KLe(t){var e=-1,r=Array(t.size);return t.forEach(function(n,i){r[++e]=[i,n]}),r}var Pee,Bee=N(()=>{"use strict";o(KLe,"mapToArray");Pee=KLe});function QLe(t){var e=-1,r=Array(t.size);return t.forEach(function(n){r[++e]=n}),r}var Rm,AT=N(()=>{"use strict";o(QLe,"setToArray");Rm=QLe});function hRe(t,e,r,n,i,a,s){switch(r){case uRe:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case cRe:return!(t.byteLength!=e.byteLength||!a(new j0(t),new j0(e)));case eRe:case tRe:case iRe:return Ro(+t,+e);case rRe:return t.name==e.name&&t.message==e.message;case aRe:case oRe:return t==e+"";case nRe:var l=Pee;case sRe:var u=n&ZLe;if(l||(l=Rm),t.size!=e.size&&!u)return!1;var h=s.get(t);if(h)return h==e;n|=JLe,s.set(t,e);var f=CT(l(t),l(e),n,i,a,s);return s.delete(t),f;case lRe:if(bL)return bL.call(t)==bL.call(e)}return!1}var ZLe,JLe,eRe,tRe,rRe,nRe,iRe,aRe,sRe,oRe,lRe,cRe,uRe,Fee,bL,$ee,zee=N(()=>{"use strict";Ed();D9();Sd();xL();Bee();AT();ZLe=1,JLe=2,eRe="[object Boolean]",tRe="[object Date]",rRe="[object Error]",nRe="[object Map]",iRe="[object Number]",aRe="[object RegExp]",sRe="[object Set]",oRe="[object String]",lRe="[object Symbol]",cRe="[object ArrayBuffer]",uRe="[object DataView]",Fee=ea?ea.prototype:void 0,bL=Fee?Fee.valueOf:void 0;o(hRe,"equalByTag");$ee=hRe});function mRe(t,e,r,n,i,a){var s=r&fRe,l=C2(t),u=l.length,h=C2(e),f=h.length;if(u!=f&&!s)return!1;for(var d=u;d--;){var p=l[d];if(!(s?p in e:pRe.call(e,p)))return!1}var m=a.get(t),g=a.get(e);if(m&&g)return m==e&&g==t;var y=!0;a.set(t,e),a.set(e,t);for(var v=s;++d<u;){p=l[d];var x=t[p],b=e[p];if(n)var w=s?n(b,x,p,e,t,a):n(x,b,p,t,e,a);if(!(w===void 0?x===b||i(x,b,r,n,a):w)){y=!1;break}v||(v=p=="constructor")}if(y&&!v){var C=t.constructor,T=e.constructor;C!=T&&"constructor"in t&&"constructor"in e&&!(typeof C=="function"&&C instanceof C&&typeof T=="function"&&T instanceof T)&&(y=!1)}return a.delete(t),a.delete(e),y}var fRe,dRe,pRe,Gee,Vee=N(()=>{"use strict";fL();fRe=1,dRe=Object.prototype,pRe=dRe.hasOwnProperty;o(mRe,"equalObjects");Gee=mRe});function vRe(t,e,r,n,i,a){var s=Pt(t),l=Pt(e),u=s?Hee:io(t),h=l?Hee:io(e);u=u==Uee?_T:u,h=h==Uee?_T:h;var f=u==_T,d=h==_T,p=u==h;if(p&&Sl(t)){if(!Sl(e))return!1;s=!0,f=!1}if(p&&!f)return a||(a=new lc),s||Oh(t)?CT(t,e,r,n,i,a):$ee(t,e,u,r,n,i,a);if(!(r&gRe)){var m=f&&Wee.call(t,"__wrapped__"),g=d&&Wee.call(e,"__wrapped__");if(m||g){var y=m?t.value():t,v=g?e.value():e;return a||(a=new lc),i(y,v,r,n,a)}}return p?(a||(a=new lc),Gee(t,e,r,n,i,a)):!1}var gRe,Uee,Hee,_T,yRe,Wee,qee,Yee=N(()=>{"use strict";Zv();xL();zee();Vee();$d();Un();tm();r2();gRe=1,Uee="[object Arguments]",Hee="[object Array]",_T="[object Object]",yRe=Object.prototype,Wee=yRe.hasOwnProperty;o(vRe,"baseIsEqualDeep");qee=vRe});function Xee(t,e,r,n,i){return t===e?!0:t==null||e==null||!ri(t)&&!ri(e)?t!==t&&e!==e:qee(t,e,r,n,Xee,i)}var DT,wL=N(()=>{"use strict";Yee();No();o(Xee,"baseIsEqual");DT=Xee});function wRe(t,e,r,n){var i=r.length,a=i,s=!n;if(t==null)return!a;for(t=Object(t);i--;){var l=r[i];if(s&&l[2]?l[1]!==t[l[0]]:!(l[0]in t))return!1}for(;++i<a;){l=r[i];var u=l[0],h=t[u],f=l[1];if(s&&l[2]){if(h===void 0&&!(u in t))return!1}else{var d=new lc;if(n)var p=n(h,f,u,t,e,d);if(!(p===void 0?DT(f,h,xRe|bRe,n,d):p))return!1}}return!0}var xRe,bRe,jee,Kee=N(()=>{"use strict";Zv();wL();xRe=1,bRe=2;o(wRe,"baseIsMatch");jee=wRe});function TRe(t){return t===t&&!bn(t)}var LT,TL=N(()=>{"use strict";Js();o(TRe,"isStrictComparable");LT=TRe});function kRe(t){for(var e=zr(t),r=e.length;r--;){var n=e[r],i=t[n];e[r]=[n,i,LT(i)]}return e}var Qee,Zee=N(()=>{"use strict";TL();xc();o(kRe,"getMatchData");Qee=kRe});function ERe(t,e){return function(r){return r==null?!1:r[t]===e&&(e!==void 0||t in Object(r))}}var RT,kL=N(()=>{"use strict";o(ERe,"matchesStrictComparable");RT=ERe});function SRe(t){var e=Qee(t);return e.length==1&&e[0][2]?RT(e[0][0],e[0][1]):function(r){return r===t||jee(r,t,e)}}var Jee,ete=N(()=>{"use strict";Kee();Zee();kL();o(SRe,"baseMatches");Jee=SRe});function CRe(t,e){return t!=null&&e in Object(t)}var tte,rte=N(()=>{"use strict";o(CRe,"baseHasIn");tte=CRe});function ARe(t,e,r){e=Yh(e,t);for(var n=-1,i=e.length,a=!1;++n<i;){var s=bc(e[n]);if(!(a=t!=null&&r(t,s)))break;t=t[s]}return a||++n!=i?a:(i=t==null?0:t.length,!!i&&em(i)&&Ph(s,i)&&(Pt(t)||El(t)))}var NT,EL=N(()=>{"use strict";E2();J0();Un();i2();sw();Em();o(ARe,"hasPath");NT=ARe});function _Re(t,e){return t!=null&&NT(t,e,tte)}var MT,SL=N(()=>{"use strict";rte();EL();o(_Re,"hasIn");MT=_Re});function RRe(t,e){return km(t)&&LT(e)?RT(bc(t),e):function(r){var n=RJ(r,t);return n===void 0&&n===e?MT(r,t):DT(e,n,DRe|LRe)}}var DRe,LRe,nte,ite=N(()=>{"use strict";wL();NJ();SL();oT();TL();kL();Em();DRe=1,LRe=2;o(RRe,"baseMatchesProperty");nte=RRe});function NRe(t){return function(e){return e?.[t]}}var IT,CL=N(()=>{"use strict";o(NRe,"baseProperty");IT=NRe});function MRe(t){return function(e){return Xh(e,t)}}var ate,ste=N(()=>{"use strict";S2();o(MRe,"basePropertyDeep");ate=MRe});function IRe(t){return km(t)?IT(bc(t)):ate(t)}var ote,lte=N(()=>{"use strict";CL();ste();oT();Em();o(IRe,"property");ote=IRe});function ORe(t){return typeof t=="function"?t:t==null?ta:typeof t=="object"?Pt(t)?nte(t[0],t[1]):Jee(t):ote(t)}var pn,rs=N(()=>{"use strict";ete();ite();Cu();Un();lte();o(ORe,"baseIteratee");pn=ORe});function PRe(t,e,r,n){for(var i=-1,a=t==null?0:t.length;++i<a;){var s=t[i];e(n,s,r(s),t)}return n}var cte,ute=N(()=>{"use strict";o(PRe,"arrayAggregator");cte=PRe});function BRe(t,e){return t&&X0(t,e,zr)}var Nm,OT=N(()=>{"use strict";Z5();xc();o(BRe,"baseForOwn");Nm=BRe});function FRe(t,e){return function(r,n){if(r==null)return r;if(!ci(r))return t(r,n);for(var i=r.length,a=e?i:-1,s=Object(r);(e?a--:++a<i)&&n(s[a],a,s)!==!1;);return r}}var hte,fte=N(()=>{"use strict";Mo();o(FRe,"createBaseEach");hte=FRe});var $Re,Ms,Kh=N(()=>{"use strict";OT();fte();$Re=hte(Nm),Ms=$Re});function zRe(t,e,r,n){return Ms(t,function(i,a,s){e(n,i,r(i),s)}),n}var dte,pte=N(()=>{"use strict";Kh();o(zRe,"baseAggregator");dte=zRe});function GRe(t,e){return function(r,n){var i=Pt(r)?cte:dte,a=e?e():{};return i(r,t,pn(n,2),a)}}var mte,gte=N(()=>{"use strict";ute();pte();rs();Un();o(GRe,"createAggregator");mte=GRe});var VRe,PT,yte=N(()=>{"use strict";Lo();VRe=o(function(){return li.Date.now()},"now"),PT=VRe});var vte,URe,HRe,Qh,xte=N(()=>{"use strict";nm();Sd();Ld();Bh();vte=Object.prototype,URe=vte.hasOwnProperty,HRe=fc(function(t,e){t=Object(t);var r=-1,n=e.length,i=n>2?e[2]:void 0;for(i&&eo(e[0],e[1],i)&&(n=1);++r<n;)for(var a=e[r],s=Cs(a),l=-1,u=s.length;++l<u;){var h=s[l],f=t[h];(f===void 0||Ro(f,vte[h])&&!URe.call(t,h))&&(t[h]=a[h])}return t}),Qh=HRe});function WRe(t,e,r){for(var n=-1,i=t==null?0:t.length;++n<i;)if(r(e,t[n]))return!0;return!1}var BT,AL=N(()=>{"use strict";o(WRe,"arrayIncludesWith");BT=WRe});function YRe(t,e,r,n){var i=-1,a=aT,s=!0,l=t.length,u=[],h=e.length;if(!l)return u;r&&(e=Ns(e,Io(r))),n?(a=BT,s=!1):e.length>=qRe&&(a=Lm,s=!1,e=new Dm(e));e:for(;++i<l;){var f=t[i],d=r==null?f:r(f);if(f=n||f!==0?f:0,s&&d===d){for(var p=h;p--;)if(e[p]===d)continue e;u.push(f)}else a(e,d,n)||u.push(f)}return u}var qRe,bte,wte=N(()=>{"use strict";kT();sL();AL();Bd();_d();ST();qRe=200;o(YRe,"baseDifference");bte=YRe});var XRe,Zh,Tte=N(()=>{"use strict";wte();Cm();nm();ow();XRe=fc(function(t,e){return Ad(t)?bte(t,wc(e,1,Ad,!0)):[]}),Zh=XRe});function jRe(t){var e=t==null?0:t.length;return e?t[e-1]:void 0}var ga,kte=N(()=>{"use strict";o(jRe,"last");ga=jRe});function KRe(t,e,r){var n=t==null?0:t.length;return n?(e=r||e===void 0?1:vc(e),hT(t,e<0?0:e,n)):[]}var gi,Ete=N(()=>{"use strict";lL();bm();o(KRe,"drop");gi=KRe});function QRe(t,e,r){var n=t==null?0:t.length;return n?(e=r||e===void 0?1:vc(e),e=n-e,hT(t,0,e<0?0:e)):[]}var Nu,Ste=N(()=>{"use strict";lL();bm();o(QRe,"dropRight");Nu=QRe});function ZRe(t){return typeof t=="function"?t:ta}var Mm,FT=N(()=>{"use strict";Cu();o(ZRe,"castFunction");Mm=ZRe});function JRe(t,e){var r=Pt(t)?rT:Ms;return r(t,Mm(e))}var Ae,$T=N(()=>{"use strict";iL();Kh();FT();Un();o(JRe,"forEach");Ae=JRe});var Cte=N(()=>{"use strict";$T()});function eNe(t,e){for(var r=-1,n=t==null?0:t.length;++r<n;)if(!e(t[r],r,t))return!1;return!0}var Ate,_te=N(()=>{"use strict";o(eNe,"arrayEvery");Ate=eNe});function tNe(t,e){var r=!0;return Ms(t,function(n,i,a){return r=!!e(n,i,a),r}),r}var Dte,Lte=N(()=>{"use strict";Kh();o(tNe,"baseEvery");Dte=tNe});function rNe(t,e,r){var n=Pt(t)?Ate:Dte;return r&&eo(t,e,r)&&(e=void 0),n(t,pn(e,3))}var Ma,Rte=N(()=>{"use strict";_te();Lte();rs();Un();Ld();o(rNe,"every");Ma=rNe});function nNe(t,e){var r=[];return Ms(t,function(n,i,a){e(n,i,a)&&r.push(n)}),r}var zT,_L=N(()=>{"use strict";Kh();o(nNe,"baseFilter");zT=nNe});function iNe(t,e){var r=Pt(t)?Am:zT;return r(t,pn(e,3))}var Yr,DL=N(()=>{"use strict";fT();_L();rs();Un();o(iNe,"filter");Yr=iNe});function aNe(t){return function(e,r,n){var i=Object(e);if(!ci(e)){var a=pn(r,3);e=zr(e),r=o(function(l){return a(i[l],l,i)},"predicate")}var s=t(e,r,n);return s>-1?i[a?e[s]:s]:void 0}}var Nte,Mte=N(()=>{"use strict";rs();Mo();xc();o(aNe,"createFind");Nte=aNe});function oNe(t,e,r){var n=t==null?0:t.length;if(!n)return-1;var i=r==null?0:vc(r);return i<0&&(i=sNe(n+i,0)),nT(t,pn(e,3),i)}var sNe,Ite,Ote=N(()=>{"use strict";aL();rs();bm();sNe=Math.max;o(oNe,"findIndex");Ite=oNe});var lNe,ns,Pte=N(()=>{"use strict";Mte();Ote();lNe=Nte(Ite),ns=lNe});function cNe(t){return t&&t.length?t[0]:void 0}var ia,Bte=N(()=>{"use strict";o(cNe,"head");ia=cNe});var Fte=N(()=>{"use strict";Bte()});function uNe(t,e){var r=-1,n=ci(t)?Array(t.length):[];return Ms(t,function(i,a,s){n[++r]=e(i,a,s)}),n}var GT,LL=N(()=>{"use strict";Kh();Mo();o(uNe,"baseMap");GT=uNe});function hNe(t,e){var r=Pt(t)?Ns:GT;return r(t,pn(e,3))}var Je,Im=N(()=>{"use strict";Bd();rs();LL();Un();o(hNe,"map");Je=hNe});function fNe(t,e){return wc(Je(t,e),1)}var ya,RL=N(()=>{"use strict";Cm();Im();o(fNe,"flatMap");ya=fNe});function dNe(t,e){return t==null?t:X0(t,Mm(e),Cs)}var NL,$te=N(()=>{"use strict";Z5();FT();Bh();o(dNe,"forIn");NL=dNe});function pNe(t,e){return t&&Nm(t,Mm(e))}var ML,zte=N(()=>{"use strict";OT();FT();o(pNe,"forOwn");ML=pNe});var mNe,gNe,yNe,IL,Gte=N(()=>{"use strict";Y0();gte();mNe=Object.prototype,gNe=mNe.hasOwnProperty,yNe=mte(function(t,e,r){gNe.call(t,r)?t[r].push(e):cc(t,r,[e])}),IL=yNe});function vNe(t,e){return t>e}var Vte,Ute=N(()=>{"use strict";o(vNe,"baseGt");Vte=vNe});function wNe(t,e){return t!=null&&bNe.call(t,e)}var xNe,bNe,Hte,Wte=N(()=>{"use strict";xNe=Object.prototype,bNe=xNe.hasOwnProperty;o(wNe,"baseHas");Hte=wNe});function TNe(t,e){return t!=null&&NT(t,e,Hte)}var Bt,qte=N(()=>{"use strict";Wte();EL();o(TNe,"has");Bt=TNe});function ENe(t){return typeof t=="string"||!Pt(t)&&ri(t)&&da(t)==kNe}var kNe,yi,VT=N(()=>{"use strict";ku();Un();No();kNe="[object String]";o(ENe,"isString");yi=ENe});function SNe(t,e){return Ns(e,function(r){return t[r]})}var Yte,Xte=N(()=>{"use strict";Bd();o(SNe,"baseValues");Yte=SNe});function CNe(t){return t==null?[]:Yte(t,zr(t))}var br,OL=N(()=>{"use strict";Xte();xc();o(CNe,"values");br=CNe});function _Ne(t,e,r,n){t=ci(t)?t:br(t),r=r&&!n?vc(r):0;var i=t.length;return r<0&&(r=ANe(i+r,0)),yi(t)?r<=i&&t.indexOf(e,r)>-1:!!i&&wm(t,e,r)>-1}var ANe,qn,jte=N(()=>{"use strict";iT();Mo();VT();bm();OL();ANe=Math.max;o(_Ne,"includes");qn=_Ne});function LNe(t,e,r){var n=t==null?0:t.length;if(!n)return-1;var i=r==null?0:vc(r);return i<0&&(i=DNe(n+i,0)),wm(t,e,i)}var DNe,UT,Kte=N(()=>{"use strict";iT();bm();DNe=Math.max;o(LNe,"indexOf");UT=LNe});function ONe(t){if(t==null)return!0;if(ci(t)&&(Pt(t)||typeof t=="string"||typeof t.splice=="function"||Sl(t)||Oh(t)||El(t)))return!t.length;var e=io(t);if(e==RNe||e==NNe)return!t.size;if(uc(t))return!Tm(t).length;for(var r in t)if(INe.call(t,r))return!1;return!0}var RNe,NNe,MNe,INe,ur,HT=N(()=>{"use strict";sT();$d();J0();Un();Mo();tm();Z0();r2();RNe="[object Map]",NNe="[object Set]",MNe=Object.prototype,INe=MNe.hasOwnProperty;o(ONe,"isEmpty");ur=ONe});function BNe(t){return ri(t)&&da(t)==PNe}var PNe,Qte,Zte=N(()=>{"use strict";ku();No();PNe="[object RegExp]";o(BNe,"baseIsRegExp");Qte=BNe});var Jte,FNe,zo,ere=N(()=>{"use strict";Zte();_d();t2();Jte=Oo&&Oo.isRegExp,FNe=Jte?Io(Jte):Qte,zo=FNe});function $Ne(t){return t===void 0}var pr,tre=N(()=>{"use strict";o($Ne,"isUndefined");pr=$Ne});function zNe(t,e){return t<e}var WT,PL=N(()=>{"use strict";o(zNe,"baseLt");WT=zNe});function GNe(t,e){var r={};return e=pn(e,3),Nm(t,function(n,i,a){cc(r,i,e(n,i,a))}),r}var zd,rre=N(()=>{"use strict";Y0();OT();rs();o(GNe,"mapValues");zd=GNe});function VNe(t,e,r){for(var n=-1,i=t.length;++n<i;){var a=t[n],s=e(a);if(s!=null&&(l===void 0?s===s&&!no(s):r(s,l)))var l=s,u=a}return u}var Om,qT=N(()=>{"use strict";Pd();o(VNe,"baseExtremum");Om=VNe});function UNe(t){return t&&t.length?Om(t,ta,Vte):void 0}var Is,nre=N(()=>{"use strict";qT();Ute();Cu();o(UNe,"max");Is=UNe});function HNe(t){return t&&t.length?Om(t,ta,WT):void 0}var Dl,BL=N(()=>{"use strict";qT();PL();Cu();o(HNe,"min");Dl=HNe});function WNe(t,e){return t&&t.length?Om(t,pn(e,2),WT):void 0}var Gd,ire=N(()=>{"use strict";qT();rs();PL();o(WNe,"minBy");Gd=WNe});function YNe(t){if(typeof t!="function")throw new TypeError(qNe);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}var qNe,are,sre=N(()=>{"use strict";qNe="Expected a function";o(YNe,"negate");are=YNe});function XNe(t,e,r,n){if(!bn(t))return t;e=Yh(e,t);for(var i=-1,a=e.length,s=a-1,l=t;l!=null&&++i<a;){var u=bc(e[i]),h=r;if(u==="__proto__"||u==="constructor"||u==="prototype")return t;if(i!=s){var f=l[u];h=n?n(f,u,l):void 0,h===void 0&&(h=bn(f)?f:Ph(e[i+1])?[]:{})}hc(l,u,h),l=l[u]}return t}var ore,lre=N(()=>{"use strict";rm();E2();i2();Js();Em();o(XNe,"baseSet");ore=XNe});function jNe(t,e,r){for(var n=-1,i=e.length,a={};++n<i;){var s=e[n],l=Xh(t,s);r(l,s)&&ore(a,Yh(s,t),l)}return a}var YT,FL=N(()=>{"use strict";S2();lre();E2();o(jNe,"basePickBy");YT=jNe});function KNe(t,e){if(t==null)return{};var r=Ns(yT(t),function(n){return[n]});return e=pn(e),YT(t,r,function(n,i){return e(n,i[0])})}var Os,cre=N(()=>{"use strict";Bd();rs();FL();dL();o(KNe,"pickBy");Os=KNe});function QNe(t,e){var r=t.length;for(t.sort(e);r--;)t[r]=t[r].value;return t}var ure,hre=N(()=>{"use strict";o(QNe,"baseSortBy");ure=QNe});function ZNe(t,e){if(t!==e){var r=t!==void 0,n=t===null,i=t===t,a=no(t),s=e!==void 0,l=e===null,u=e===e,h=no(e);if(!l&&!h&&!a&&t>e||a&&s&&u&&!l&&!h||n&&s&&u||!r&&u||!i)return 1;if(!n&&!a&&!h&&t<e||h&&r&&i&&!n&&!a||l&&r&&i||!s&&i||!u)return-1}return 0}var fre,dre=N(()=>{"use strict";Pd();o(ZNe,"compareAscending");fre=ZNe});function JNe(t,e,r){for(var n=-1,i=t.criteria,a=e.criteria,s=i.length,l=r.length;++n<s;){var u=fre(i[n],a[n]);if(u){if(n>=l)return u;var h=r[n];return u*(h=="desc"?-1:1)}}return t.index-e.index}var pre,mre=N(()=>{"use strict";dre();o(JNe,"compareMultiple");pre=JNe});function eMe(t,e,r){e.length?e=Ns(e,function(a){return Pt(a)?function(s){return Xh(s,a.length===1?a[0]:a)}:a}):e=[ta];var n=-1;e=Ns(e,Io(pn));var i=GT(t,function(a,s,l){var u=Ns(e,function(h){return h(a)});return{criteria:u,index:++n,value:a}});return ure(i,function(a,s){return pre(a,s,r)})}var gre,yre=N(()=>{"use strict";Bd();S2();rs();LL();hre();_d();mre();Cu();Un();o(eMe,"baseOrderBy");gre=eMe});var tMe,vre,xre=N(()=>{"use strict";CL();tMe=IT("length"),vre=tMe});function dMe(t){for(var e=bre.lastIndex=0;bre.test(t);)++e;return e}var wre,rMe,nMe,iMe,aMe,sMe,oMe,$L,zL,lMe,Tre,kre,Ere,cMe,Sre,Cre,uMe,hMe,fMe,bre,Are,_re=N(()=>{"use strict";wre="\\ud800-\\udfff",rMe="\\u0300-\\u036f",nMe="\\ufe20-\\ufe2f",iMe="\\u20d0-\\u20ff",aMe=rMe+nMe+iMe,sMe="\\ufe0e\\ufe0f",oMe="["+wre+"]",$L="["+aMe+"]",zL="\\ud83c[\\udffb-\\udfff]",lMe="(?:"+$L+"|"+zL+")",Tre="[^"+wre+"]",kre="(?:\\ud83c[\\udde6-\\uddff]){2}",Ere="[\\ud800-\\udbff][\\udc00-\\udfff]",cMe="\\u200d",Sre=lMe+"?",Cre="["+sMe+"]?",uMe="(?:"+cMe+"(?:"+[Tre,kre,Ere].join("|")+")"+Cre+Sre+")*",hMe=Cre+Sre+uMe,fMe="(?:"+[Tre+$L+"?",$L,kre,Ere,oMe].join("|")+")",bre=RegExp(zL+"(?="+zL+")|"+fMe+hMe,"g");o(dMe,"unicodeSize");Are=dMe});function pMe(t){return $J(t)?Are(t):vre(t)}var Dre,Lre=N(()=>{"use strict";xre();zJ();_re();o(pMe,"stringSize");Dre=pMe});function mMe(t,e){return YT(t,e,function(r,n){return MT(t,n)})}var Rre,Nre=N(()=>{"use strict";FL();SL();o(mMe,"basePick");Rre=mMe});var gMe,Vd,Mre=N(()=>{"use strict";Nre();FJ();gMe=BJ(function(t,e){return t==null?{}:Rre(t,e)}),Vd=gMe});function xMe(t,e,r,n){for(var i=-1,a=vMe(yMe((e-t)/(r||1)),0),s=Array(a);a--;)s[n?a:++i]=t,t+=r;return s}var yMe,vMe,Ire,Ore=N(()=>{"use strict";yMe=Math.ceil,vMe=Math.max;o(xMe,"baseRange");Ire=xMe});function bMe(t){return function(e,r,n){return n&&typeof n!="number"&&eo(e,r,n)&&(r=n=void 0),e=xm(e),r===void 0?(r=e,e=0):r=xm(r),n=n===void 0?e<r?1:-1:xm(n),Ire(e,r,n,t)}}var Pre,Bre=N(()=>{"use strict";Ore();Ld();rL();o(bMe,"createRange");Pre=bMe});var wMe,Go,Fre=N(()=>{"use strict";Bre();wMe=Pre(),Go=wMe});function TMe(t,e,r,n,i){return i(t,function(a,s,l){r=n?(n=!1,a):e(r,a,s,l)}),r}var $re,zre=N(()=>{"use strict";o(TMe,"baseReduce");$re=TMe});function kMe(t,e,r){var n=Pt(t)?GJ:$re,i=arguments.length<3;return n(t,pn(e,4),r,i,Ms)}var Xr,GL=N(()=>{"use strict";VJ();Kh();rs();zre();Un();o(kMe,"reduce");Xr=kMe});function EMe(t,e){var r=Pt(t)?Am:zT;return r(t,are(pn(e,3)))}var Jh,Gre=N(()=>{"use strict";fT();_L();rs();Un();sre();o(EMe,"reject");Jh=EMe});function AMe(t){if(t==null)return 0;if(ci(t))return yi(t)?Dre(t):t.length;var e=io(t);return e==SMe||e==CMe?t.size:Tm(t).length}var SMe,CMe,VL,Vre=N(()=>{"use strict";sT();$d();Mo();VT();Lre();SMe="[object Map]",CMe="[object Set]";o(AMe,"size");VL=AMe});function _Me(t,e){var r;return Ms(t,function(n,i,a){return r=e(n,i,a),!r}),!!r}var Ure,Hre=N(()=>{"use strict";Kh();o(_Me,"baseSome");Ure=_Me});function DMe(t,e,r){var n=Pt(t)?ET:Ure;return r&&eo(t,e,r)&&(e=void 0),n(t,pn(e,3))}var A2,Wre=N(()=>{"use strict";vL();rs();Hre();Un();Ld();o(DMe,"some");A2=DMe});var LMe,kc,qre=N(()=>{"use strict";Cm();yre();nm();Ld();LMe=fc(function(t,e){if(t==null)return[];var r=e.length;return r>1&&eo(t,e[0],e[1])?e=[]:r>2&&eo(e[0],e[1],e[2])&&(e=[e[0]]),gre(t,wc(e,1),[])}),kc=LMe});var RMe,NMe,Yre,Xre=N(()=>{"use strict";pL();nL();AT();RMe=1/0,NMe=jh&&1/Rm(new jh([,-0]))[1]==RMe?function(t){return new jh(t)}:ni,Yre=NMe});function IMe(t,e,r){var n=-1,i=aT,a=t.length,s=!0,l=[],u=l;if(r)s=!1,i=BT;else if(a>=MMe){var h=e?null:Yre(t);if(h)return Rm(h);s=!1,i=Lm,u=new Dm}else u=e?[]:l;e:for(;++n<a;){var f=t[n],d=e?e(f):f;if(f=r||f!==0?f:0,s&&d===d){for(var p=u.length;p--;)if(u[p]===d)continue e;e&&u.push(d),l.push(f)}else i(u,d,r)||(u!==l&&u.push(d),l.push(f))}return l}var MMe,Pm,XT=N(()=>{"use strict";kT();sL();AL();ST();Xre();AT();MMe=200;o(IMe,"baseUniq");Pm=IMe});var OMe,UL,jre=N(()=>{"use strict";Cm();nm();XT();ow();OMe=fc(function(t){return Pm(wc(t,1,Ad,!0))}),UL=OMe});function PMe(t){return t&&t.length?Pm(t):[]}var Bm,Kre=N(()=>{"use strict";XT();o(PMe,"uniq");Bm=PMe});function BMe(t,e){return t&&t.length?Pm(t,pn(e,2)):[]}var Qre,Zre=N(()=>{"use strict";rs();XT();o(BMe,"uniqBy");Qre=BMe});function $Me(t){var e=++FMe;return lT(t)+e}var FMe,Ud,Jre=N(()=>{"use strict";oL();FMe=0;o($Me,"uniqueId");Ud=$Me});function zMe(t,e,r){for(var n=-1,i=t.length,a=e.length,s={};++n<i;){var l=n<a?e[n]:void 0;r(s,t[n],l)}return s}var ene,tne=N(()=>{"use strict";o(zMe,"baseZipObject");ene=zMe});function GMe(t,e){return ene(t||[],e||[],hc)}var jT,rne=N(()=>{"use strict";rm();tne();o(GMe,"zipObject");jT=GMe});var qt=N(()=>{"use strict";CJ();gL();Lee();Ree();$9();xte();Tte();Ete();Ste();Cte();Rte();DL();Pte();Fte();RL();uT();$T();$te();zte();Gte();qte();Cu();jte();Kte();Un();HT();Yv();Js();ere();VT();tre();xc();kte();Im();rre();nre();V9();BL();ire();nL();yte();Mre();cre();Fre();GL();Gre();Vre();Wre();qre();jre();Kre();Jre();OL();rne();});function ine(t,e){t[e]?t[e]++:t[e]=1}function ane(t,e){--t[e]||delete t[e]}function _2(t,e,r,n){var i=""+e,a=""+r;if(!t&&i>a){var s=i;i=a,a=s}return i+nne+a+nne+(pr(n)?VMe:n)}function UMe(t,e,r,n){var i=""+e,a=""+r;if(!t&&i>a){var s=i;i=a,a=s}var l={v:i,w:a};return n&&(l.name=n),l}function HL(t,e){return _2(t,e.v,e.w,e.name)}var VMe,Hd,nne,sn,KT=N(()=>{"use strict";qt();VMe="\0",Hd="\0",nne="",sn=class{static{o(this,"Graph")}constructor(e={}){this._isDirected=Object.prototype.hasOwnProperty.call(e,"directed")?e.directed:!0,this._isMultigraph=Object.prototype.hasOwnProperty.call(e,"multigraph")?e.multigraph:!1,this._isCompound=Object.prototype.hasOwnProperty.call(e,"compound")?e.compound:!1,this._label=void 0,this._defaultNodeLabelFn=As(void 0),this._defaultEdgeLabelFn=As(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[Hd]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(e){return this._label=e,this}graph(){return this._label}setDefaultNodeLabel(e){return Si(e)||(e=As(e)),this._defaultNodeLabelFn=e,this}nodeCount(){return this._nodeCount}nodes(){return zr(this._nodes)}sources(){var e=this;return Yr(this.nodes(),function(r){return ur(e._in[r])})}sinks(){var e=this;return Yr(this.nodes(),function(r){return ur(e._out[r])})}setNodes(e,r){var n=arguments,i=this;return Ae(e,function(a){n.length>1?i.setNode(a,r):i.setNode(a)}),this}setNode(e,r){return Object.prototype.hasOwnProperty.call(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=r),this):(this._nodes[e]=arguments.length>1?r:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]=Hd,this._children[e]={},this._children[Hd][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return Object.prototype.hasOwnProperty.call(this._nodes,e)}removeNode(e){if(Object.prototype.hasOwnProperty.call(this._nodes,e)){var r=o(n=>this.removeEdge(this._edgeObjs[n]),"removeEdge");delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],Ae(this.children(e),n=>{this.setParent(n)}),delete this._children[e]),Ae(zr(this._in[e]),r),delete this._in[e],delete this._preds[e],Ae(zr(this._out[e]),r),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,r){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(pr(r))r=Hd;else{r+="";for(var n=r;!pr(n);n=this.parent(n))if(n===e)throw new Error("Setting "+r+" as parent of "+e+" would create a cycle");this.setNode(r)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=r,this._children[r][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var r=this._parent[e];if(r!==Hd)return r}}children(e){if(pr(e)&&(e=Hd),this._isCompound){var r=this._children[e];if(r)return zr(r)}else{if(e===Hd)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var r=this._preds[e];if(r)return zr(r)}successors(e){var r=this._sucs[e];if(r)return zr(r)}neighbors(e){var r=this.predecessors(e);if(r)return UL(r,this.successors(e))}isLeaf(e){var r;return this.isDirected()?r=this.successors(e):r=this.neighbors(e),r.length===0}filterNodes(e){var r=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});r.setGraph(this.graph());var n=this;Ae(this._nodes,function(s,l){e(l)&&r.setNode(l,s)}),Ae(this._edgeObjs,function(s){r.hasNode(s.v)&&r.hasNode(s.w)&&r.setEdge(s,n.edge(s))});var i={};function a(s){var l=n.parent(s);return l===void 0||r.hasNode(l)?(i[s]=l,l):l in i?i[l]:a(l)}return o(a,"findParent"),this._isCompound&&Ae(r.nodes(),function(s){r.setParent(s,a(s))}),r}setDefaultEdgeLabel(e){return Si(e)||(e=As(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return br(this._edgeObjs)}setPath(e,r){var n=this,i=arguments;return Xr(e,function(a,s){return i.length>1?n.setEdge(a,s,r):n.setEdge(a,s),s}),this}setEdge(){var e,r,n,i,a=!1,s=arguments[0];typeof s=="object"&&s!==null&&"v"in s?(e=s.v,r=s.w,n=s.name,arguments.length===2&&(i=arguments[1],a=!0)):(e=s,r=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],a=!0)),e=""+e,r=""+r,pr(n)||(n=""+n);var l=_2(this._isDirected,e,r,n);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,l))return a&&(this._edgeLabels[l]=i),this;if(!pr(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(r),this._edgeLabels[l]=a?i:this._defaultEdgeLabelFn(e,r,n);var u=UMe(this._isDirected,e,r,n);return e=u.v,r=u.w,Object.freeze(u),this._edgeObjs[l]=u,ine(this._preds[r],e),ine(this._sucs[e],r),this._in[r][l]=u,this._out[e][l]=u,this._edgeCount++,this}edge(e,r,n){var i=arguments.length===1?HL(this._isDirected,arguments[0]):_2(this._isDirected,e,r,n);return this._edgeLabels[i]}hasEdge(e,r,n){var i=arguments.length===1?HL(this._isDirected,arguments[0]):_2(this._isDirected,e,r,n);return Object.prototype.hasOwnProperty.call(this._edgeLabels,i)}removeEdge(e,r,n){var i=arguments.length===1?HL(this._isDirected,arguments[0]):_2(this._isDirected,e,r,n),a=this._edgeObjs[i];return a&&(e=a.v,r=a.w,delete this._edgeLabels[i],delete this._edgeObjs[i],ane(this._preds[r],e),ane(this._sucs[e],r),delete this._in[r][i],delete this._out[e][i],this._edgeCount--),this}inEdges(e,r){var n=this._in[e];if(n){var i=br(n);return r?Yr(i,function(a){return a.v===r}):i}}outEdges(e,r){var n=this._out[e];if(n){var i=br(n);return r?Yr(i,function(a){return a.w===r}):i}}nodeEdges(e,r){var n=this.inEdges(e,r);if(n)return n.concat(this.outEdges(e,r))}};sn.prototype._nodeCount=0;sn.prototype._edgeCount=0;o(ine,"incrementOrInitEntry");o(ane,"decrementOrRemoveEntry");o(_2,"edgeArgsToId");o(UMe,"edgeArgsToObj");o(HL,"edgeObjToId")});var Vo=N(()=>{"use strict";KT()});function sne(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function HMe(t,e){if(t!=="_next"&&t!=="_prev")return e}var ZT,one=N(()=>{"use strict";ZT=class{static{o(this,"List")}constructor(){var e={};e._next=e._prev=e,this._sentinel=e}dequeue(){var e=this._sentinel,r=e._prev;if(r!==e)return sne(r),r}enqueue(e){var r=this._sentinel;e._prev&&e._next&&sne(e),e._next=r._next,r._next._prev=e,r._next=e,e._prev=r}toString(){for(var e=[],r=this._sentinel,n=r._prev;n!==r;)e.push(JSON.stringify(n,HMe)),n=n._prev;return"["+e.join(", ")+"]"}};o(sne,"unlink");o(HMe,"filterOutLinks")});function lne(t,e){if(t.nodeCount()<=1)return[];var r=YMe(t,e||WMe),n=qMe(r.graph,r.buckets,r.zeroIdx);return qr(Je(n,function(i){return t.outEdges(i.v,i.w)}))}function qMe(t,e,r){for(var n=[],i=e[e.length-1],a=e[0],s;t.nodeCount();){for(;s=a.dequeue();)WL(t,e,r,s);for(;s=i.dequeue();)WL(t,e,r,s);if(t.nodeCount()){for(var l=e.length-2;l>0;--l)if(s=e[l].dequeue(),s){n=n.concat(WL(t,e,r,s,!0));break}}}return n}function WL(t,e,r,n,i){var a=i?[]:void 0;return Ae(t.inEdges(n.v),function(s){var l=t.edge(s),u=t.node(s.v);i&&a.push({v:s.v,w:s.w}),u.out-=l,qL(e,r,u)}),Ae(t.outEdges(n.v),function(s){var l=t.edge(s),u=s.w,h=t.node(u);h.in-=l,qL(e,r,h)}),t.removeNode(n.v),a}function YMe(t,e){var r=new sn,n=0,i=0;Ae(t.nodes(),function(l){r.setNode(l,{v:l,in:0,out:0})}),Ae(t.edges(),function(l){var u=r.edge(l.v,l.w)||0,h=e(l),f=u+h;r.setEdge(l.v,l.w,f),i=Math.max(i,r.node(l.v).out+=h),n=Math.max(n,r.node(l.w).in+=h)});var a=Go(i+n+3).map(function(){return new ZT}),s=n+1;return Ae(r.nodes(),function(l){qL(a,s,r.node(l))}),{graph:r,buckets:a,zeroIdx:s}}function qL(t,e,r){r.out?r.in?t[r.out-r.in+e].enqueue(r):t[t.length-1].enqueue(r):t[0].enqueue(r)}var WMe,cne=N(()=>{"use strict";qt();Vo();one();WMe=As(1);o(lne,"greedyFAS");o(qMe,"doGreedyFAS");o(WL,"removeNode");o(YMe,"buildState");o(qL,"assignBucket")});function une(t){var e=t.graph().acyclicer==="greedy"?lne(t,r(t)):XMe(t);Ae(e,function(n){var i=t.edge(n);t.removeEdge(n),i.forwardName=n.name,i.reversed=!0,t.setEdge(n.w,n.v,i,Ud("rev"))});function r(n){return function(i){return n.edge(i).weight}}o(r,"weightFn")}function XMe(t){var e=[],r={},n={};function i(a){Object.prototype.hasOwnProperty.call(n,a)||(n[a]=!0,r[a]=!0,Ae(t.outEdges(a),function(s){Object.prototype.hasOwnProperty.call(r,s.w)?e.push(s):i(s.w)}),delete r[a])}return o(i,"dfs"),Ae(t.nodes(),i),e}function hne(t){Ae(t.edges(),function(e){var r=t.edge(e);if(r.reversed){t.removeEdge(e);var n=r.forwardName;delete r.reversed,delete r.forwardName,t.setEdge(e.w,e.v,r,n)}})}var YL=N(()=>{"use strict";qt();cne();o(une,"run");o(XMe,"dfsFAS");o(hne,"undo")});function Ec(t,e,r,n){var i;do i=Ud(n);while(t.hasNode(i));return r.dummy=e,t.setNode(i,r),i}function dne(t){var e=new sn().setGraph(t.graph());return Ae(t.nodes(),function(r){e.setNode(r,t.node(r))}),Ae(t.edges(),function(r){var n=e.edge(r.v,r.w)||{weight:0,minlen:1},i=t.edge(r);e.setEdge(r.v,r.w,{weight:n.weight+i.weight,minlen:Math.max(n.minlen,i.minlen)})}),e}function JT(t){var e=new sn({multigraph:t.isMultigraph()}).setGraph(t.graph());return Ae(t.nodes(),function(r){t.children(r).length||e.setNode(r,t.node(r))}),Ae(t.edges(),function(r){e.setEdge(r,t.edge(r))}),e}function XL(t,e){var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2;if(!i&&!a)throw new Error("Not possible to find intersection inside of the rectangle");var u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=l*i/a,h=l):(i<0&&(s=-s),u=s,h=s*a/i),{x:r+u,y:n+h}}function ef(t){var e=Je(Go(KL(t)+1),function(){return[]});return Ae(t.nodes(),function(r){var n=t.node(r),i=n.rank;pr(i)||(e[i][n.order]=r)}),e}function pne(t){var e=Dl(Je(t.nodes(),function(r){return t.node(r).rank}));Ae(t.nodes(),function(r){var n=t.node(r);Bt(n,"rank")&&(n.rank-=e)})}function mne(t){var e=Dl(Je(t.nodes(),function(a){return t.node(a).rank})),r=[];Ae(t.nodes(),function(a){var s=t.node(a).rank-e;r[s]||(r[s]=[]),r[s].push(a)});var n=0,i=t.graph().nodeRankFactor;Ae(r,function(a,s){pr(a)&&s%i!==0?--n:n&&Ae(a,function(l){t.node(l).rank+=n})})}function jL(t,e,r,n){var i={width:0,height:0};return arguments.length>=4&&(i.rank=r,i.order=n),Ec(t,"border",i,e)}function KL(t){return Is(Je(t.nodes(),function(e){var r=t.node(e).rank;if(!pr(r))return r}))}function gne(t,e){var r={lhs:[],rhs:[]};return Ae(t,function(n){e(n)?r.lhs.push(n):r.rhs.push(n)}),r}function yne(t,e){var r=PT();try{return e()}finally{console.log(t+" time: "+(PT()-r)+"ms")}}function vne(t,e){return e()}var Sc=N(()=>{"use strict";qt();Vo();o(Ec,"addDummyNode");o(dne,"simplify");o(JT,"asNonCompoundGraph");o(XL,"intersectRect");o(ef,"buildLayerMatrix");o(pne,"normalizeRanks");o(mne,"removeEmptyRanks");o(jL,"addBorderNode");o(KL,"maxRank");o(gne,"partition");o(yne,"time");o(vne,"notime")});function bne(t){function e(r){var n=t.children(r),i=t.node(r);if(n.length&&Ae(n,e),Object.prototype.hasOwnProperty.call(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var a=i.minRank,s=i.maxRank+1;a<s;++a)xne(t,"borderLeft","_bl",r,i,a),xne(t,"borderRight","_br",r,i,a)}}o(e,"dfs"),Ae(t.children(),e)}function xne(t,e,r,n,i,a){var s={width:0,height:0,rank:a,borderType:e},l=i[e][a-1],u=Ec(t,"border",s,r);i[e][a]=u,t.setParent(u,n),l&&t.setEdge(l,u,{weight:1})}var wne=N(()=>{"use strict";qt();Sc();o(bne,"addBorderSegments");o(xne,"addBorderNode")});function kne(t){var e=t.graph().rankdir.toLowerCase();(e==="lr"||e==="rl")&&Sne(t)}function Ene(t){var e=t.graph().rankdir.toLowerCase();(e==="bt"||e==="rl")&&jMe(t),(e==="lr"||e==="rl")&&(KMe(t),Sne(t))}function Sne(t){Ae(t.nodes(),function(e){Tne(t.node(e))}),Ae(t.edges(),function(e){Tne(t.edge(e))})}function Tne(t){var e=t.width;t.width=t.height,t.height=e}function jMe(t){Ae(t.nodes(),function(e){QL(t.node(e))}),Ae(t.edges(),function(e){var r=t.edge(e);Ae(r.points,QL),Object.prototype.hasOwnProperty.call(r,"y")&&QL(r)})}function QL(t){t.y=-t.y}function KMe(t){Ae(t.nodes(),function(e){ZL(t.node(e))}),Ae(t.edges(),function(e){var r=t.edge(e);Ae(r.points,ZL),Object.prototype.hasOwnProperty.call(r,"x")&&ZL(r)})}function ZL(t){var e=t.x;t.x=t.y,t.y=e}var Cne=N(()=>{"use strict";qt();o(kne,"adjust");o(Ene,"undo");o(Sne,"swapWidthHeight");o(Tne,"swapWidthHeightOne");o(jMe,"reverseY");o(QL,"reverseYOne");o(KMe,"swapXY");o(ZL,"swapXYOne")});function Ane(t){t.graph().dummyChains=[],Ae(t.edges(),function(e){ZMe(t,e)})}function ZMe(t,e){var r=e.v,n=t.node(r).rank,i=e.w,a=t.node(i).rank,s=e.name,l=t.edge(e),u=l.labelRank;if(a!==n+1){t.removeEdge(e);var h=void 0,f,d;for(d=0,++n;n<a;++d,++n)l.points=[],h={width:0,height:0,edgeLabel:l,edgeObj:e,rank:n},f=Ec(t,"edge",h,"_d"),n===u&&(h.width=l.width,h.height=l.height,h.dummy="edge-label",h.labelpos=l.labelpos),t.setEdge(r,f,{weight:l.weight},s),d===0&&t.graph().dummyChains.push(f),r=f;t.setEdge(r,i,{weight:l.weight},s)}}function _ne(t){Ae(t.graph().dummyChains,function(e){var r=t.node(e),n=r.edgeLabel,i;for(t.setEdge(r.edgeObj,n);r.dummy;)i=t.successors(e)[0],t.removeNode(e),n.points.push({x:r.x,y:r.y}),r.dummy==="edge-label"&&(n.x=r.x,n.y=r.y,n.width=r.width,n.height=r.height),e=i,r=t.node(e)})}var JL=N(()=>{"use strict";qt();Sc();o(Ane,"run");o(ZMe,"normalizeEdge");o(_ne,"undo")});function D2(t){var e={};function r(n){var i=t.node(n);if(Object.prototype.hasOwnProperty.call(e,n))return i.rank;e[n]=!0;var a=Dl(Je(t.outEdges(n),function(s){return r(s.w)-t.edge(s).minlen}));return(a===Number.POSITIVE_INFINITY||a===void 0||a===null)&&(a=0),i.rank=a}o(r,"dfs"),Ae(t.sources(),r)}function Wd(t,e){return t.node(e.w).rank-t.node(e.v).rank-t.edge(e).minlen}var ek=N(()=>{"use strict";qt();o(D2,"longestPath");o(Wd,"slack")});function tk(t){var e=new sn({directed:!1}),r=t.nodes()[0],n=t.nodeCount();e.setNode(r,{});for(var i,a;JMe(e,t)<n;)i=eIe(e,t),a=e.hasNode(i.v)?Wd(t,i):-Wd(t,i),tIe(e,t,a);return e}function JMe(t,e){function r(n){Ae(e.nodeEdges(n),function(i){var a=i.v,s=n===a?i.w:a;!t.hasNode(s)&&!Wd(e,i)&&(t.setNode(s,{}),t.setEdge(n,s,{}),r(s))})}return o(r,"dfs"),Ae(t.nodes(),r),t.nodeCount()}function eIe(t,e){return Gd(e.edges(),function(r){if(t.hasNode(r.v)!==t.hasNode(r.w))return Wd(e,r)})}function tIe(t,e,r){Ae(t.nodes(),function(n){e.node(n).rank+=r})}var eR=N(()=>{"use strict";qt();Vo();ek();o(tk,"feasibleTree");o(JMe,"tightTree");o(eIe,"findMinSlackEdge");o(tIe,"shiftRanks")});var Lne=N(()=>{"use strict"});var tR=N(()=>{"use strict"});var cWt,rR=N(()=>{"use strict";qt();tR();cWt=As(1)});var Rne=N(()=>{"use strict";rR()});var nR=N(()=>{"use strict"});var Nne=N(()=>{"use strict";nR()});var bWt,Mne=N(()=>{"use strict";qt();bWt=As(1)});function iR(t){var e={},r={},n=[];function i(a){if(Object.prototype.hasOwnProperty.call(r,a))throw new L2;Object.prototype.hasOwnProperty.call(e,a)||(r[a]=!0,e[a]=!0,Ae(t.predecessors(a),i),delete r[a],n.push(a))}if(o(i,"visit"),Ae(t.sinks(),i),VL(e)!==t.nodeCount())throw new L2;return n}function L2(){}var aR=N(()=>{"use strict";qt();iR.CycleException=L2;o(iR,"topsort");o(L2,"CycleException");L2.prototype=new Error});var Ine=N(()=>{"use strict";aR()});function rk(t,e,r){Pt(e)||(e=[e]);var n=(t.isDirected()?t.successors:t.neighbors).bind(t),i=[],a={};return Ae(e,function(s){if(!t.hasNode(s))throw new Error("Graph does not have node: "+s);One(t,s,r==="post",a,n,i)}),i}function One(t,e,r,n,i,a){Object.prototype.hasOwnProperty.call(n,e)||(n[e]=!0,r||a.push(e),Ae(i(e),function(s){One(t,s,r,n,i,a)}),r&&a.push(e))}var sR=N(()=>{"use strict";qt();o(rk,"dfs");o(One,"doDfs")});function oR(t,e){return rk(t,e,"post")}var Pne=N(()=>{"use strict";sR();o(oR,"postorder")});function lR(t,e){return rk(t,e,"pre")}var Bne=N(()=>{"use strict";sR();o(lR,"preorder")});var Fne=N(()=>{"use strict";tR();KT()});var $ne=N(()=>{"use strict";Lne();rR();Rne();Nne();Mne();Ine();Pne();Bne();Fne();nR();aR()});function rf(t){t=dne(t),D2(t);var e=tk(t);uR(e),cR(e,t);for(var r,n;r=Une(e);)n=Hne(e,t,r),Wne(e,t,r,n)}function cR(t,e){var r=oR(t,t.nodes());r=r.slice(0,r.length-1),Ae(r,function(n){sIe(t,e,n)})}function sIe(t,e,r){var n=t.node(r),i=n.parent;t.edge(r,i).cutvalue=Gne(t,e,r)}function Gne(t,e,r){var n=t.node(r),i=n.parent,a=!0,s=e.edge(r,i),l=0;return s||(a=!1,s=e.edge(i,r)),l=s.weight,Ae(e.nodeEdges(r),function(u){var h=u.v===r,f=h?u.w:u.v;if(f!==i){var d=h===a,p=e.edge(u).weight;if(l+=d?p:-p,lIe(t,r,f)){var m=t.edge(r,f).cutvalue;l+=d?-m:m}}}),l}function uR(t,e){arguments.length<2&&(e=t.nodes()[0]),Vne(t,{},1,e)}function Vne(t,e,r,n,i){var a=r,s=t.node(n);return e[n]=!0,Ae(t.neighbors(n),function(l){Object.prototype.hasOwnProperty.call(e,l)||(r=Vne(t,e,r,l,n))}),s.low=a,s.lim=r++,i?s.parent=i:delete s.parent,r}function Une(t){return ns(t.edges(),function(e){return t.edge(e).cutvalue<0})}function Hne(t,e,r){var n=r.v,i=r.w;e.hasEdge(n,i)||(n=r.w,i=r.v);var a=t.node(n),s=t.node(i),l=a,u=!1;a.lim>s.lim&&(l=s,u=!0);var h=Yr(e.edges(),function(f){return u===zne(t,t.node(f.v),l)&&u!==zne(t,t.node(f.w),l)});return Gd(h,function(f){return Wd(e,f)})}function Wne(t,e,r,n){var i=r.v,a=r.w;t.removeEdge(i,a),t.setEdge(n.v,n.w,{}),uR(t),cR(t,e),oIe(t,e)}function oIe(t,e){var r=ns(t.nodes(),function(i){return!e.node(i).parent}),n=lR(t,r);n=n.slice(1),Ae(n,function(i){var a=t.node(i).parent,s=e.edge(i,a),l=!1;s||(s=e.edge(a,i),l=!0),e.node(i).rank=e.node(a).rank+(l?s.minlen:-s.minlen)})}function lIe(t,e,r){return t.hasEdge(e,r)}function zne(t,e,r){return r.low<=e.lim&&e.lim<=r.lim}var qne=N(()=>{"use strict";qt();$ne();Sc();eR();ek();rf.initLowLimValues=uR;rf.initCutValues=cR;rf.calcCutValue=Gne;rf.leaveEdge=Une;rf.enterEdge=Hne;rf.exchangeEdges=Wne;o(rf,"networkSimplex");o(cR,"initCutValues");o(sIe,"assignCutValue");o(Gne,"calcCutValue");o(uR,"initLowLimValues");o(Vne,"dfsAssignLowLim");o(Une,"leaveEdge");o(Hne,"enterEdge");o(Wne,"exchangeEdges");o(oIe,"updateRanks");o(lIe,"isTreeEdge");o(zne,"isDescendant")});function hR(t){switch(t.graph().ranker){case"network-simplex":Yne(t);break;case"tight-tree":uIe(t);break;case"longest-path":cIe(t);break;default:Yne(t)}}function uIe(t){D2(t),tk(t)}function Yne(t){rf(t)}var cIe,fR=N(()=>{"use strict";eR();qne();ek();o(hR,"rank");cIe=D2;o(uIe,"tightTreeRanker");o(Yne,"networkSimplexRanker")});function Xne(t){var e=Ec(t,"root",{},"_root"),r=hIe(t),n=Is(br(r))-1,i=2*n+1;t.graph().nestingRoot=e,Ae(t.edges(),function(s){t.edge(s).minlen*=i});var a=fIe(t)+1;Ae(t.children(),function(s){jne(t,e,i,a,n,r,s)}),t.graph().nodeRankFactor=i}function jne(t,e,r,n,i,a,s){var l=t.children(s);if(!l.length){s!==e&&t.setEdge(e,s,{weight:0,minlen:r});return}var u=jL(t,"_bt"),h=jL(t,"_bb"),f=t.node(s);t.setParent(u,s),f.borderTop=u,t.setParent(h,s),f.borderBottom=h,Ae(l,function(d){jne(t,e,r,n,i,a,d);var p=t.node(d),m=p.borderTop?p.borderTop:d,g=p.borderBottom?p.borderBottom:d,y=p.borderTop?n:2*n,v=m!==g?1:i-a[s]+1;t.setEdge(u,m,{weight:y,minlen:v,nestingEdge:!0}),t.setEdge(g,h,{weight:y,minlen:v,nestingEdge:!0})}),t.parent(s)||t.setEdge(e,u,{weight:0,minlen:i+a[s]})}function hIe(t){var e={};function r(n,i){var a=t.children(n);a&&a.length&&Ae(a,function(s){r(s,i+1)}),e[n]=i}return o(r,"dfs"),Ae(t.children(),function(n){r(n,1)}),e}function fIe(t){return Xr(t.edges(),function(e,r){return e+t.edge(r).weight},0)}function Kne(t){var e=t.graph();t.removeNode(e.nestingRoot),delete e.nestingRoot,Ae(t.edges(),function(r){var n=t.edge(r);n.nestingEdge&&t.removeEdge(r)})}var Qne=N(()=>{"use strict";qt();Sc();o(Xne,"run");o(jne,"dfs");o(hIe,"treeDepths");o(fIe,"sumWeights");o(Kne,"cleanup")});function Zne(t,e,r){var n={},i;Ae(r,function(a){for(var s=t.parent(a),l,u;s;){if(l=t.parent(s),l?(u=n[l],n[l]=s):(u=i,i=s),u&&u!==s){e.setEdge(u,s);return}s=l}})}var Jne=N(()=>{"use strict";qt();o(Zne,"addSubgraphConstraints")});function eie(t,e,r){var n=pIe(t),i=new sn({compound:!0}).setGraph({root:n}).setDefaultNodeLabel(function(a){return t.node(a)});return Ae(t.nodes(),function(a){var s=t.node(a),l=t.parent(a);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(i.setNode(a),i.setParent(a,l||n),Ae(t[r](a),function(u){var h=u.v===a?u.w:u.v,f=i.edge(h,a),d=pr(f)?0:f.weight;i.setEdge(h,a,{weight:t.edge(u).weight+d})}),Object.prototype.hasOwnProperty.call(s,"minRank")&&i.setNode(a,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))}),i}function pIe(t){for(var e;t.hasNode(e=Ud("_root")););return e}var tie=N(()=>{"use strict";qt();Vo();o(eie,"buildLayerGraph");o(pIe,"createRootNode")});function rie(t,e){for(var r=0,n=1;n<e.length;++n)r+=mIe(t,e[n-1],e[n]);return r}function mIe(t,e,r){for(var n=jT(r,Je(r,function(h,f){return f})),i=qr(Je(e,function(h){return kc(Je(t.outEdges(h),function(f){return{pos:n[f.w],weight:t.edge(f).weight}}),"pos")})),a=1;a<r.length;)a<<=1;var s=2*a-1;a-=1;var l=Je(new Array(s),function(){return 0}),u=0;return Ae(i.forEach(function(h){var f=h.pos+a;l[f]+=h.weight;for(var d=0;f>0;)f%2&&(d+=l[f+1]),f=f-1>>1,l[f]+=h.weight;u+=h.weight*d})),u}var nie=N(()=>{"use strict";qt();o(rie,"crossCount");o(mIe,"twoLayerCrossCount")});function iie(t){var e={},r=Yr(t.nodes(),function(l){return!t.children(l).length}),n=Is(Je(r,function(l){return t.node(l).rank})),i=Je(Go(n+1),function(){return[]});function a(l){if(!Bt(e,l)){e[l]=!0;var u=t.node(l);i[u.rank].push(l),Ae(t.successors(l),a)}}o(a,"dfs");var s=kc(r,function(l){return t.node(l).rank});return Ae(s,a),i}var aie=N(()=>{"use strict";qt();o(iie,"initOrder")});function sie(t,e){return Je(e,function(r){var n=t.inEdges(r);if(n.length){var i=Xr(n,function(a,s){var l=t.edge(s),u=t.node(s.v);return{sum:a.sum+l.weight*u.order,weight:a.weight+l.weight}},{sum:0,weight:0});return{v:r,barycenter:i.sum/i.weight,weight:i.weight}}else return{v:r}})}var oie=N(()=>{"use strict";qt();o(sie,"barycenter")});function lie(t,e){var r={};Ae(t,function(i,a){var s=r[i.v]={indegree:0,in:[],out:[],vs:[i.v],i:a};pr(i.barycenter)||(s.barycenter=i.barycenter,s.weight=i.weight)}),Ae(e.edges(),function(i){var a=r[i.v],s=r[i.w];!pr(a)&&!pr(s)&&(s.indegree++,a.out.push(r[i.w]))});var n=Yr(r,function(i){return!i.indegree});return gIe(n)}function gIe(t){var e=[];function r(a){return function(s){s.merged||(pr(s.barycenter)||pr(a.barycenter)||s.barycenter>=a.barycenter)&&yIe(a,s)}}o(r,"handleIn");function n(a){return function(s){s.in.push(a),--s.indegree===0&&t.push(s)}}for(o(n,"handleOut");t.length;){var i=t.pop();e.push(i),Ae(i.in.reverse(),r(i)),Ae(i.out,n(i))}return Je(Yr(e,function(a){return!a.merged}),function(a){return Vd(a,["vs","i","barycenter","weight"])})}function yIe(t,e){var r=0,n=0;t.weight&&(r+=t.barycenter*t.weight,n+=t.weight),e.weight&&(r+=e.barycenter*e.weight,n+=e.weight),t.vs=e.vs.concat(t.vs),t.barycenter=r/n,t.weight=n,t.i=Math.min(e.i,t.i),e.merged=!0}var cie=N(()=>{"use strict";qt();o(lie,"resolveConflicts");o(gIe,"doResolveConflicts");o(yIe,"mergeEntries")});function hie(t,e){var r=gne(t,function(f){return Object.prototype.hasOwnProperty.call(f,"barycenter")}),n=r.lhs,i=kc(r.rhs,function(f){return-f.i}),a=[],s=0,l=0,u=0;n.sort(vIe(!!e)),u=uie(a,i,u),Ae(n,function(f){u+=f.vs.length,a.push(f.vs),s+=f.barycenter*f.weight,l+=f.weight,u=uie(a,i,u)});var h={vs:qr(a)};return l&&(h.barycenter=s/l,h.weight=l),h}function uie(t,e,r){for(var n;e.length&&(n=ga(e)).i<=r;)e.pop(),t.push(n.vs),r++;return r}function vIe(t){return function(e,r){return e.barycenter<r.barycenter?-1:e.barycenter>r.barycenter?1:t?r.i-e.i:e.i-r.i}}var fie=N(()=>{"use strict";qt();Sc();o(hie,"sort");o(uie,"consumeUnsortable");o(vIe,"compareWithBias")});function dR(t,e,r,n){var i=t.children(e),a=t.node(e),s=a?a.borderLeft:void 0,l=a?a.borderRight:void 0,u={};s&&(i=Yr(i,function(g){return g!==s&&g!==l}));var h=sie(t,i);Ae(h,function(g){if(t.children(g.v).length){var y=dR(t,g.v,r,n);u[g.v]=y,Object.prototype.hasOwnProperty.call(y,"barycenter")&&bIe(g,y)}});var f=lie(h,r);xIe(f,u);var d=hie(f,n);if(s&&(d.vs=qr([s,d.vs,l]),t.predecessors(s).length)){var p=t.node(t.predecessors(s)[0]),m=t.node(t.predecessors(l)[0]);Object.prototype.hasOwnProperty.call(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+p.order+m.order)/(d.weight+2),d.weight+=2}return d}function xIe(t,e){Ae(t,function(r){r.vs=qr(r.vs.map(function(n){return e[n]?e[n].vs:n}))})}function bIe(t,e){pr(t.barycenter)?(t.barycenter=e.barycenter,t.weight=e.weight):(t.barycenter=(t.barycenter*t.weight+e.barycenter*e.weight)/(t.weight+e.weight),t.weight+=e.weight)}var die=N(()=>{"use strict";qt();oie();cie();fie();o(dR,"sortSubgraph");o(xIe,"expandSubgraphs");o(bIe,"mergeBarycenters")});function gie(t){var e=KL(t),r=pie(t,Go(1,e+1),"inEdges"),n=pie(t,Go(e-1,-1,-1),"outEdges"),i=iie(t);mie(t,i);for(var a=Number.POSITIVE_INFINITY,s,l=0,u=0;u<4;++l,++u){wIe(l%2?r:n,l%4>=2),i=ef(t);var h=rie(t,i);h<a&&(u=0,s=yL(i),a=h)}mie(t,s)}function pie(t,e,r){return Je(e,function(n){return eie(t,n,r)})}function wIe(t,e){var r=new sn;Ae(t,function(n){var i=n.graph().root,a=dR(n,i,r,e);Ae(a.vs,function(s,l){n.node(s).order=l}),Zne(n,r,a.vs)})}function mie(t,e){Ae(e,function(r){Ae(r,function(n,i){t.node(n).order=i})})}var yie=N(()=>{"use strict";qt();Vo();Sc();Jne();tie();nie();aie();die();o(gie,"order");o(pie,"buildLayerGraphs");o(wIe,"sweepLayerGraphs");o(mie,"assignOrder")});function vie(t){var e=kIe(t);Ae(t.graph().dummyChains,function(r){for(var n=t.node(r),i=n.edgeObj,a=TIe(t,e,i.v,i.w),s=a.path,l=a.lca,u=0,h=s[u],f=!0;r!==i.w;){if(n=t.node(r),f){for(;(h=s[u])!==l&&t.node(h).maxRank<n.rank;)u++;h===l&&(f=!1)}if(!f){for(;u<s.length-1&&t.node(h=s[u+1]).minRank<=n.rank;)u++;h=s[u]}t.setParent(r,h),r=t.successors(r)[0]}})}function TIe(t,e,r,n){var i=[],a=[],s=Math.min(e[r].low,e[n].low),l=Math.max(e[r].lim,e[n].lim),u,h;u=r;do u=t.parent(u),i.push(u);while(u&&(e[u].low>s||l>e[u].lim));for(h=u,u=n;(u=t.parent(u))!==h;)a.push(u);return{path:i.concat(a.reverse()),lca:h}}function kIe(t){var e={},r=0;function n(i){var a=r;Ae(t.children(i),n),e[i]={low:a,lim:r++}}return o(n,"dfs"),Ae(t.children(),n),e}var xie=N(()=>{"use strict";qt();o(vie,"parentDummyChains");o(TIe,"findPath");o(kIe,"postorder")});function EIe(t,e){var r={};function n(i,a){var s=0,l=0,u=i.length,h=ga(a);return Ae(a,function(f,d){var p=CIe(t,f),m=p?t.node(p).order:u;(p||f===h)&&(Ae(a.slice(l,d+1),function(g){Ae(t.predecessors(g),function(y){var v=t.node(y),x=v.order;(x<s||m<x)&&!(v.dummy&&t.node(g).dummy)&&bie(r,y,g)})}),l=d+1,s=m)}),a}return o(n,"visitLayer"),Xr(e,n),r}function SIe(t,e){var r={};function n(a,s,l,u,h){var f;Ae(Go(s,l),function(d){f=a[d],t.node(f).dummy&&Ae(t.predecessors(f),function(p){var m=t.node(p);m.dummy&&(m.order<u||m.order>h)&&bie(r,p,f)})})}o(n,"scan");function i(a,s){var l=-1,u,h=0;return Ae(s,function(f,d){if(t.node(f).dummy==="border"){var p=t.predecessors(f);p.length&&(u=t.node(p[0]).order,n(s,h,d,l,u),h=d,l=u)}n(s,h,s.length,u,a.length)}),s}return o(i,"visitLayer"),Xr(e,i),r}function CIe(t,e){if(t.node(e).dummy)return ns(t.predecessors(e),function(r){return t.node(r).dummy})}function bie(t,e,r){if(e>r){var n=e;e=r,r=n}var i=t[e];i||(t[e]=i={}),i[r]=!0}function AIe(t,e,r){if(e>r){var n=e;e=r,r=n}return!!t[e]&&Object.prototype.hasOwnProperty.call(t[e],r)}function _Ie(t,e,r,n){var i={},a={},s={};return Ae(e,function(l){Ae(l,function(u,h){i[u]=u,a[u]=u,s[u]=h})}),Ae(e,function(l){var u=-1;Ae(l,function(h){var f=n(h);if(f.length){f=kc(f,function(y){return s[y]});for(var d=(f.length-1)/2,p=Math.floor(d),m=Math.ceil(d);p<=m;++p){var g=f[p];a[h]===h&&u<s[g]&&!AIe(r,h,g)&&(a[g]=h,a[h]=i[h]=i[g],u=s[g])}}})}),{root:i,align:a}}function DIe(t,e,r,n,i){var a={},s=LIe(t,e,r,i),l=i?"borderLeft":"borderRight";function u(d,p){for(var m=s.nodes(),g=m.pop(),y={};g;)y[g]?d(g):(y[g]=!0,m.push(g),m=m.concat(p(g))),g=m.pop()}o(u,"iterate");function h(d){a[d]=s.inEdges(d).reduce(function(p,m){return Math.max(p,a[m.v]+s.edge(m))},0)}o(h,"pass1");function f(d){var p=s.outEdges(d).reduce(function(g,y){return Math.min(g,a[y.w]-s.edge(y))},Number.POSITIVE_INFINITY),m=t.node(d);p!==Number.POSITIVE_INFINITY&&m.borderType!==l&&(a[d]=Math.max(a[d],p))}return o(f,"pass2"),u(h,s.predecessors.bind(s)),u(f,s.successors.bind(s)),Ae(n,function(d){a[d]=a[r[d]]}),a}function LIe(t,e,r,n){var i=new sn,a=t.graph(),s=IIe(a.nodesep,a.edgesep,n);return Ae(e,function(l){var u;Ae(l,function(h){var f=r[h];if(i.setNode(f),u){var d=r[u],p=i.edge(d,f);i.setEdge(d,f,Math.max(s(t,h,u),p||0))}u=h})}),i}function RIe(t,e){return Gd(br(e),function(r){var n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;return NL(r,function(a,s){var l=OIe(t,s)/2;n=Math.max(a+l,n),i=Math.min(a-l,i)}),n-i})}function NIe(t,e){var r=br(e),n=Dl(r),i=Is(r);Ae(["u","d"],function(a){Ae(["l","r"],function(s){var l=a+s,u=t[l],h;if(u!==e){var f=br(u);h=s==="l"?n-Dl(f):i-Is(f),h&&(t[l]=zd(u,function(d){return d+h}))}})})}function MIe(t,e){return zd(t.ul,function(r,n){if(e)return t[e.toLowerCase()][n];var i=kc(Je(t,n));return(i[1]+i[2])/2})}function wie(t){var e=ef(t),r=Fh(EIe(t,e),SIe(t,e)),n={},i;Ae(["u","d"],function(s){i=s==="u"?e:br(e).reverse(),Ae(["l","r"],function(l){l==="r"&&(i=Je(i,function(d){return br(d).reverse()}));var u=(s==="u"?t.predecessors:t.successors).bind(t),h=_Ie(t,i,r,u),f=DIe(t,i,h.root,h.align,l==="r");l==="r"&&(f=zd(f,function(d){return-d})),n[s+l]=f})});var a=RIe(t,n);return NIe(n,a),MIe(n,t.graph().align)}function IIe(t,e,r){return function(n,i,a){var s=n.node(i),l=n.node(a),u=0,h;if(u+=s.width/2,Object.prototype.hasOwnProperty.call(s,"labelpos"))switch(s.labelpos.toLowerCase()){case"l":h=-s.width/2;break;case"r":h=s.width/2;break}if(h&&(u+=r?h:-h),h=0,u+=(s.dummy?e:t)/2,u+=(l.dummy?e:t)/2,u+=l.width/2,Object.prototype.hasOwnProperty.call(l,"labelpos"))switch(l.labelpos.toLowerCase()){case"l":h=l.width/2;break;case"r":h=-l.width/2;break}return h&&(u+=r?h:-h),h=0,u}}function OIe(t,e){return t.node(e).width}var Tie=N(()=>{"use strict";qt();Vo();Sc();o(EIe,"findType1Conflicts");o(SIe,"findType2Conflicts");o(CIe,"findOtherInnerSegmentNode");o(bie,"addConflict");o(AIe,"hasConflict");o(_Ie,"verticalAlignment");o(DIe,"horizontalCompaction");o(LIe,"buildBlockGraph");o(RIe,"findSmallestWidthAlignment");o(NIe,"alignCoordinates");o(MIe,"balance");o(wie,"positionX");o(IIe,"sep");o(OIe,"width")});function kie(t){t=JT(t),PIe(t),ML(wie(t),function(e,r){t.node(r).x=e})}function PIe(t){var e=ef(t),r=t.graph().ranksep,n=0;Ae(e,function(i){var a=Is(Je(i,function(s){return t.node(s).height}));Ae(i,function(s){t.node(s).y=n+a/2}),n+=a+r})}var Eie=N(()=>{"use strict";qt();Sc();Tie();o(kie,"position");o(PIe,"positionY")});function R2(t,e){var r=e&&e.debugTiming?yne:vne;r("layout",()=>{var n=r(" buildLayoutGraph",()=>YIe(t));r(" runLayout",()=>BIe(n,r)),r(" updateInputGraph",()=>FIe(t,n))})}function BIe(t,e){e(" makeSpaceForEdgeLabels",()=>XIe(t)),e(" removeSelfEdges",()=>nOe(t)),e(" acyclic",()=>une(t)),e(" nestingGraph.run",()=>Xne(t)),e(" rank",()=>hR(JT(t))),e(" injectEdgeLabelProxies",()=>jIe(t)),e(" removeEmptyRanks",()=>mne(t)),e(" nestingGraph.cleanup",()=>Kne(t)),e(" normalizeRanks",()=>pne(t)),e(" assignRankMinMax",()=>KIe(t)),e(" removeEdgeLabelProxies",()=>QIe(t)),e(" normalize.run",()=>Ane(t)),e(" parentDummyChains",()=>vie(t)),e(" addBorderSegments",()=>bne(t)),e(" order",()=>gie(t)),e(" insertSelfEdges",()=>iOe(t)),e(" adjustCoordinateSystem",()=>kne(t)),e(" position",()=>kie(t)),e(" positionSelfEdges",()=>aOe(t)),e(" removeBorderNodes",()=>rOe(t)),e(" normalize.undo",()=>_ne(t)),e(" fixupEdgeLabelCoords",()=>eOe(t)),e(" undoCoordinateSystem",()=>Ene(t)),e(" translateGraph",()=>ZIe(t)),e(" assignNodeIntersects",()=>JIe(t)),e(" reversePoints",()=>tOe(t)),e(" acyclic.undo",()=>hne(t))}function FIe(t,e){Ae(t.nodes(),function(r){var n=t.node(r),i=e.node(r);n&&(n.x=i.x,n.y=i.y,e.children(r).length&&(n.width=i.width,n.height=i.height))}),Ae(t.edges(),function(r){var n=t.edge(r),i=e.edge(r);n.points=i.points,Object.prototype.hasOwnProperty.call(i,"x")&&(n.x=i.x,n.y=i.y)}),t.graph().width=e.graph().width,t.graph().height=e.graph().height}function YIe(t){var e=new sn({multigraph:!0,compound:!0}),r=mR(t.graph());return e.setGraph(Fh({},zIe,pR(r,$Ie),Vd(r,GIe))),Ae(t.nodes(),function(n){var i=mR(t.node(n));e.setNode(n,Qh(pR(i,VIe),UIe)),e.setParent(n,t.parent(n))}),Ae(t.edges(),function(n){var i=mR(t.edge(n));e.setEdge(n,Fh({},WIe,pR(i,HIe),Vd(i,qIe)))}),e}function XIe(t){var e=t.graph();e.ranksep/=2,Ae(t.edges(),function(r){var n=t.edge(r);n.minlen*=2,n.labelpos.toLowerCase()!=="c"&&(e.rankdir==="TB"||e.rankdir==="BT"?n.width+=n.labeloffset:n.height+=n.labeloffset)})}function jIe(t){Ae(t.edges(),function(e){var r=t.edge(e);if(r.width&&r.height){var n=t.node(e.v),i=t.node(e.w),a={rank:(i.rank-n.rank)/2+n.rank,e};Ec(t,"edge-proxy",a,"_ep")}})}function KIe(t){var e=0;Ae(t.nodes(),function(r){var n=t.node(r);n.borderTop&&(n.minRank=t.node(n.borderTop).rank,n.maxRank=t.node(n.borderBottom).rank,e=Is(e,n.maxRank))}),t.graph().maxRank=e}function QIe(t){Ae(t.nodes(),function(e){var r=t.node(e);r.dummy==="edge-proxy"&&(t.edge(r.e).labelRank=r.rank,t.removeNode(e))})}function ZIe(t){var e=Number.POSITIVE_INFINITY,r=0,n=Number.POSITIVE_INFINITY,i=0,a=t.graph(),s=a.marginx||0,l=a.marginy||0;function u(h){var f=h.x,d=h.y,p=h.width,m=h.height;e=Math.min(e,f-p/2),r=Math.max(r,f+p/2),n=Math.min(n,d-m/2),i=Math.max(i,d+m/2)}o(u,"getExtremes"),Ae(t.nodes(),function(h){u(t.node(h))}),Ae(t.edges(),function(h){var f=t.edge(h);Object.prototype.hasOwnProperty.call(f,"x")&&u(f)}),e-=s,n-=l,Ae(t.nodes(),function(h){var f=t.node(h);f.x-=e,f.y-=n}),Ae(t.edges(),function(h){var f=t.edge(h);Ae(f.points,function(d){d.x-=e,d.y-=n}),Object.prototype.hasOwnProperty.call(f,"x")&&(f.x-=e),Object.prototype.hasOwnProperty.call(f,"y")&&(f.y-=n)}),a.width=r-e+s,a.height=i-n+l}function JIe(t){Ae(t.edges(),function(e){var r=t.edge(e),n=t.node(e.v),i=t.node(e.w),a,s;r.points?(a=r.points[0],s=r.points[r.points.length-1]):(r.points=[],a=i,s=n),r.points.unshift(XL(n,a)),r.points.push(XL(i,s))})}function eOe(t){Ae(t.edges(),function(e){var r=t.edge(e);if(Object.prototype.hasOwnProperty.call(r,"x"))switch((r.labelpos==="l"||r.labelpos==="r")&&(r.width-=r.labeloffset),r.labelpos){case"l":r.x-=r.width/2+r.labeloffset;break;case"r":r.x+=r.width/2+r.labeloffset;break}})}function tOe(t){Ae(t.edges(),function(e){var r=t.edge(e);r.reversed&&r.points.reverse()})}function rOe(t){Ae(t.nodes(),function(e){if(t.children(e).length){var r=t.node(e),n=t.node(r.borderTop),i=t.node(r.borderBottom),a=t.node(ga(r.borderLeft)),s=t.node(ga(r.borderRight));r.width=Math.abs(s.x-a.x),r.height=Math.abs(i.y-n.y),r.x=a.x+r.width/2,r.y=n.y+r.height/2}}),Ae(t.nodes(),function(e){t.node(e).dummy==="border"&&t.removeNode(e)})}function nOe(t){Ae(t.edges(),function(e){if(e.v===e.w){var r=t.node(e.v);r.selfEdges||(r.selfEdges=[]),r.selfEdges.push({e,label:t.edge(e)}),t.removeEdge(e)}})}function iOe(t){var e=ef(t);Ae(e,function(r){var n=0;Ae(r,function(i,a){var s=t.node(i);s.order=a+n,Ae(s.selfEdges,function(l){Ec(t,"selfedge",{width:l.label.width,height:l.label.height,rank:s.rank,order:a+ ++n,e:l.e,label:l.label},"_se")}),delete s.selfEdges})})}function aOe(t){Ae(t.nodes(),function(e){var r=t.node(e);if(r.dummy==="selfedge"){var n=t.node(r.e.v),i=n.x+n.width/2,a=n.y,s=r.x-i,l=n.height/2;t.setEdge(r.e,r.label),t.removeNode(e),r.label.points=[{x:i+2*s/3,y:a-l},{x:i+5*s/6,y:a-l},{x:i+s,y:a},{x:i+5*s/6,y:a+l},{x:i+2*s/3,y:a+l}],r.label.x=r.x,r.label.y=r.y}})}function pR(t,e){return zd(Vd(t,e),Number)}function mR(t){var e={};return Ae(t,function(r,n){e[n.toLowerCase()]=r}),e}var $Ie,zIe,GIe,VIe,UIe,HIe,WIe,qIe,Sie=N(()=>{"use strict";qt();Vo();wne();Cne();YL();JL();fR();Qne();yie();xie();Eie();Sc();o(R2,"layout");o(BIe,"runLayout");o(FIe,"updateInputGraph");$Ie=["nodesep","edgesep","ranksep","marginx","marginy"],zIe={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},GIe=["acyclicer","ranker","rankdir","align"],VIe=["width","height"],UIe={width:0,height:0},HIe=["minlen","weight","width","height","labeloffset"],WIe={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},qIe=["labelpos"];o(YIe,"buildLayoutGraph");o(XIe,"makeSpaceForEdgeLabels");o(jIe,"injectEdgeLabelProxies");o(KIe,"assignRankMinMax");o(QIe,"removeEdgeLabelProxies");o(ZIe,"translateGraph");o(JIe,"assignNodeIntersects");o(eOe,"fixupEdgeLabelCoords");o(tOe,"reversePointsForReversedEdges");o(rOe,"removeBorderNodes");o(nOe,"removeSelfEdges");o(iOe,"insertSelfEdges");o(aOe,"positionSelfEdges");o(pR,"selectNumberAttrs");o(mR,"canonicalize")});var gR=N(()=>{"use strict";YL();Sie();JL();fR()});function Uo(t){var e={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:sOe(t),edges:oOe(t)};return pr(t.graph())||(e.value=an(t.graph())),e}function sOe(t){return Je(t.nodes(),function(e){var r=t.node(e),n=t.parent(e),i={v:e};return pr(r)||(i.value=r),pr(n)||(i.parent=n),i})}function oOe(t){return Je(t.edges(),function(e){var r=t.edge(e),n={v:e.v,w:e.w};return pr(e.name)||(n.name=e.name),pr(r)||(n.value=r),n})}var yR=N(()=>{"use strict";qt();KT();o(Uo,"write");o(sOe,"writeNodes");o(oOe,"writeEdges")});var wr,qd,_ie,Die,nk,lOe,Lie,Rie,cOe,Fm,Aie,Nie,Mie,Iie,Oie,Pie=N(()=>{"use strict";vt();Vo();yR();wr=new Map,qd=new Map,_ie=new Map,Die=o(()=>{qd.clear(),_ie.clear(),wr.clear()},"clear"),nk=o((t,e)=>{let r=qd.get(e)||[];return Y.trace("In isDescendant",e," ",t," = ",r.includes(t)),r.includes(t)},"isDescendant"),lOe=o((t,e)=>{let r=qd.get(e)||[];return Y.info("Descendants of ",e," is ",r),Y.info("Edge is ",t),t.v===e||t.w===e?!1:r?r.includes(t.v)||nk(t.v,e)||nk(t.w,e)||r.includes(t.w):(Y.debug("Tilt, ",e,",not in descendants"),!1)},"edgeInCluster"),Lie=o((t,e,r,n)=>{Y.warn("Copying children of ",t,"root",n,"data",e.node(t),n);let i=e.children(t)||[];t!==n&&i.push(t),Y.warn("Copying (nodes) clusterId",t,"nodes",i),i.forEach(a=>{if(e.children(a).length>0)Lie(a,e,r,n);else{let s=e.node(a);Y.info("cp ",a," to ",n," with parent ",t),r.setNode(a,s),n!==e.parent(a)&&(Y.warn("Setting parent",a,e.parent(a)),r.setParent(a,e.parent(a))),t!==n&&a!==t?(Y.debug("Setting parent",a,t),r.setParent(a,t)):(Y.info("In copy ",t,"root",n,"data",e.node(t),n),Y.debug("Not Setting parent for node=",a,"cluster!==rootId",t!==n,"node!==clusterId",a!==t));let l=e.edges(a);Y.debug("Copying Edges",l),l.forEach(u=>{Y.info("Edge",u);let h=e.edge(u.v,u.w,u.name);Y.info("Edge data",h,n);try{lOe(u,n)?(Y.info("Copying as ",u.v,u.w,h,u.name),r.setEdge(u.v,u.w,h,u.name),Y.info("newGraph edges ",r.edges(),r.edge(r.edges()[0]))):Y.info("Skipping copy of edge ",u.v,"-->",u.w," rootId: ",n," clusterId:",t)}catch(f){Y.error(f)}})}Y.debug("Removing node",a),e.removeNode(a)})},"copy"),Rie=o((t,e)=>{let r=e.children(t),n=[...r];for(let i of r)_ie.set(i,t),n=[...n,...Rie(i,e)];return n},"extractDescendants"),cOe=o((t,e,r)=>{let n=t.edges().filter(u=>u.v===e||u.w===e),i=t.edges().filter(u=>u.v===r||u.w===r),a=n.map(u=>({v:u.v===e?r:u.v,w:u.w===e?e:u.w})),s=i.map(u=>({v:u.v,w:u.w}));return a.filter(u=>s.some(h=>u.v===h.v&&u.w===h.w))},"findCommonEdges"),Fm=o((t,e,r)=>{let n=e.children(t);if(Y.trace("Searching children of id ",t,n),n.length<1)return t;let i;for(let a of n){let s=Fm(a,e,r),l=cOe(e,r,s);if(s)if(l.length>0)i=s;else return s}return i},"findNonClusterChild"),Aie=o(t=>!wr.has(t)||!wr.get(t).externalConnections?t:wr.has(t)?wr.get(t).id:t,"getAnchorId"),Nie=o((t,e)=>{if(!t||e>10){Y.debug("Opting out, no graph ");return}else Y.debug("Opting in, graph ");t.nodes().forEach(function(r){t.children(r).length>0&&(Y.warn("Cluster identified",r," Replacement id in edges: ",Fm(r,t,r)),qd.set(r,Rie(r,t)),wr.set(r,{id:Fm(r,t,r),clusterData:t.node(r)}))}),t.nodes().forEach(function(r){let n=t.children(r),i=t.edges();n.length>0?(Y.debug("Cluster identified",r,qd),i.forEach(a=>{let s=nk(a.v,r),l=nk(a.w,r);s^l&&(Y.warn("Edge: ",a," leaves cluster ",r),Y.warn("Descendants of XXX ",r,": ",qd.get(r)),wr.get(r).externalConnections=!0)})):Y.debug("Not a cluster ",r,qd)});for(let r of wr.keys()){let n=wr.get(r).id,i=t.parent(n);i!==r&&wr.has(i)&&!wr.get(i).externalConnections&&(wr.get(r).id=i)}t.edges().forEach(function(r){let n=t.edge(r);Y.warn("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(r)),Y.warn("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(t.edge(r)));let i=r.v,a=r.w;if(Y.warn("Fix XXX",wr,"ids:",r.v,r.w,"Translating: ",wr.get(r.v)," --- ",wr.get(r.w)),wr.get(r.v)||wr.get(r.w)){if(Y.warn("Fixing and trying - removing XXX",r.v,r.w,r.name),i=Aie(r.v),a=Aie(r.w),t.removeEdge(r.v,r.w,r.name),i!==r.v){let s=t.parent(i);wr.get(s).externalConnections=!0,n.fromCluster=r.v}if(a!==r.w){let s=t.parent(a);wr.get(s).externalConnections=!0,n.toCluster=r.w}Y.warn("Fix Replacing with XXX",i,a,r.name),t.setEdge(i,a,n,r.name)}}),Y.warn("Adjusted Graph",Uo(t)),Mie(t,0),Y.trace(wr)},"adjustClustersAndEdges"),Mie=o((t,e)=>{if(Y.warn("extractor - ",e,Uo(t),t.children("D")),e>10){Y.error("Bailing out");return}let r=t.nodes(),n=!1;for(let i of r){let a=t.children(i);n=n||a.length>0}if(!n){Y.debug("Done, no node has children",t.nodes());return}Y.debug("Nodes = ",r,e);for(let i of r)if(Y.debug("Extracting node",i,wr,wr.has(i)&&!wr.get(i).externalConnections,!t.parent(i),t.node(i),t.children("D")," Depth ",e),!wr.has(i))Y.debug("Not a cluster",i,e);else if(!wr.get(i).externalConnections&&t.children(i)&&t.children(i).length>0){Y.warn("Cluster without external connections, without a parent and with children",i,e);let s=t.graph().rankdir==="TB"?"LR":"TB";wr.get(i)?.clusterData?.dir&&(s=wr.get(i).clusterData.dir,Y.warn("Fixing dir",wr.get(i).clusterData.dir,s));let l=new sn({multigraph:!0,compound:!0}).setGraph({rankdir:s,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});Y.warn("Old graph before copy",Uo(t)),Lie(i,t,l,i),t.setNode(i,{clusterNode:!0,id:i,clusterData:wr.get(i).clusterData,label:wr.get(i).label,graph:l}),Y.warn("New graph after copy node: (",i,")",Uo(l)),Y.debug("Old graph after copy",Uo(t))}else Y.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!wr.get(i).externalConnections," no parent: ",!t.parent(i)," children ",t.children(i)&&t.children(i).length>0,t.children("D"),e),Y.debug(wr);r=t.nodes(),Y.warn("New list of nodes",r);for(let i of r){let a=t.node(i);Y.warn(" Now next level",i,a),a?.clusterNode&&Mie(a.graph,e+1)}},"extractor"),Iie=o((t,e)=>{if(e.length===0)return[];let r=Object.assign([],e);return e.forEach(n=>{let i=t.children(n),a=Iie(t,i);r=[...r,...a]}),r},"sorter"),Oie=o(t=>Iie(t,t.children()),"sortNodesByHierarchy")});var Fie={};hr(Fie,{render:()=>uOe});var Bie,uOe,$ie=N(()=>{"use strict";gR();yR();Vo();tL();Ft();Pie();eT();Hw();eL();vt();w2();zt();Bie=o(async(t,e,r,n,i,a)=>{Y.warn("Graph in recursive render:XAX",Uo(e),i);let s=e.graph().rankdir;Y.trace("Dir in recursive render - dir:",s);let l=t.insert("g").attr("class","root");e.nodes()?Y.info("Recursive render XXX",e.nodes()):Y.info("No nodes found for",e),e.edges().length>0&&Y.info("Recursive edges",e.edge(e.edges()[0]));let u=l.insert("g").attr("class","clusters"),h=l.insert("g").attr("class","edgePaths"),f=l.insert("g").attr("class","edgeLabels"),d=l.insert("g").attr("class","nodes");await Promise.all(e.nodes().map(async function(y){let v=e.node(y);if(i!==void 0){let x=JSON.parse(JSON.stringify(i.clusterData));Y.trace(`Setting data for parent cluster XXX
+ Node.id = `,y,`
+ data=`,x.height,`
+Parent cluster`,i.height),e.setNode(i.id,x),e.parent(y)||(Y.trace("Setting parent",y,i.id),e.setParent(y,i.id,x))}if(Y.info("(Insert) Node XXX"+y+": "+JSON.stringify(e.node(y))),v?.clusterNode){Y.info("Cluster identified XBX",y,v.width,e.node(y));let{ranksep:x,nodesep:b}=e.graph();v.graph.setGraph({...v.graph.graph(),ranksep:x+25,nodesep:b});let w=await Bie(d,v.graph,r,n,e.node(y),a),C=w.elem;je(v,C),v.diff=w.diff||0,Y.info("New compound node after recursive render XAX",y,"width",v.width,"height",v.height),rJ(C,v)}else e.children(y).length>0?(Y.trace("Cluster - the non recursive path XBX",y,v.id,v,v.width,"Graph:",e),Y.trace(Fm(v.id,e)),wr.set(v.id,{id:Fm(v.id,e),node:v})):(Y.trace("Node - the non recursive path XAX",y,d,e.node(y),s),await vm(d,e.node(y),{config:a,dir:s}))})),await o(async()=>{let y=e.edges().map(async function(v){let x=e.edge(v.v,v.w,v.name);Y.info("Edge "+v.v+" -> "+v.w+": "+JSON.stringify(v)),Y.info("Edge "+v.v+" -> "+v.w+": ",v," ",JSON.stringify(e.edge(v))),Y.info("Fix",wr,"ids:",v.v,v.w,"Translating: ",wr.get(v.v),wr.get(v.w)),await jw(f,x)});await Promise.all(y)},"processEdges")(),Y.info("Graph before layout:",JSON.stringify(Uo(e))),Y.info("############################################# XXX"),Y.info("### Layout ### XXX"),Y.info("############################################# XXX"),R2(e),Y.info("Graph after layout:",JSON.stringify(Uo(e)));let m=0,{subGraphTitleTotalMargin:g}=Ru(a);return await Promise.all(Oie(e).map(async function(y){let v=e.node(y);if(Y.info("Position XBX => "+y+": ("+v.x,","+v.y,") width: ",v.width," height: ",v.height),v?.clusterNode)v.y+=g,Y.info("A tainted cluster node XBX1",y,v.id,v.width,v.height,v.x,v.y,e.parent(y)),wr.get(v.id).node=v,k2(v);else if(e.children(y).length>0){Y.info("A pure cluster node XBX1",y,v.id,v.x,v.y,v.width,v.height,e.parent(y)),v.height+=g,e.node(v.parentId);let x=v?.padding/2||0,b=v?.labelBBox?.height||0,w=b-x||0;Y.debug("OffsetY",w,"labelHeight",b,"halfPadding",x),await ym(u,v),wr.get(v.id).node=v}else{let x=e.node(v.parentId);v.y+=g/2,Y.info("A regular node XBX1 - using the padding",v.id,"parent",v.parentId,v.width,v.height,v.x,v.y,"offsetY",v.offsetY,"parent",x,x?.offsetY,v),k2(v)}})),e.edges().forEach(function(y){let v=e.edge(y);Y.info("Edge "+y.v+" -> "+y.w+": "+JSON.stringify(v),v),v.points.forEach(C=>C.y+=g/2);let x=e.node(y.v);var b=e.node(y.w);let w=Qw(h,v,wr,r,x,b,n);Kw(v,w)}),e.nodes().forEach(function(y){let v=e.node(y);Y.info(y,v.type,v.diff),v.isGroup&&(m=v.diff)}),Y.warn("Returning from recursive render XAX",l,m),{elem:l,diff:m}},"recursiveRender"),uOe=o(async(t,e)=>{let r=new sn({multigraph:!0,compound:!0}).setGraph({rankdir:t.direction,nodesep:t.config?.nodeSpacing||t.config?.flowchart?.nodeSpacing||t.nodeSpacing,ranksep:t.config?.rankSpacing||t.config?.flowchart?.rankSpacing||t.rankSpacing,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),n=e.select("g");Zw(n,t.markers,t.type,t.diagramId),nJ(),tJ(),jZ(),Die(),t.nodes.forEach(a=>{r.setNode(a.id,{...a}),a.parentId&&r.setParent(a.id,a.parentId)}),Y.debug("Edges:",t.edges),t.edges.forEach(a=>{if(a.start===a.end){let s=a.start,l=s+"---"+s+"---1",u=s+"---"+s+"---2",h=r.node(s);r.setNode(l,{domId:l,id:l,parentId:h.parentId,labelStyle:"",label:"",padding:0,shape:"labelRect",style:"",width:10,height:10}),r.setParent(l,h.parentId),r.setNode(u,{domId:u,id:u,parentId:h.parentId,labelStyle:"",padding:0,shape:"labelRect",label:"",style:"",width:10,height:10}),r.setParent(u,h.parentId);let f=structuredClone(a),d=structuredClone(a),p=structuredClone(a);f.label="",f.arrowTypeEnd="none",f.id=s+"-cyclic-special-1",d.arrowTypeStart="none",d.arrowTypeEnd="none",d.id=s+"-cyclic-special-mid",p.label="",h.isGroup&&(f.fromCluster=s,p.toCluster=s),p.id=s+"-cyclic-special-2",p.arrowTypeStart="none",r.setEdge(s,l,f,s+"-cyclic-special-0"),r.setEdge(l,u,d,s+"-cyclic-special-1"),r.setEdge(u,s,p,s+"-cyc<lic-special-2")}else r.setEdge(a.start,a.end,{...a},a.id)}),Y.warn("Graph at first:",JSON.stringify(Uo(r))),Nie(r),Y.warn("Graph after XAX:",JSON.stringify(Uo(r)));let i=me();await Bie(n,r,t.type,t.diagramId,void 0,i)},"render")});var N2,vR,hOe,Cc,nf,Yd=N(()=>{"use strict";aJ();vt();N2={},vR=o(t=>{for(let e of t)N2[e.name]=e},"registerLayoutLoaders"),hOe=o(()=>{vR([{name:"dagre",loader:o(async()=>await Promise.resolve().then(()=>($ie(),Fie)),"loader")}])},"registerDefaultLayoutLoaders");hOe();Cc=o(async(t,e)=>{if(!(t.layoutAlgorithm in N2))throw new Error(`Unknown layout algorithm: ${t.layoutAlgorithm}`);let r=N2[t.layoutAlgorithm];return(await r.loader()).render(t,e,iJ,{algorithm:r.algorithm})},"render"),nf=o((t="",{fallback:e="dagre"}={})=>{if(t in N2)return t;if(e in N2)return Y.warn(`Layout algorithm ${t} is not registered. Using ${e} as fallback.`),e;throw new Error(`Both layout algorithms ${t} and ${e} are not registered.`)},"getRegisteredLayoutAlgorithm")});var Ac,fOe,dOe,$m=N(()=>{"use strict";Ei();vt();Ac=o((t,e,r,n)=>{t.attr("class",r);let{width:i,height:a,x:s,y:l}=fOe(t,e);vn(t,a,i,n);let u=dOe(s,l,i,a,e);t.attr("viewBox",u),Y.debug(`viewBox configured: ${u} with padding: ${e}`)},"setupViewPortForSVG"),fOe=o((t,e)=>{let r=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:r.width+e*2,height:r.height+e*2,x:r.x,y:r.y}},"calculateDimensionsWithPadding"),dOe=o((t,e,r,n,i)=>`${t-i} ${e-i} ${r} ${n}`,"createViewBox")});var pOe,mOe,zie,Gie=N(()=>{"use strict";dr();zt();vt();gm();Yd();$m();ir();pOe=o(function(t,e){return e.db.getClasses()},"getClasses"),mOe=o(async function(t,e,r,n){Y.info("REF0:"),Y.info("Drawing state diagram (v2)",e);let{securityLevel:i,flowchart:a,layout:s}=me(),l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?l.nodes()[0].contentDocument:document;Y.debug("Before getData: ");let h=n.db.getData();Y.debug("Data: ",h);let f=yc(e,i),d=n.db.getDirection();h.type=n.type,h.layoutAlgorithm=nf(s),h.layoutAlgorithm==="dagre"&&s==="elk"&&Y.warn("flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0) for more details. This diagram will be rendered using `dagre` layout as a fallback."),h.direction=d,h.nodeSpacing=a?.nodeSpacing||50,h.rankSpacing=a?.rankSpacing||50,h.markers=["point","circle","cross"],h.diagramId=e,Y.debug("REF1:",h),await Cc(h,f);let p=h.config.flowchart?.diagramPadding??8;Gt.insertTitle(f,"flowchartTitleText",a?.titleTopMargin||0,n.db.getDiagramTitle()),Ac(f,p,"flowchart",a?.useMaxWidth||!1);for(let m of h.nodes){let g=Ge(`#${e} [id="${m.id}"]`);if(!g||!m.link)continue;let y=u.createElementNS("http://www.w3.org/2000/svg","a");y.setAttributeNS("http://www.w3.org/2000/svg","class",m.cssClasses),y.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),i==="sandbox"?y.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):m.linkTarget&&y.setAttributeNS("http://www.w3.org/2000/svg","target",m.linkTarget);let v=g.insert(function(){return y},":first-child"),x=g.select(".label-container");x&&v.append(function(){return x.node()});let b=g.select(".label");b&&v.append(function(){return b.node()})}},"draw"),zie={getClasses:pOe,draw:mOe}});var xR,bR,Vie=N(()=>{"use strict";xR=function(){var t=o(function(Hr,et,mt,Kt){for(mt=mt||{},Kt=Hr.length;Kt--;mt[Hr[Kt]]=et);return mt},"o"),e=[1,4],r=[1,3],n=[1,5],i=[1,8,9,10,11,27,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],a=[2,2],s=[1,13],l=[1,14],u=[1,15],h=[1,16],f=[1,23],d=[1,25],p=[1,26],m=[1,27],g=[1,49],y=[1,48],v=[1,29],x=[1,30],b=[1,31],w=[1,32],C=[1,33],T=[1,44],E=[1,46],A=[1,42],S=[1,47],_=[1,43],I=[1,50],D=[1,45],k=[1,51],L=[1,52],R=[1,34],O=[1,35],M=[1,36],B=[1,37],F=[1,57],P=[1,8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],z=[1,61],$=[1,60],H=[1,62],Q=[8,9,11,75,77,78],j=[1,78],ie=[1,91],ne=[1,96],le=[1,95],he=[1,92],K=[1,88],X=[1,94],te=[1,90],J=[1,97],se=[1,93],ue=[1,98],Z=[1,89],Se=[8,9,10,11,40,75,77,78],ce=[8,9,10,11,40,46,75,77,78],ae=[8,9,10,11,29,40,44,46,48,50,52,54,56,58,60,63,65,67,68,70,75,77,78,89,102,105,106,109,111,114,115,116],Oe=[8,9,11,44,60,75,77,78,89,102,105,106,109,111,114,115,116],ge=[44,60,89,102,105,106,109,111,114,115,116],ze=[1,121],He=[1,122],$e=[1,124],Re=[1,123],Ie=[44,60,62,74,89,102,105,106,109,111,114,115,116],be=[1,133],W=[1,147],de=[1,148],re=[1,149],oe=[1,150],V=[1,135],xe=[1,137],q=[1,141],pe=[1,142],ve=[1,143],Pe=[1,144],_e=[1,145],we=[1,146],Ve=[1,151],De=[1,152],qe=[1,131],at=[1,132],Rt=[1,139],st=[1,134],Ue=[1,138],ct=[1,136],We=[8,9,10,11,27,32,34,36,38,44,60,84,85,86,87,88,89,102,105,106,109,111,114,115,116,121,122,123,124],ot=[1,154],Yt=[1,156],bt=[8,9,11],Mt=[8,9,10,11,14,44,60,89,105,106,109,111,114,115,116],xt=[1,176],ut=[1,172],Et=[1,173],ft=[1,177],yt=[1,174],nt=[1,175],dn=[77,116,119],Tt=[8,9,10,11,12,14,27,29,32,44,60,75,84,85,86,87,88,89,90,105,109,111,114,115,116],On=[10,106],tn=[31,49,51,53,55,57,62,64,66,67,69,71,116,117,118],_r=[1,247],Dr=[1,245],Pn=[1,249],At=[1,243],Ce=[1,244],tt=[1,246],St=[1,248],mr=[1,250],rn=[1,268],gn=[8,9,11,106],Zr=[8,9,10,11,60,84,105,106,109,110,111,112],Ni={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,shapeData:39,SHAPE_DATA:40,link:41,node:42,styledVertex:43,AMP:44,vertex:45,STYLE_SEPARATOR:46,idString:47,DOUBLECIRCLESTART:48,DOUBLECIRCLEEND:49,PS:50,PE:51,"(-":52,"-)":53,STADIUMSTART:54,STADIUMEND:55,SUBROUTINESTART:56,SUBROUTINEEND:57,VERTEX_WITH_PROPS_START:58,"NODE_STRING[field]":59,COLON:60,"NODE_STRING[value]":61,PIPE:62,CYLINDERSTART:63,CYLINDEREND:64,DIAMOND_START:65,DIAMOND_STOP:66,TAGEND:67,TRAPSTART:68,TRAPEND:69,INVTRAPSTART:70,INVTRAPEND:71,linkStatement:72,arrowText:73,TESTSTR:74,START_LINK:75,edgeText:76,LINK:77,LINK_ID:78,edgeTextToken:79,STR:80,MD_STR:81,textToken:82,keywords:83,STYLE:84,LINKSTYLE:85,CLASSDEF:86,CLASS:87,CLICK:88,DOWN:89,UP:90,textNoTagsToken:91,stylesOpt:92,"idString[vertex]":93,"idString[class]":94,CALLBACKNAME:95,CALLBACKARGS:96,HREF:97,LINK_TARGET:98,"STR[link]":99,"STR[tooltip]":100,alphaNum:101,DEFAULT:102,numList:103,INTERPOLATE:104,NUM:105,COMMA:106,style:107,styleComponent:108,NODE_STRING:109,UNIT:110,BRKT:111,PCT:112,idStringToken:113,MINUS:114,MULT:115,UNICODE_TEXT:116,TEXT:117,TAGSTART:118,EDGE_TEXT:119,alphaNumToken:120,direction_tb:121,direction_bt:122,direction_rl:123,direction_lr:124,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",40:"SHAPE_DATA",44:"AMP",46:"STYLE_SEPARATOR",48:"DOUBLECIRCLESTART",49:"DOUBLECIRCLEEND",50:"PS",51:"PE",52:"(-",53:"-)",54:"STADIUMSTART",55:"STADIUMEND",56:"SUBROUTINESTART",57:"SUBROUTINEEND",58:"VERTEX_WITH_PROPS_START",59:"NODE_STRING[field]",60:"COLON",61:"NODE_STRING[value]",62:"PIPE",63:"CYLINDERSTART",64:"CYLINDEREND",65:"DIAMOND_START",66:"DIAMOND_STOP",67:"TAGEND",68:"TRAPSTART",69:"TRAPEND",70:"INVTRAPSTART",71:"INVTRAPEND",74:"TESTSTR",75:"START_LINK",77:"LINK",78:"LINK_ID",80:"STR",81:"MD_STR",84:"STYLE",85:"LINKSTYLE",86:"CLASSDEF",87:"CLASS",88:"CLICK",89:"DOWN",90:"UP",93:"idString[vertex]",94:"idString[class]",95:"CALLBACKNAME",96:"CALLBACKARGS",97:"HREF",98:"LINK_TARGET",99:"STR[link]",100:"STR[tooltip]",102:"DEFAULT",104:"INTERPOLATE",105:"NUM",106:"COMMA",109:"NODE_STRING",110:"UNIT",111:"BRKT",112:"PCT",114:"MINUS",115:"MULT",116:"UNICODE_TEXT",117:"TEXT",118:"TAGSTART",119:"EDGE_TEXT",121:"direction_tb",122:"direction_bt",123:"direction_rl",124:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[39,2],[39,1],[20,4],[20,3],[20,4],[20,2],[20,2],[20,1],[42,1],[42,6],[42,5],[43,1],[43,3],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,8],[45,4],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,4],[45,4],[45,1],[41,2],[41,3],[41,3],[41,1],[41,3],[41,4],[76,1],[76,2],[76,1],[76,1],[72,1],[72,2],[73,3],[30,1],[30,2],[30,1],[30,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[103,1],[103,3],[92,1],[92,3],[107,1],[107,2],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[113,1],[82,1],[82,1],[82,1],[82,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[79,1],[79,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[120,1],[47,1],[47,2],[101,1],[101,2],[33,1],[33,1],[33,1],[33,1]],performAction:o(function(et,mt,Kt,lt,Cn,ye,Vf){var Te=ye.length-1;switch(Cn){case 2:this.$=[];break;case 3:(!Array.isArray(ye[Te])||ye[Te].length>0)&&ye[Te-1].push(ye[Te]),this.$=ye[Te-1];break;case 4:case 183:this.$=ye[Te];break;case 11:lt.setDirection("TB"),this.$="TB";break;case 12:lt.setDirection(ye[Te-1]),this.$=ye[Te-1];break;case 27:this.$=ye[Te-1].nodes;break;case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 33:this.$=lt.addSubGraph(ye[Te-6],ye[Te-1],ye[Te-4]);break;case 34:this.$=lt.addSubGraph(ye[Te-3],ye[Te-1],ye[Te-3]);break;case 35:this.$=lt.addSubGraph(void 0,ye[Te-1],void 0);break;case 37:this.$=ye[Te].trim(),lt.setAccTitle(this.$);break;case 38:case 39:this.$=ye[Te].trim(),lt.setAccDescription(this.$);break;case 43:this.$=ye[Te-1]+ye[Te];break;case 44:this.$=ye[Te];break;case 45:lt.addVertex(ye[Te-1][ye[Te-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ye[Te]),lt.addLink(ye[Te-3].stmt,ye[Te-1],ye[Te-2]),this.$={stmt:ye[Te-1],nodes:ye[Te-1].concat(ye[Te-3].nodes)};break;case 46:lt.addLink(ye[Te-2].stmt,ye[Te],ye[Te-1]),this.$={stmt:ye[Te],nodes:ye[Te].concat(ye[Te-2].nodes)};break;case 47:lt.addLink(ye[Te-3].stmt,ye[Te-1],ye[Te-2]),this.$={stmt:ye[Te-1],nodes:ye[Te-1].concat(ye[Te-3].nodes)};break;case 48:this.$={stmt:ye[Te-1],nodes:ye[Te-1]};break;case 49:lt.addVertex(ye[Te-1][ye[Te-1].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ye[Te]),this.$={stmt:ye[Te-1],nodes:ye[Te-1],shapeData:ye[Te]};break;case 50:this.$={stmt:ye[Te],nodes:ye[Te]};break;case 51:this.$=[ye[Te]];break;case 52:lt.addVertex(ye[Te-5][ye[Te-5].length-1],void 0,void 0,void 0,void 0,void 0,void 0,ye[Te-4]),this.$=ye[Te-5].concat(ye[Te]);break;case 53:this.$=ye[Te-4].concat(ye[Te]);break;case 54:this.$=ye[Te];break;case 55:this.$=ye[Te-2],lt.setClass(ye[Te-2],ye[Te]);break;case 56:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"square");break;case 57:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"doublecircle");break;case 58:this.$=ye[Te-5],lt.addVertex(ye[Te-5],ye[Te-2],"circle");break;case 59:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"ellipse");break;case 60:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"stadium");break;case 61:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"subroutine");break;case 62:this.$=ye[Te-7],lt.addVertex(ye[Te-7],ye[Te-1],"rect",void 0,void 0,void 0,Object.fromEntries([[ye[Te-5],ye[Te-3]]]));break;case 63:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"cylinder");break;case 64:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"round");break;case 65:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"diamond");break;case 66:this.$=ye[Te-5],lt.addVertex(ye[Te-5],ye[Te-2],"hexagon");break;case 67:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"odd");break;case 68:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"trapezoid");break;case 69:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"inv_trapezoid");break;case 70:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"lean_right");break;case 71:this.$=ye[Te-3],lt.addVertex(ye[Te-3],ye[Te-1],"lean_left");break;case 72:this.$=ye[Te],lt.addVertex(ye[Te]);break;case 73:ye[Te-1].text=ye[Te],this.$=ye[Te-1];break;case 74:case 75:ye[Te-2].text=ye[Te-1],this.$=ye[Te-2];break;case 76:this.$=ye[Te];break;case 77:var wi=lt.destructLink(ye[Te],ye[Te-2]);this.$={type:wi.type,stroke:wi.stroke,length:wi.length,text:ye[Te-1]};break;case 78:var wi=lt.destructLink(ye[Te],ye[Te-2]);this.$={type:wi.type,stroke:wi.stroke,length:wi.length,text:ye[Te-1],id:ye[Te-3]};break;case 79:this.$={text:ye[Te],type:"text"};break;case 80:this.$={text:ye[Te-1].text+""+ye[Te],type:ye[Te-1].type};break;case 81:this.$={text:ye[Te],type:"string"};break;case 82:this.$={text:ye[Te],type:"markdown"};break;case 83:var wi=lt.destructLink(ye[Te]);this.$={type:wi.type,stroke:wi.stroke,length:wi.length};break;case 84:var wi=lt.destructLink(ye[Te]);this.$={type:wi.type,stroke:wi.stroke,length:wi.length,id:ye[Te-1]};break;case 85:this.$=ye[Te-1];break;case 86:this.$={text:ye[Te],type:"text"};break;case 87:this.$={text:ye[Te-1].text+""+ye[Te],type:ye[Te-1].type};break;case 88:this.$={text:ye[Te],type:"string"};break;case 89:case 104:this.$={text:ye[Te],type:"markdown"};break;case 101:this.$={text:ye[Te],type:"text"};break;case 102:this.$={text:ye[Te-1].text+""+ye[Te],type:ye[Te-1].type};break;case 103:this.$={text:ye[Te],type:"text"};break;case 105:this.$=ye[Te-4],lt.addClass(ye[Te-2],ye[Te]);break;case 106:this.$=ye[Te-4],lt.setClass(ye[Te-2],ye[Te]);break;case 107:case 115:this.$=ye[Te-1],lt.setClickEvent(ye[Te-1],ye[Te]);break;case 108:case 116:this.$=ye[Te-3],lt.setClickEvent(ye[Te-3],ye[Te-2]),lt.setTooltip(ye[Te-3],ye[Te]);break;case 109:this.$=ye[Te-2],lt.setClickEvent(ye[Te-2],ye[Te-1],ye[Te]);break;case 110:this.$=ye[Te-4],lt.setClickEvent(ye[Te-4],ye[Te-3],ye[Te-2]),lt.setTooltip(ye[Te-4],ye[Te]);break;case 111:this.$=ye[Te-2],lt.setLink(ye[Te-2],ye[Te]);break;case 112:this.$=ye[Te-4],lt.setLink(ye[Te-4],ye[Te-2]),lt.setTooltip(ye[Te-4],ye[Te]);break;case 113:this.$=ye[Te-4],lt.setLink(ye[Te-4],ye[Te-2],ye[Te]);break;case 114:this.$=ye[Te-6],lt.setLink(ye[Te-6],ye[Te-4],ye[Te]),lt.setTooltip(ye[Te-6],ye[Te-2]);break;case 117:this.$=ye[Te-1],lt.setLink(ye[Te-1],ye[Te]);break;case 118:this.$=ye[Te-3],lt.setLink(ye[Te-3],ye[Te-2]),lt.setTooltip(ye[Te-3],ye[Te]);break;case 119:this.$=ye[Te-3],lt.setLink(ye[Te-3],ye[Te-2],ye[Te]);break;case 120:this.$=ye[Te-5],lt.setLink(ye[Te-5],ye[Te-4],ye[Te]),lt.setTooltip(ye[Te-5],ye[Te-2]);break;case 121:this.$=ye[Te-4],lt.addVertex(ye[Te-2],void 0,void 0,ye[Te]);break;case 122:this.$=ye[Te-4],lt.updateLink([ye[Te-2]],ye[Te]);break;case 123:this.$=ye[Te-4],lt.updateLink(ye[Te-2],ye[Te]);break;case 124:this.$=ye[Te-8],lt.updateLinkInterpolate([ye[Te-6]],ye[Te-2]),lt.updateLink([ye[Te-6]],ye[Te]);break;case 125:this.$=ye[Te-8],lt.updateLinkInterpolate(ye[Te-6],ye[Te-2]),lt.updateLink(ye[Te-6],ye[Te]);break;case 126:this.$=ye[Te-6],lt.updateLinkInterpolate([ye[Te-4]],ye[Te]);break;case 127:this.$=ye[Te-6],lt.updateLinkInterpolate(ye[Te-4],ye[Te]);break;case 128:case 130:this.$=[ye[Te]];break;case 129:case 131:ye[Te-2].push(ye[Te]),this.$=ye[Te-2];break;case 133:this.$=ye[Te-1]+ye[Te];break;case 181:this.$=ye[Te];break;case 182:this.$=ye[Te-1]+""+ye[Te];break;case 184:this.$=ye[Te-1]+""+ye[Te];break;case 185:this.$={stmt:"dir",value:"TB"};break;case 186:this.$={stmt:"dir",value:"BT"};break;case 187:this.$={stmt:"dir",value:"RL"};break;case 188:this.$={stmt:"dir",value:"LR"};break}},"anonymous"),table:[{3:1,4:2,9:e,10:r,12:n},{1:[3]},t(i,a,{5:6}),{4:7,9:e,10:r,12:n},{4:8,9:e,10:r,12:n},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:w,88:C,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L,121:R,122:O,123:M,124:B},t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),{8:[1,54],9:[1,55],10:F,15:53,18:56},t(P,[2,3]),t(P,[2,4]),t(P,[2,5]),t(P,[2,6]),t(P,[2,7]),t(P,[2,8]),{8:z,9:$,11:H,21:58,41:59,72:63,75:[1,64],77:[1,66],78:[1,65]},{8:z,9:$,11:H,21:67},{8:z,9:$,11:H,21:68},{8:z,9:$,11:H,21:69},{8:z,9:$,11:H,21:70},{8:z,9:$,11:H,21:71},{8:z,9:$,10:[1,72],11:H,21:73},t(P,[2,36]),{35:[1,74]},{37:[1,75]},t(P,[2,39]),t(Q,[2,50],{18:76,39:77,10:F,40:j}),{10:[1,79]},{10:[1,80]},{10:[1,81]},{10:[1,82]},{14:ie,44:ne,60:le,80:[1,86],89:he,95:[1,83],97:[1,84],101:85,105:K,106:X,109:te,111:J,114:se,115:ue,116:Z,120:87},t(P,[2,185]),t(P,[2,186]),t(P,[2,187]),t(P,[2,188]),t(Se,[2,51]),t(Se,[2,54],{46:[1,99]}),t(ce,[2,72],{113:112,29:[1,100],44:g,48:[1,101],50:[1,102],52:[1,103],54:[1,104],56:[1,105],58:[1,106],60:y,63:[1,107],65:[1,108],67:[1,109],68:[1,110],70:[1,111],89:T,102:E,105:A,106:S,109:_,111:I,114:D,115:k,116:L}),t(ae,[2,181]),t(ae,[2,142]),t(ae,[2,143]),t(ae,[2,144]),t(ae,[2,145]),t(ae,[2,146]),t(ae,[2,147]),t(ae,[2,148]),t(ae,[2,149]),t(ae,[2,150]),t(ae,[2,151]),t(ae,[2,152]),t(i,[2,12]),t(i,[2,18]),t(i,[2,19]),{9:[1,113]},t(Oe,[2,26],{18:114,10:F}),t(P,[2,27]),{42:115,43:38,44:g,45:39,47:40,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},t(P,[2,40]),t(P,[2,41]),t(P,[2,42]),t(ge,[2,76],{73:116,62:[1,118],74:[1,117]}),{76:119,79:120,80:ze,81:He,116:$e,119:Re},{75:[1,125],77:[1,126]},t(Ie,[2,83]),t(P,[2,28]),t(P,[2,29]),t(P,[2,30]),t(P,[2,31]),t(P,[2,32]),{10:be,12:W,14:de,27:re,28:127,32:oe,44:V,60:xe,75:q,80:[1,129],81:[1,130],83:140,84:pe,85:ve,86:Pe,87:_e,88:we,89:Ve,90:De,91:128,105:qe,109:at,111:Rt,114:st,115:Ue,116:ct},t(We,a,{5:153}),t(P,[2,37]),t(P,[2,38]),t(Q,[2,48],{44:ot}),t(Q,[2,49],{18:155,10:F,40:Yt}),t(Se,[2,44]),{44:g,47:157,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},{102:[1,158],103:159,105:[1,160]},{44:g,47:161,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},{44:g,47:162,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},t(bt,[2,107],{10:[1,163],96:[1,164]}),{80:[1,165]},t(bt,[2,115],{120:167,10:[1,166],14:ie,44:ne,60:le,89:he,105:K,106:X,109:te,111:J,114:se,115:ue,116:Z}),t(bt,[2,117],{10:[1,168]}),t(Mt,[2,183]),t(Mt,[2,170]),t(Mt,[2,171]),t(Mt,[2,172]),t(Mt,[2,173]),t(Mt,[2,174]),t(Mt,[2,175]),t(Mt,[2,176]),t(Mt,[2,177]),t(Mt,[2,178]),t(Mt,[2,179]),t(Mt,[2,180]),{44:g,47:169,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},{30:170,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:178,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:180,50:[1,179],67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:181,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:182,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:183,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{109:[1,184]},{30:185,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:186,65:[1,187],67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:188,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:189,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{30:190,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},t(ae,[2,182]),t(i,[2,20]),t(Oe,[2,25]),t(Q,[2,46],{39:191,18:192,10:F,40:j}),t(ge,[2,73],{10:[1,193]}),{10:[1,194]},{30:195,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{77:[1,196],79:197,116:$e,119:Re},t(dn,[2,79]),t(dn,[2,81]),t(dn,[2,82]),t(dn,[2,168]),t(dn,[2,169]),{76:198,79:120,80:ze,81:He,116:$e,119:Re},t(Ie,[2,84]),{8:z,9:$,10:be,11:H,12:W,14:de,21:200,27:re,29:[1,199],32:oe,44:V,60:xe,75:q,83:140,84:pe,85:ve,86:Pe,87:_e,88:we,89:Ve,90:De,91:201,105:qe,109:at,111:Rt,114:st,115:Ue,116:ct},t(Tt,[2,101]),t(Tt,[2,103]),t(Tt,[2,104]),t(Tt,[2,157]),t(Tt,[2,158]),t(Tt,[2,159]),t(Tt,[2,160]),t(Tt,[2,161]),t(Tt,[2,162]),t(Tt,[2,163]),t(Tt,[2,164]),t(Tt,[2,165]),t(Tt,[2,166]),t(Tt,[2,167]),t(Tt,[2,90]),t(Tt,[2,91]),t(Tt,[2,92]),t(Tt,[2,93]),t(Tt,[2,94]),t(Tt,[2,95]),t(Tt,[2,96]),t(Tt,[2,97]),t(Tt,[2,98]),t(Tt,[2,99]),t(Tt,[2,100]),{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,202],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:w,88:C,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L,121:R,122:O,123:M,124:B},{10:F,18:203},{44:[1,204]},t(Se,[2,43]),{10:[1,205],44:g,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:112,114:D,115:k,116:L},{10:[1,206]},{10:[1,207],106:[1,208]},t(On,[2,128]),{10:[1,209],44:g,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:112,114:D,115:k,116:L},{10:[1,210],44:g,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:112,114:D,115:k,116:L},{80:[1,211]},t(bt,[2,109],{10:[1,212]}),t(bt,[2,111],{10:[1,213]}),{80:[1,214]},t(Mt,[2,184]),{80:[1,215],98:[1,216]},t(Se,[2,55],{113:112,44:g,60:y,89:T,102:E,105:A,106:S,109:_,111:I,114:D,115:k,116:L}),{31:[1,217],67:xt,82:218,116:ft,117:yt,118:nt},t(tn,[2,86]),t(tn,[2,88]),t(tn,[2,89]),t(tn,[2,153]),t(tn,[2,154]),t(tn,[2,155]),t(tn,[2,156]),{49:[1,219],67:xt,82:218,116:ft,117:yt,118:nt},{30:220,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{51:[1,221],67:xt,82:218,116:ft,117:yt,118:nt},{53:[1,222],67:xt,82:218,116:ft,117:yt,118:nt},{55:[1,223],67:xt,82:218,116:ft,117:yt,118:nt},{57:[1,224],67:xt,82:218,116:ft,117:yt,118:nt},{60:[1,225]},{64:[1,226],67:xt,82:218,116:ft,117:yt,118:nt},{66:[1,227],67:xt,82:218,116:ft,117:yt,118:nt},{30:228,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},{31:[1,229],67:xt,82:218,116:ft,117:yt,118:nt},{67:xt,69:[1,230],71:[1,231],82:218,116:ft,117:yt,118:nt},{67:xt,69:[1,233],71:[1,232],82:218,116:ft,117:yt,118:nt},t(Q,[2,45],{18:155,10:F,40:Yt}),t(Q,[2,47],{44:ot}),t(ge,[2,75]),t(ge,[2,74]),{62:[1,234],67:xt,82:218,116:ft,117:yt,118:nt},t(ge,[2,77]),t(dn,[2,80]),{77:[1,235],79:197,116:$e,119:Re},{30:236,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},t(We,a,{5:237}),t(Tt,[2,102]),t(P,[2,35]),{43:238,44:g,45:39,47:40,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},{10:F,18:239},{10:_r,60:Dr,84:Pn,92:240,105:At,107:241,108:242,109:Ce,110:tt,111:St,112:mr},{10:_r,60:Dr,84:Pn,92:251,104:[1,252],105:At,107:241,108:242,109:Ce,110:tt,111:St,112:mr},{10:_r,60:Dr,84:Pn,92:253,104:[1,254],105:At,107:241,108:242,109:Ce,110:tt,111:St,112:mr},{105:[1,255]},{10:_r,60:Dr,84:Pn,92:256,105:At,107:241,108:242,109:Ce,110:tt,111:St,112:mr},{44:g,47:257,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},t(bt,[2,108]),{80:[1,258]},{80:[1,259],98:[1,260]},t(bt,[2,116]),t(bt,[2,118],{10:[1,261]}),t(bt,[2,119]),t(ce,[2,56]),t(tn,[2,87]),t(ce,[2,57]),{51:[1,262],67:xt,82:218,116:ft,117:yt,118:nt},t(ce,[2,64]),t(ce,[2,59]),t(ce,[2,60]),t(ce,[2,61]),{109:[1,263]},t(ce,[2,63]),t(ce,[2,65]),{66:[1,264],67:xt,82:218,116:ft,117:yt,118:nt},t(ce,[2,67]),t(ce,[2,68]),t(ce,[2,70]),t(ce,[2,69]),t(ce,[2,71]),t([10,44,60,89,102,105,106,109,111,114,115,116],[2,85]),t(ge,[2,78]),{31:[1,265],67:xt,82:218,116:ft,117:yt,118:nt},{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,266],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:w,88:C,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L,121:R,122:O,123:M,124:B},t(Se,[2,53]),{43:267,44:g,45:39,47:40,60:y,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L},t(bt,[2,121],{106:rn}),t(gn,[2,130],{108:269,10:_r,60:Dr,84:Pn,105:At,109:Ce,110:tt,111:St,112:mr}),t(Zr,[2,132]),t(Zr,[2,134]),t(Zr,[2,135]),t(Zr,[2,136]),t(Zr,[2,137]),t(Zr,[2,138]),t(Zr,[2,139]),t(Zr,[2,140]),t(Zr,[2,141]),t(bt,[2,122],{106:rn}),{10:[1,270]},t(bt,[2,123],{106:rn}),{10:[1,271]},t(On,[2,129]),t(bt,[2,105],{106:rn}),t(bt,[2,106],{113:112,44:g,60:y,89:T,102:E,105:A,106:S,109:_,111:I,114:D,115:k,116:L}),t(bt,[2,110]),t(bt,[2,112],{10:[1,272]}),t(bt,[2,113]),{98:[1,273]},{51:[1,274]},{62:[1,275]},{66:[1,276]},{8:z,9:$,11:H,21:277},t(P,[2,34]),t(Se,[2,52]),{10:_r,60:Dr,84:Pn,105:At,107:278,108:242,109:Ce,110:tt,111:St,112:mr},t(Zr,[2,133]),{14:ie,44:ne,60:le,89:he,101:279,105:K,106:X,109:te,111:J,114:se,115:ue,116:Z,120:87},{14:ie,44:ne,60:le,89:he,101:280,105:K,106:X,109:te,111:J,114:se,115:ue,116:Z,120:87},{98:[1,281]},t(bt,[2,120]),t(ce,[2,58]),{30:282,67:xt,80:ut,81:Et,82:171,116:ft,117:yt,118:nt},t(ce,[2,66]),t(We,a,{5:283}),t(gn,[2,131],{108:269,10:_r,60:Dr,84:Pn,105:At,109:Ce,110:tt,111:St,112:mr}),t(bt,[2,126],{120:167,10:[1,284],14:ie,44:ne,60:le,89:he,105:K,106:X,109:te,111:J,114:se,115:ue,116:Z}),t(bt,[2,127],{120:167,10:[1,285],14:ie,44:ne,60:le,89:he,105:K,106:X,109:te,111:J,114:se,115:ue,116:Z}),t(bt,[2,114]),{31:[1,286],67:xt,82:218,116:ft,117:yt,118:nt},{6:11,7:12,8:s,9:l,10:u,11:h,20:17,22:18,23:19,24:20,25:21,26:22,27:f,32:[1,287],33:24,34:d,36:p,38:m,42:28,43:38,44:g,45:39,47:40,60:y,84:v,85:x,86:b,87:w,88:C,89:T,102:E,105:A,106:S,109:_,111:I,113:41,114:D,115:k,116:L,121:R,122:O,123:M,124:B},{10:_r,60:Dr,84:Pn,92:288,105:At,107:241,108:242,109:Ce,110:tt,111:St,112:mr},{10:_r,60:Dr,84:Pn,92:289,105:At,107:241,108:242,109:Ce,110:tt,111:St,112:mr},t(ce,[2,62]),t(P,[2,33]),t(bt,[2,124],{106:rn}),t(bt,[2,125],{106:rn})],defaultActions:{},parseError:o(function(et,mt){if(mt.recoverable)this.trace(et);else{var Kt=new Error(et);throw Kt.hash=mt,Kt}},"parseError"),parse:o(function(et){var mt=this,Kt=[0],lt=[],Cn=[null],ye=[],Vf=this.table,Te="",wi=0,TF=0,kF=0,M2e=2,EF=1,I2e=ye.slice.call(arguments,1),Xi=Object.create(this.lexer),Uf={yy:{}};for(var xC in this.yy)Object.prototype.hasOwnProperty.call(this.yy,xC)&&(Uf.yy[xC]=this.yy[xC]);Xi.setInput(et,Uf.yy),Uf.yy.lexer=Xi,Uf.yy.parser=this,typeof Xi.yylloc>"u"&&(Xi.yylloc={});var bC=Xi.yylloc;ye.push(bC);var O2e=Xi.options&&Xi.options.ranges;typeof Uf.yy.parseError=="function"?this.parseError=Uf.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function wnt(Ws){Kt.length=Kt.length-2*Ws,Cn.length=Cn.length-Ws,ye.length=ye.length-Ws}o(wnt,"popStack");function P2e(){var Ws;return Ws=lt.pop()||Xi.lex()||EF,typeof Ws!="number"&&(Ws instanceof Array&&(lt=Ws,Ws=lt.pop()),Ws=mt.symbols_[Ws]||Ws),Ws}o(P2e,"lex");for(var Wa,wC,Hf,xo,Tnt,TC,Jp={},_4,Jc,SF,D4;;){if(Hf=Kt[Kt.length-1],this.defaultActions[Hf]?xo=this.defaultActions[Hf]:((Wa===null||typeof Wa>"u")&&(Wa=P2e()),xo=Vf[Hf]&&Vf[Hf][Wa]),typeof xo>"u"||!xo.length||!xo[0]){var kC="";D4=[];for(_4 in Vf[Hf])this.terminals_[_4]&&_4>M2e&&D4.push("'"+this.terminals_[_4]+"'");Xi.showPosition?kC="Parse error on line "+(wi+1)+`:
+`+Xi.showPosition()+`
+Expecting `+D4.join(", ")+", got '"+(this.terminals_[Wa]||Wa)+"'":kC="Parse error on line "+(wi+1)+": Unexpected "+(Wa==EF?"end of input":"'"+(this.terminals_[Wa]||Wa)+"'"),this.parseError(kC,{text:Xi.match,token:this.terminals_[Wa]||Wa,line:Xi.yylineno,loc:bC,expected:D4})}if(xo[0]instanceof Array&&xo.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Hf+", token: "+Wa);switch(xo[0]){case 1:Kt.push(Wa),Cn.push(Xi.yytext),ye.push(Xi.yylloc),Kt.push(xo[1]),Wa=null,wC?(Wa=wC,wC=null):(TF=Xi.yyleng,Te=Xi.yytext,wi=Xi.yylineno,bC=Xi.yylloc,kF>0&&kF--);break;case 2:if(Jc=this.productions_[xo[1]][1],Jp.$=Cn[Cn.length-Jc],Jp._$={first_line:ye[ye.length-(Jc||1)].first_line,last_line:ye[ye.length-1].last_line,first_column:ye[ye.length-(Jc||1)].first_column,last_column:ye[ye.length-1].last_column},O2e&&(Jp._$.range=[ye[ye.length-(Jc||1)].range[0],ye[ye.length-1].range[1]]),TC=this.performAction.apply(Jp,[Te,TF,wi,Uf.yy,xo[1],Cn,ye].concat(I2e)),typeof TC<"u")return TC;Jc&&(Kt=Kt.slice(0,-1*Jc*2),Cn=Cn.slice(0,-1*Jc),ye=ye.slice(0,-1*Jc)),Kt.push(this.productions_[xo[1]][0]),Cn.push(Jp.$),ye.push(Jp._$),SF=Vf[Kt[Kt.length-2]][Kt[Kt.length-1]],Kt.push(SF);break;case 3:return!0}}return!0},"parse")},Zn=function(){var Hr={EOF:1,parseError:o(function(mt,Kt){if(this.yy.parser)this.yy.parser.parseError(mt,Kt);else throw new Error(mt)},"parseError"),setInput:o(function(et,mt){return this.yy=mt||this.yy||{},this._input=et,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var et=this._input[0];this.yytext+=et,this.yyleng++,this.offset++,this.match+=et,this.matched+=et;var mt=et.match(/(?:\r\n?|\n).*/g);return mt?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),et},"input"),unput:o(function(et){var mt=et.length,Kt=et.split(/(?:\r\n?|\n)/g);this._input=et+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-mt),this.offset-=mt;var lt=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),Kt.length-1&&(this.yylineno-=Kt.length-1);var Cn=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:Kt?(Kt.length===lt.length?this.yylloc.first_column:0)+lt[lt.length-Kt.length].length-Kt[0].length:this.yylloc.first_column-mt},this.options.ranges&&(this.yylloc.range=[Cn[0],Cn[0]+this.yyleng-mt]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(et){this.unput(this.match.slice(et))},"less"),pastInput:o(function(){var et=this.matched.substr(0,this.matched.length-this.match.length);return(et.length>20?"...":"")+et.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var et=this.match;return et.length<20&&(et+=this._input.substr(0,20-et.length)),(et.substr(0,20)+(et.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var et=this.pastInput(),mt=new Array(et.length+1).join("-");return et+this.upcomingInput()+`
+`+mt+"^"},"showPosition"),test_match:o(function(et,mt){var Kt,lt,Cn;if(this.options.backtrack_lexer&&(Cn={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(Cn.yylloc.range=this.yylloc.range.slice(0))),lt=et[0].match(/(?:\r\n?|\n).*/g),lt&&(this.yylineno+=lt.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:lt?lt[lt.length-1].length-lt[lt.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+et[0].length},this.yytext+=et[0],this.match+=et[0],this.matches=et,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(et[0].length),this.matched+=et[0],Kt=this.performAction.call(this,this.yy,this,mt,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Kt)return Kt;if(this._backtrack){for(var ye in Cn)this[ye]=Cn[ye];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var et,mt,Kt,lt;this._more||(this.yytext="",this.match="");for(var Cn=this._currentRules(),ye=0;ye<Cn.length;ye++)if(Kt=this._input.match(this.rules[Cn[ye]]),Kt&&(!mt||Kt[0].length>mt[0].length)){if(mt=Kt,lt=ye,this.options.backtrack_lexer){if(et=this.test_match(Kt,Cn[ye]),et!==!1)return et;if(this._backtrack){mt=!1;continue}else return!1}else if(!this.options.flex)break}return mt?(et=this.test_match(mt,Cn[lt]),et!==!1?et:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var mt=this.next();return mt||this.lex()},"lex"),begin:o(function(mt){this.conditionStack.push(mt)},"begin"),popState:o(function(){var mt=this.conditionStack.length-1;return mt>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(mt){return mt=this.conditionStack.length-1-Math.abs(mt||0),mt>=0?this.conditionStack[mt]:"INITIAL"},"topState"),pushState:o(function(mt){this.begin(mt)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(mt,Kt,lt,Cn){var ye=Cn;switch(lt){case 0:return this.begin("acc_title"),34;break;case 1:return this.popState(),"acc_title_value";break;case 2:return this.begin("acc_descr"),36;break;case 3:return this.popState(),"acc_descr_value";break;case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.pushState("shapeData"),Kt.yytext="",40;break;case 8:return this.pushState("shapeDataStr"),40;break;case 9:return this.popState(),40;break;case 10:let Vf=/\n\s*/g;return Kt.yytext=Kt.yytext.replace(Vf,"<br/>"),40;break;case 11:return 40;case 12:this.popState();break;case 13:this.begin("callbackname");break;case 14:this.popState();break;case 15:this.popState(),this.begin("callbackargs");break;case 16:return 95;case 17:this.popState();break;case 18:return 96;case 19:return"MD_STR";case 20:this.popState();break;case 21:this.begin("md_string");break;case 22:return"STR";case 23:this.popState();break;case 24:this.pushState("string");break;case 25:return 84;case 26:return 102;case 27:return 85;case 28:return 104;case 29:return 86;case 30:return 87;case 31:return 97;case 32:this.begin("click");break;case 33:this.popState();break;case 34:return 88;case 35:return mt.lex.firstGraph()&&this.begin("dir"),12;break;case 36:return mt.lex.firstGraph()&&this.begin("dir"),12;break;case 37:return mt.lex.firstGraph()&&this.begin("dir"),12;break;case 38:return 27;case 39:return 32;case 40:return 98;case 41:return 98;case 42:return 98;case 43:return 98;case 44:return this.popState(),13;break;case 45:return this.popState(),14;break;case 46:return this.popState(),14;break;case 47:return this.popState(),14;break;case 48:return this.popState(),14;break;case 49:return this.popState(),14;break;case 50:return this.popState(),14;break;case 51:return this.popState(),14;break;case 52:return this.popState(),14;break;case 53:return this.popState(),14;break;case 54:return this.popState(),14;break;case 55:return 121;case 56:return 122;case 57:return 123;case 58:return 124;case 59:return 78;case 60:return 105;case 61:return 111;case 62:return 46;case 63:return 60;case 64:return 44;case 65:return 8;case 66:return 106;case 67:return 115;case 68:return this.popState(),77;break;case 69:return this.pushState("edgeText"),75;break;case 70:return 119;case 71:return this.popState(),77;break;case 72:return this.pushState("thickEdgeText"),75;break;case 73:return 119;case 74:return this.popState(),77;break;case 75:return this.pushState("dottedEdgeText"),75;break;case 76:return 119;case 77:return 77;case 78:return this.popState(),53;break;case 79:return"TEXT";case 80:return this.pushState("ellipseText"),52;break;case 81:return this.popState(),55;break;case 82:return this.pushState("text"),54;break;case 83:return this.popState(),57;break;case 84:return this.pushState("text"),56;break;case 85:return 58;case 86:return this.pushState("text"),67;break;case 87:return this.popState(),64;break;case 88:return this.pushState("text"),63;break;case 89:return this.popState(),49;break;case 90:return this.pushState("text"),48;break;case 91:return this.popState(),69;break;case 92:return this.popState(),71;break;case 93:return 117;case 94:return this.pushState("trapText"),68;break;case 95:return this.pushState("trapText"),70;break;case 96:return 118;case 97:return 67;case 98:return 90;case 99:return"SEP";case 100:return 89;case 101:return 115;case 102:return 111;case 103:return 44;case 104:return 109;case 105:return 114;case 106:return 116;case 107:return this.popState(),62;break;case 108:return this.pushState("text"),62;break;case 109:return this.popState(),51;break;case 110:return this.pushState("text"),50;break;case 111:return this.popState(),31;break;case 112:return this.pushState("text"),29;break;case 113:return this.popState(),66;break;case 114:return this.pushState("text"),65;break;case 115:return"TEXT";case 116:return"QUOTE";case 117:return 9;case 118:return 10;case 119:return 11}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:@\{)/,/^(?:["])/,/^(?:["])/,/^(?:[^\"]+)/,/^(?:[^}^"]+)/,/^(?:\})/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[^\s\"]+@(?=[^\{\"]))/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{shapeDataEndBracket:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeDataStr:{rules:[9,10,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},shapeData:{rules:[8,11,12,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackargs:{rules:[17,18,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},callbackname:{rules:[14,15,16,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},href:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},click:{rules:[21,24,33,34,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dottedEdgeText:{rules:[21,24,74,76,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},thickEdgeText:{rules:[21,24,71,73,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},edgeText:{rules:[21,24,68,70,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},trapText:{rules:[21,24,77,80,82,84,88,90,91,92,93,94,95,108,110,112,114],inclusive:!1},ellipseText:{rules:[21,24,77,78,79,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},text:{rules:[21,24,77,80,81,82,83,84,87,88,89,90,94,95,107,108,109,110,111,112,113,114,115],inclusive:!1},vertex:{rules:[21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},dir:{rules:[21,24,44,45,46,47,48,49,50,51,52,53,54,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr_multiline:{rules:[5,6,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_descr:{rules:[3,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},acc_title:{rules:[1,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},md_string:{rules:[19,20,21,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},string:{rules:[21,22,23,24,77,80,82,84,88,90,94,95,108,110,112,114],inclusive:!1},INITIAL:{rules:[0,2,4,7,13,21,24,25,26,27,28,29,30,31,32,35,36,37,38,39,40,41,42,43,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,71,72,74,75,77,80,82,84,85,86,88,90,94,95,96,97,98,99,100,101,102,103,104,105,106,108,110,112,114,116,117,118,119],inclusive:!0}}};return Hr}();Ni.lexer=Zn;function Sn(){this.yy={}}return o(Sn,"Parser"),Sn.prototype=Ni,Ni.Parser=Sn,new Sn}();xR.parser=xR;bR=xR});var Uie,Hie,Wie=N(()=>{"use strict";Vie();Uie=Object.assign({},bR);Uie.parse=t=>{let e=t.replace(/}\s*\n/g,`}
+`);return bR.parse(e)};Hie=Uie});var gOe,yOe,qie,Yie=N(()=>{"use strict";Ys();gOe=o((t,e)=>{let r=Kf,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return qa(n,i,a,e)},"fade"),yOe=o(t=>`.label {
+ font-family: ${t.fontFamily};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+ .cluster-label text {
+ fill: ${t.titleColor};
+ }
+ .cluster-label span {
+ color: ${t.titleColor};
+ }
+ .cluster-label span p {
+ background-color: transparent;
+ }
+
+ .label text,span {
+ fill: ${t.nodeTextColor||t.textColor};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+
+ .node rect,
+ .node circle,
+ .node ellipse,
+ .node polygon,
+ .node path {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+ stroke-width: 1px;
+ }
+ .rough-node .label text , .node .label text, .image-shape .label, .icon-shape .label {
+ text-anchor: middle;
+ }
+ // .flowchart-label .text-outer-tspan {
+ // text-anchor: middle;
+ // }
+ // .flowchart-label .text-inner-tspan {
+ // text-anchor: start;
+ // }
+
+ .node .katex path {
+ fill: #000;
+ stroke: #000;
+ stroke-width: 1px;
+ }
+
+ .rough-node .label,.node .label, .image-shape .label, .icon-shape .label {
+ text-align: center;
+ }
+ .node.clickable {
+ cursor: pointer;
+ }
+
+
+ .root .anchor path {
+ fill: ${t.lineColor} !important;
+ stroke-width: 0;
+ stroke: ${t.lineColor};
+ }
+
+ .arrowheadPath {
+ fill: ${t.arrowheadColor};
+ }
+
+ .edgePath .path {
+ stroke: ${t.lineColor};
+ stroke-width: 2.0px;
+ }
+
+ .flowchart-link {
+ stroke: ${t.lineColor};
+ fill: none;
+ }
+
+ .edgeLabel {
+ background-color: ${t.edgeLabelBackground};
+ p {
+ background-color: ${t.edgeLabelBackground};
+ }
+ rect {
+ opacity: 0.5;
+ background-color: ${t.edgeLabelBackground};
+ fill: ${t.edgeLabelBackground};
+ }
+ text-align: center;
+ }
+
+ /* For html labels only */
+ .labelBkg {
+ background-color: ${gOe(t.edgeLabelBackground,.5)};
+ // background-color:
+ }
+
+ .cluster rect {
+ fill: ${t.clusterBkg};
+ stroke: ${t.clusterBorder};
+ stroke-width: 1px;
+ }
+
+ .cluster text {
+ fill: ${t.titleColor};
+ }
+
+ .cluster span {
+ color: ${t.titleColor};
+ }
+ /* .cluster div {
+ color: ${t.titleColor};
+ } */
+
+ div.mermaidTooltip {
+ position: absolute;
+ text-align: center;
+ max-width: 200px;
+ padding: 2px;
+ font-family: ${t.fontFamily};
+ font-size: 12px;
+ background: ${t.tertiaryColor};
+ border: 1px solid ${t.border2};
+ border-radius: 2px;
+ pointer-events: none;
+ z-index: 100;
+ }
+
+ .flowchartTitleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: ${t.textColor};
+ }
+
+ rect.text {
+ fill: none;
+ stroke-width: 0;
+ }
+
+ .icon-shape, .image-shape {
+ background-color: ${t.edgeLabelBackground};
+ p {
+ background-color: ${t.edgeLabelBackground};
+ padding: 2px;
+ }
+ rect {
+ opacity: 0.5;
+ background-color: ${t.edgeLabelBackground};
+ fill: ${t.edgeLabelBackground};
+ }
+ text-align: center;
+ }
+`,"getStyles"),qie=yOe});var ik={};hr(ik,{diagram:()=>vOe});var vOe,ak=N(()=>{"use strict";zt();qZ();Gie();Wie();Yie();vOe={parser:Hie,get db(){return new Uw},renderer:zie,styles:qie,init:o(t=>{t.flowchart||(t.flowchart={}),t.layout&&Yy({layout:t.layout}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,Yy({flowchart:{arrowMarkerAbsolute:t.arrowMarkerAbsolute}})},"init")}});var wR,Zie,Jie=N(()=>{"use strict";wR=function(){var t=o(function(J,se,ue,Z){for(ue=ue||{},Z=J.length;Z--;ue[J[Z]]=se);return ue},"o"),e=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,50],r=[1,10],n=[1,11],i=[1,12],a=[1,13],s=[1,20],l=[1,21],u=[1,22],h=[1,23],f=[1,24],d=[1,19],p=[1,25],m=[1,26],g=[1,18],y=[1,33],v=[1,34],x=[1,35],b=[1,36],w=[1,37],C=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,50,63,64,65,66,67],T=[1,42],E=[1,43],A=[1,52],S=[40,50,68,69],_=[1,63],I=[1,61],D=[1,58],k=[1,62],L=[1,64],R=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,63,64,65,66,67],O=[63,64,65,66,67],M=[1,81],B=[1,80],F=[1,78],P=[1,79],z=[6,10,42,47],$=[6,10,13,41,42,47,48,49],H=[1,89],Q=[1,88],j=[1,87],ie=[19,56],ne=[1,98],le=[1,97],he=[19,56,58,60],K={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,COLON:13,role:14,STYLE_SEPARATOR:15,idList:16,BLOCK_START:17,attributes:18,BLOCK_STOP:19,SQS:20,SQE:21,title:22,title_value:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,direction:29,classDefStatement:30,classStatement:31,styleStatement:32,direction_tb:33,direction_bt:34,direction_rl:35,direction_lr:36,CLASSDEF:37,stylesOpt:38,separator:39,UNICODE_TEXT:40,STYLE_TEXT:41,COMMA:42,CLASS:43,STYLE:44,style:45,styleComponent:46,SEMI:47,NUM:48,BRKT:49,ENTITY_NAME:50,attribute:51,attributeType:52,attributeName:53,attributeKeyTypeList:54,attributeComment:55,ATTRIBUTE_WORD:56,attributeKeyType:57,",":58,ATTRIBUTE_KEY:59,COMMENT:60,cardinality:61,relType:62,ZERO_OR_ONE:63,ZERO_OR_MORE:64,ONE_OR_MORE:65,ONLY_ONE:66,MD_PARENT:67,NON_IDENTIFYING:68,IDENTIFYING:69,WORD:70,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:"COLON",15:"STYLE_SEPARATOR",17:"BLOCK_START",19:"BLOCK_STOP",20:"SQS",21:"SQE",22:"title",23:"title_value",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"direction_tb",34:"direction_bt",35:"direction_rl",36:"direction_lr",37:"CLASSDEF",40:"UNICODE_TEXT",41:"STYLE_TEXT",42:"COMMA",43:"CLASS",44:"STYLE",47:"SEMI",48:"NUM",49:"BRKT",50:"ENTITY_NAME",56:"ATTRIBUTE_WORD",58:",",59:"ATTRIBUTE_KEY",60:"COMMENT",63:"ZERO_OR_ONE",64:"ZERO_OR_MORE",65:"ONE_OR_MORE",66:"ONLY_ONE",67:"MD_PARENT",68:"NON_IDENTIFYING",69:"IDENTIFYING",70:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[18,1],[18,2],[51,2],[51,3],[51,3],[51,4],[52,1],[53,1],[54,1],[54,3],[57,1],[55,1],[12,3],[61,1],[61,1],[61,1],[61,1],[61,1],[62,1],[62,1],[14,1],[14,1],[14,1]],performAction:o(function(se,ue,Z,Se,ce,ae,Oe){var ge=ae.length-1;switch(ce){case 1:break;case 2:this.$=[];break;case 3:ae[ge-1].push(ae[ge]),this.$=ae[ge-1];break;case 4:case 5:this.$=ae[ge];break;case 6:case 7:this.$=[];break;case 8:Se.addEntity(ae[ge-4]),Se.addEntity(ae[ge-2]),Se.addRelationship(ae[ge-4],ae[ge],ae[ge-2],ae[ge-3]);break;case 9:Se.addEntity(ae[ge-8]),Se.addEntity(ae[ge-4]),Se.addRelationship(ae[ge-8],ae[ge],ae[ge-4],ae[ge-5]),Se.setClass([ae[ge-8]],ae[ge-6]),Se.setClass([ae[ge-4]],ae[ge-2]);break;case 10:Se.addEntity(ae[ge-6]),Se.addEntity(ae[ge-2]),Se.addRelationship(ae[ge-6],ae[ge],ae[ge-2],ae[ge-3]),Se.setClass([ae[ge-6]],ae[ge-4]);break;case 11:Se.addEntity(ae[ge-6]),Se.addEntity(ae[ge-4]),Se.addRelationship(ae[ge-6],ae[ge],ae[ge-4],ae[ge-5]),Se.setClass([ae[ge-4]],ae[ge-2]);break;case 12:Se.addEntity(ae[ge-3]),Se.addAttributes(ae[ge-3],ae[ge-1]);break;case 13:Se.addEntity(ae[ge-5]),Se.addAttributes(ae[ge-5],ae[ge-1]),Se.setClass([ae[ge-5]],ae[ge-3]);break;case 14:Se.addEntity(ae[ge-2]);break;case 15:Se.addEntity(ae[ge-4]),Se.setClass([ae[ge-4]],ae[ge-2]);break;case 16:Se.addEntity(ae[ge]);break;case 17:Se.addEntity(ae[ge-2]),Se.setClass([ae[ge-2]],ae[ge]);break;case 18:Se.addEntity(ae[ge-6],ae[ge-4]),Se.addAttributes(ae[ge-6],ae[ge-1]);break;case 19:Se.addEntity(ae[ge-8],ae[ge-6]),Se.addAttributes(ae[ge-8],ae[ge-1]),Se.setClass([ae[ge-8]],ae[ge-3]);break;case 20:Se.addEntity(ae[ge-5],ae[ge-3]);break;case 21:Se.addEntity(ae[ge-7],ae[ge-5]),Se.setClass([ae[ge-7]],ae[ge-2]);break;case 22:Se.addEntity(ae[ge-3],ae[ge-1]);break;case 23:Se.addEntity(ae[ge-5],ae[ge-3]),Se.setClass([ae[ge-5]],ae[ge]);break;case 24:case 25:this.$=ae[ge].trim(),Se.setAccTitle(this.$);break;case 26:case 27:this.$=ae[ge].trim(),Se.setAccDescription(this.$);break;case 32:Se.setDirection("TB");break;case 33:Se.setDirection("BT");break;case 34:Se.setDirection("RL");break;case 35:Se.setDirection("LR");break;case 36:this.$=ae[ge-3],Se.addClass(ae[ge-2],ae[ge-1]);break;case 37:case 38:case 56:case 64:this.$=[ae[ge]];break;case 39:case 40:this.$=ae[ge-2].concat([ae[ge]]);break;case 41:this.$=ae[ge-2],Se.setClass(ae[ge-1],ae[ge]);break;case 42:this.$=ae[ge-3],Se.addCssStyles(ae[ge-2],ae[ge-1]);break;case 43:this.$=[ae[ge]];break;case 44:ae[ge-2].push(ae[ge]),this.$=ae[ge-2];break;case 46:this.$=ae[ge-1]+ae[ge];break;case 54:case 76:case 77:this.$=ae[ge].replace(/"/g,"");break;case 55:case 78:this.$=ae[ge];break;case 57:ae[ge].push(ae[ge-1]),this.$=ae[ge];break;case 58:this.$={type:ae[ge-1],name:ae[ge]};break;case 59:this.$={type:ae[ge-2],name:ae[ge-1],keys:ae[ge]};break;case 60:this.$={type:ae[ge-2],name:ae[ge-1],comment:ae[ge]};break;case 61:this.$={type:ae[ge-3],name:ae[ge-2],keys:ae[ge-1],comment:ae[ge]};break;case 62:case 63:case 66:this.$=ae[ge];break;case 65:ae[ge-2].push(ae[ge]),this.$=ae[ge-2];break;case 67:this.$=ae[ge].replace(/"/g,"");break;case 68:this.$={cardA:ae[ge],relType:ae[ge-1],cardB:ae[ge-2]};break;case 69:this.$=Se.Cardinality.ZERO_OR_ONE;break;case 70:this.$=Se.Cardinality.ZERO_OR_MORE;break;case 71:this.$=Se.Cardinality.ONE_OR_MORE;break;case 72:this.$=Se.Cardinality.ONLY_ONE;break;case 73:this.$=Se.Cardinality.MD_PARENT;break;case 74:this.$=Se.Identification.NON_IDENTIFYING;break;case 75:this.$=Se.Identification.IDENTIFYING;break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,22:r,24:n,26:i,28:a,29:14,30:15,31:16,32:17,33:s,34:l,35:u,36:h,37:f,40:d,43:p,44:m,50:g},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:27,11:9,22:r,24:n,26:i,28:a,29:14,30:15,31:16,32:17,33:s,34:l,35:u,36:h,37:f,40:d,43:p,44:m,50:g},t(e,[2,5]),t(e,[2,6]),t(e,[2,16],{12:28,61:32,15:[1,29],17:[1,30],20:[1,31],63:y,64:v,65:x,66:b,67:w}),{23:[1,38]},{25:[1,39]},{27:[1,40]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),t(e,[2,30]),t(e,[2,31]),t(C,[2,54]),t(C,[2,55]),t(e,[2,32]),t(e,[2,33]),t(e,[2,34]),t(e,[2,35]),{16:41,40:T,41:E},{16:44,40:T,41:E},{16:45,40:T,41:E},t(e,[2,4]),{11:46,40:d,50:g},{16:47,40:T,41:E},{18:48,19:[1,49],51:50,52:51,56:A},{11:53,40:d,50:g},{62:54,68:[1,55],69:[1,56]},t(S,[2,69]),t(S,[2,70]),t(S,[2,71]),t(S,[2,72]),t(S,[2,73]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),{13:_,38:57,41:I,42:D,45:59,46:60,48:k,49:L},t(R,[2,37]),t(R,[2,38]),{16:65,40:T,41:E,42:D},{13:_,38:66,41:I,42:D,45:59,46:60,48:k,49:L},{13:[1,67],15:[1,68]},t(e,[2,17],{61:32,12:69,17:[1,70],42:D,63:y,64:v,65:x,66:b,67:w}),{19:[1,71]},t(e,[2,14]),{18:72,19:[2,56],51:50,52:51,56:A},{53:73,56:[1,74]},{56:[2,62]},{21:[1,75]},{61:76,63:y,64:v,65:x,66:b,67:w},t(O,[2,74]),t(O,[2,75]),{6:M,10:B,39:77,42:F,47:P},{40:[1,82],41:[1,83]},t(z,[2,43],{46:84,13:_,41:I,48:k,49:L}),t($,[2,45]),t($,[2,50]),t($,[2,51]),t($,[2,52]),t($,[2,53]),t(e,[2,41],{42:D}),{6:M,10:B,39:85,42:F,47:P},{14:86,40:H,50:Q,70:j},{16:90,40:T,41:E},{11:91,40:d,50:g},{18:92,19:[1,93],51:50,52:51,56:A},t(e,[2,12]),{19:[2,57]},t(ie,[2,58],{54:94,55:95,57:96,59:ne,60:le}),t([19,56,59,60],[2,63]),t(e,[2,22],{15:[1,100],17:[1,99]}),t([40,50],[2,68]),t(e,[2,36]),{13:_,41:I,45:101,46:60,48:k,49:L},t(e,[2,47]),t(e,[2,48]),t(e,[2,49]),t(R,[2,39]),t(R,[2,40]),t($,[2,46]),t(e,[2,42]),t(e,[2,8]),t(e,[2,76]),t(e,[2,77]),t(e,[2,78]),{13:[1,102],42:D},{13:[1,104],15:[1,103]},{19:[1,105]},t(e,[2,15]),t(ie,[2,59],{55:106,58:[1,107],60:le}),t(ie,[2,60]),t(he,[2,64]),t(ie,[2,67]),t(he,[2,66]),{18:108,19:[1,109],51:50,52:51,56:A},{16:110,40:T,41:E},t(z,[2,44],{46:84,13:_,41:I,48:k,49:L}),{14:111,40:H,50:Q,70:j},{16:112,40:T,41:E},{14:113,40:H,50:Q,70:j},t(e,[2,13]),t(ie,[2,61]),{57:114,59:ne},{19:[1,115]},t(e,[2,20]),t(e,[2,23],{17:[1,116],42:D}),t(e,[2,11]),{13:[1,117],42:D},t(e,[2,10]),t(he,[2,65]),t(e,[2,18]),{18:118,19:[1,119],51:50,52:51,56:A},{14:120,40:H,50:Q,70:j},{19:[1,121]},t(e,[2,21]),t(e,[2,9]),t(e,[2,19])],defaultActions:{52:[2,62],72:[2,57]},parseError:o(function(se,ue){if(ue.recoverable)this.trace(se);else{var Z=new Error(se);throw Z.hash=ue,Z}},"parseError"),parse:o(function(se){var ue=this,Z=[0],Se=[],ce=[null],ae=[],Oe=this.table,ge="",ze=0,He=0,$e=0,Re=2,Ie=1,be=ae.slice.call(arguments,1),W=Object.create(this.lexer),de={yy:{}};for(var re in this.yy)Object.prototype.hasOwnProperty.call(this.yy,re)&&(de.yy[re]=this.yy[re]);W.setInput(se,de.yy),de.yy.lexer=W,de.yy.parser=this,typeof W.yylloc>"u"&&(W.yylloc={});var oe=W.yylloc;ae.push(oe);var V=W.options&&W.options.ranges;typeof de.yy.parseError=="function"?this.parseError=de.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function xe(ct){Z.length=Z.length-2*ct,ce.length=ce.length-ct,ae.length=ae.length-ct}o(xe,"popStack");function q(){var ct;return ct=Se.pop()||W.lex()||Ie,typeof ct!="number"&&(ct instanceof Array&&(Se=ct,ct=Se.pop()),ct=ue.symbols_[ct]||ct),ct}o(q,"lex");for(var pe,ve,Pe,_e,we,Ve,De={},qe,at,Rt,st;;){if(Pe=Z[Z.length-1],this.defaultActions[Pe]?_e=this.defaultActions[Pe]:((pe===null||typeof pe>"u")&&(pe=q()),_e=Oe[Pe]&&Oe[Pe][pe]),typeof _e>"u"||!_e.length||!_e[0]){var Ue="";st=[];for(qe in Oe[Pe])this.terminals_[qe]&&qe>Re&&st.push("'"+this.terminals_[qe]+"'");W.showPosition?Ue="Parse error on line "+(ze+1)+`:
+`+W.showPosition()+`
+Expecting `+st.join(", ")+", got '"+(this.terminals_[pe]||pe)+"'":Ue="Parse error on line "+(ze+1)+": Unexpected "+(pe==Ie?"end of input":"'"+(this.terminals_[pe]||pe)+"'"),this.parseError(Ue,{text:W.match,token:this.terminals_[pe]||pe,line:W.yylineno,loc:oe,expected:st})}if(_e[0]instanceof Array&&_e.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Pe+", token: "+pe);switch(_e[0]){case 1:Z.push(pe),ce.push(W.yytext),ae.push(W.yylloc),Z.push(_e[1]),pe=null,ve?(pe=ve,ve=null):(He=W.yyleng,ge=W.yytext,ze=W.yylineno,oe=W.yylloc,$e>0&&$e--);break;case 2:if(at=this.productions_[_e[1]][1],De.$=ce[ce.length-at],De._$={first_line:ae[ae.length-(at||1)].first_line,last_line:ae[ae.length-1].last_line,first_column:ae[ae.length-(at||1)].first_column,last_column:ae[ae.length-1].last_column},V&&(De._$.range=[ae[ae.length-(at||1)].range[0],ae[ae.length-1].range[1]]),Ve=this.performAction.apply(De,[ge,He,ze,de.yy,_e[1],ce,ae].concat(be)),typeof Ve<"u")return Ve;at&&(Z=Z.slice(0,-1*at*2),ce=ce.slice(0,-1*at),ae=ae.slice(0,-1*at)),Z.push(this.productions_[_e[1]][0]),ce.push(De.$),ae.push(De._$),Rt=Oe[Z[Z.length-2]][Z[Z.length-1]],Z.push(Rt);break;case 3:return!0}}return!0},"parse")},X=function(){var J={EOF:1,parseError:o(function(ue,Z){if(this.yy.parser)this.yy.parser.parseError(ue,Z);else throw new Error(ue)},"parseError"),setInput:o(function(se,ue){return this.yy=ue||this.yy||{},this._input=se,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var se=this._input[0];this.yytext+=se,this.yyleng++,this.offset++,this.match+=se,this.matched+=se;var ue=se.match(/(?:\r\n?|\n).*/g);return ue?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),se},"input"),unput:o(function(se){var ue=se.length,Z=se.split(/(?:\r\n?|\n)/g);this._input=se+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-ue),this.offset-=ue;var Se=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),Z.length-1&&(this.yylineno-=Z.length-1);var ce=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:Z?(Z.length===Se.length?this.yylloc.first_column:0)+Se[Se.length-Z.length].length-Z[0].length:this.yylloc.first_column-ue},this.options.ranges&&(this.yylloc.range=[ce[0],ce[0]+this.yyleng-ue]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(se){this.unput(this.match.slice(se))},"less"),pastInput:o(function(){var se=this.matched.substr(0,this.matched.length-this.match.length);return(se.length>20?"...":"")+se.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var se=this.match;return se.length<20&&(se+=this._input.substr(0,20-se.length)),(se.substr(0,20)+(se.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var se=this.pastInput(),ue=new Array(se.length+1).join("-");return se+this.upcomingInput()+`
+`+ue+"^"},"showPosition"),test_match:o(function(se,ue){var Z,Se,ce;if(this.options.backtrack_lexer&&(ce={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(ce.yylloc.range=this.yylloc.range.slice(0))),Se=se[0].match(/(?:\r\n?|\n).*/g),Se&&(this.yylineno+=Se.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Se?Se[Se.length-1].length-Se[Se.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+se[0].length},this.yytext+=se[0],this.match+=se[0],this.matches=se,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(se[0].length),this.matched+=se[0],Z=this.performAction.call(this,this.yy,this,ue,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),Z)return Z;if(this._backtrack){for(var ae in ce)this[ae]=ce[ae];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var se,ue,Z,Se;this._more||(this.yytext="",this.match="");for(var ce=this._currentRules(),ae=0;ae<ce.length;ae++)if(Z=this._input.match(this.rules[ce[ae]]),Z&&(!ue||Z[0].length>ue[0].length)){if(ue=Z,Se=ae,this.options.backtrack_lexer){if(se=this.test_match(Z,ce[ae]),se!==!1)return se;if(this._backtrack){ue=!1;continue}else return!1}else if(!this.options.flex)break}return ue?(se=this.test_match(ue,ce[Se]),se!==!1?se:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var ue=this.next();return ue||this.lex()},"lex"),begin:o(function(ue){this.conditionStack.push(ue)},"begin"),popState:o(function(){var ue=this.conditionStack.length-1;return ue>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(ue){return ue=this.conditionStack.length-1-Math.abs(ue||0),ue>=0?this.conditionStack[ue]:"INITIAL"},"topState"),pushState:o(function(ue){this.begin(ue)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(ue,Z,Se,ce){var ae=ce;switch(Se){case 0:return this.begin("acc_title"),24;break;case 1:return this.popState(),"acc_title_value";break;case 2:return this.begin("acc_descr"),26;break;case 3:return this.popState(),"acc_descr_value";break;case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 33;case 8:return 34;case 9:return 35;case 10:return 36;case 11:return 10;case 12:break;case 13:return 8;case 14:return 50;case 15:return 70;case 16:return 4;case 17:return this.begin("block"),17;break;case 18:return 49;case 19:return 49;case 20:return 42;case 21:return 15;case 22:return 13;case 23:break;case 24:return 59;case 25:return 56;case 26:return 56;case 27:return 60;case 28:break;case 29:return this.popState(),19;break;case 30:return Z.yytext[0];case 31:return 20;case 32:return 21;case 33:return this.begin("style"),44;break;case 34:return this.popState(),10;break;case 35:break;case 36:return 13;case 37:return 42;case 38:return 49;case 39:return this.begin("style"),37;break;case 40:return 43;case 41:return 63;case 42:return 65;case 43:return 65;case 44:return 65;case 45:return 63;case 46:return 63;case 47:return 64;case 48:return 64;case 49:return 64;case 50:return 64;case 51:return 64;case 52:return 65;case 53:return 64;case 54:return 65;case 55:return 66;case 56:return 66;case 57:return 66;case 58:return 66;case 59:return 63;case 60:return 64;case 61:return 65;case 62:return 67;case 63:return 68;case 64:return 69;case 65:return 69;case 66:return 68;case 67:return 68;case 68:return 68;case 69:return 41;case 70:return 47;case 71:return 40;case 72:return 48;case 73:return Z.yytext[0];case 74:return 6}},"anonymous"),rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:#)/i,/^(?:#)/i,/^(?:,)/i,/^(?::::)/i,/^(?::)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:([^\s]*)[~].*[~]([^\s]*))/i,/^(?:([\*A-Za-z_\u00C0-\uFFFF][A-Za-z0-9\-\_\[\]\(\)\u00C0-\uFFFF\*]*))/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:style\b)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?::)/i,/^(?:,)/i,/^(?:#)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:;)/i,/^(?:([^\x00-\x7F]|\w|-|\*)+)/i,/^(?:[0-9])/i,/^(?:.)/i,/^(?:$)/i],conditions:{style:{rules:[34,35,36,37,38,69,70],inclusive:!1},acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[23,24,25,26,27,28,29,30],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,31,32,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,71,72,73,74],inclusive:!0}}};return J}();K.lexer=X;function te(){this.yy={}}return o(te,"Parser"),te.prototype=K,K.Parser=te,new te}();wR.parser=wR;Zie=wR});var sk,eae=N(()=>{"use strict";vt();zt();mi();ir();sk=class{constructor(){this.entities=new Map;this.relationships=[];this.classes=new Map;this.direction="TB";this.Cardinality={ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"};this.Identification={NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"};this.setAccTitle=Lr;this.getAccTitle=Rr;this.setAccDescription=Nr;this.getAccDescription=Mr;this.setDiagramTitle=$r;this.getDiagramTitle=Ir;this.getConfig=o(()=>me().er,"getConfig");this.clear(),this.addEntity=this.addEntity.bind(this),this.addAttributes=this.addAttributes.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setDirection=this.setDirection.bind(this),this.addCssStyles=this.addCssStyles.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{o(this,"ErDB")}addEntity(e,r=""){return this.entities.has(e)?!this.entities.get(e)?.alias&&r&&(this.entities.get(e).alias=r,Y.info(`Add alias '${r}' to entity '${e}'`)):(this.entities.set(e,{id:`entity-${e}-${this.entities.size}`,label:e,attributes:[],alias:r,shape:"erBox",look:me().look??"default",cssClasses:"default",cssStyles:[]}),Y.info("Added new entity :",e)),this.entities.get(e)}getEntity(e){return this.entities.get(e)}getEntities(){return this.entities}getClasses(){return this.classes}addAttributes(e,r){let n=this.addEntity(e),i;for(i=r.length-1;i>=0;i--)r[i].keys||(r[i].keys=[]),r[i].comment||(r[i].comment=""),n.attributes.push(r[i]),Y.debug("Added attribute ",r[i].name)}addRelationship(e,r,n,i){let a=this.entities.get(e),s=this.entities.get(n);if(!a||!s)return;let l={entityA:a.id,roleA:r,entityB:s.id,relSpec:i};this.relationships.push(l),Y.debug("Added new relationship :",l)}getRelationships(){return this.relationships}getDirection(){return this.direction}setDirection(e){this.direction=e}getCompiledStyles(e){let r=[];for(let n of e){let i=this.classes.get(n);i?.styles&&(r=[...r,...i.styles??[]].map(a=>a.trim())),i?.textStyles&&(r=[...r,...i.textStyles??[]].map(a=>a.trim()))}return r}addCssStyles(e,r){for(let n of e){let i=this.entities.get(n);if(!r||!i)return;for(let a of r)i.cssStyles.push(a)}}addClass(e,r){e.forEach(n=>{let i=this.classes.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.classes.set(n,i)),r&&r.forEach(function(a){if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)})})}setClass(e,r){for(let n of e){let i=this.entities.get(n);if(i)for(let a of r)i.cssClasses+=" "+a}}clear(){this.entities=new Map,this.classes=new Map,this.relationships=[],Ar()}getData(){let e=[],r=[],n=me();for(let a of this.entities.keys()){let s=this.entities.get(a);s&&(s.cssCompiledStyles=this.getCompiledStyles(s.cssClasses.split(" ")),e.push(s))}let i=0;for(let a of this.relationships){let s={id:$h(a.entityA,a.entityB,{prefix:"id",counter:i++}),type:"normal",curve:"basis",start:a.entityA,end:a.entityB,label:a.roleA,labelpos:"c",thickness:"normal",classes:"relationshipLine",arrowTypeStart:a.relSpec.cardB.toLowerCase(),arrowTypeEnd:a.relSpec.cardA.toLowerCase(),pattern:a.relSpec.relType=="IDENTIFYING"?"solid":"dashed",look:n.look};r.push(s)}return{nodes:e,edges:r,other:{},config:n,direction:"TB"}}}});var TR={};hr(TR,{draw:()=>SOe});var SOe,tae=N(()=>{"use strict";zt();vt();gm();Yd();$m();ir();dr();SOe=o(async function(t,e,r,n){Y.info("REF0:"),Y.info("Drawing er diagram (unified)",e);let{securityLevel:i,er:a,layout:s}=me(),l=n.db.getData(),u=yc(e,i);l.type=n.type,l.layoutAlgorithm=nf(s),l.config.flowchart.nodeSpacing=a?.nodeSpacing||140,l.config.flowchart.rankSpacing=a?.rankSpacing||80,l.direction=n.db.getDirection(),l.markers=["only_one","zero_or_one","one_or_more","zero_or_more"],l.diagramId=e,await Cc(l,u),l.layoutAlgorithm==="elk"&&u.select(".edges").lower();let h=u.selectAll('[id*="-background"]');Array.from(h).length>0&&h.each(function(){let d=Ge(this),m=d.attr("id").replace("-background",""),g=u.select(`#${CSS.escape(m)}`);if(!g.empty()){let y=g.attr("transform");d.attr("transform",y)}});let f=8;Gt.insertTitle(u,"erDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Ac(u,f,"erDiagram",a?.useMaxWidth??!0)},"draw")});var COe,AOe,rae,nae=N(()=>{"use strict";Ys();COe=o((t,e)=>{let r=Kf,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return qa(n,i,a,e)},"fade"),AOe=o(t=>`
+ .entityBox {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+ }
+
+ .relationshipLabelBox {
+ fill: ${t.tertiaryColor};
+ opacity: 0.7;
+ background-color: ${t.tertiaryColor};
+ rect {
+ opacity: 0.5;
+ }
+ }
+
+ .labelBkg {
+ background-color: ${COe(t.tertiaryColor,.5)};
+ }
+
+ .edgeLabel .label {
+ fill: ${t.nodeBorder};
+ font-size: 14px;
+ }
+
+ .label {
+ font-family: ${t.fontFamily};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+
+ .edge-pattern-dashed {
+ stroke-dasharray: 8,8;
+ }
+
+ .node rect,
+ .node circle,
+ .node ellipse,
+ .node polygon
+ {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+ stroke-width: 1px;
+ }
+
+ .relationshipLine {
+ stroke: ${t.lineColor};
+ stroke-width: 1;
+ fill: none;
+ }
+
+ .marker {
+ fill: none !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+ }
+`,"getStyles"),rae=AOe});var iae={};hr(iae,{diagram:()=>_Oe});var _Oe,aae=N(()=>{"use strict";Jie();eae();tae();nae();_Oe={parser:Zie,get db(){return new sk},renderer:TR,styles:rae}});function ii(t){return typeof t=="object"&&t!==null&&typeof t.$type=="string"}function va(t){return typeof t=="object"&&t!==null&&typeof t.$refText=="string"}function kR(t){return typeof t=="object"&&t!==null&&typeof t.name=="string"&&typeof t.type=="string"&&typeof t.path=="string"}function jd(t){return typeof t=="object"&&t!==null&&ii(t.container)&&va(t.reference)&&typeof t.message=="string"}function Ll(t){return typeof t=="object"&&t!==null&&Array.isArray(t.content)}function af(t){return typeof t=="object"&&t!==null&&typeof t.tokenType=="object"}function M2(t){return Ll(t)&&typeof t.fullText=="string"}var Xd,Rl=N(()=>{"use strict";o(ii,"isAstNode");o(va,"isReference");o(kR,"isAstNodeDescription");o(jd,"isLinkingError");Xd=class{static{o(this,"AbstractAstReflection")}constructor(){this.subtypes={},this.allSubtypes={}}isInstance(e,r){return ii(e)&&this.isSubtype(e.$type,r)}isSubtype(e,r){if(e===r)return!0;let n=this.subtypes[e];n||(n=this.subtypes[e]={});let i=n[r];if(i!==void 0)return i;{let a=this.computeIsSubtype(e,r);return n[r]=a,a}}getAllSubTypes(e){let r=this.allSubtypes[e];if(r)return r;{let n=this.getAllTypes(),i=[];for(let a of n)this.isSubtype(a,e)&&i.push(a);return this.allSubtypes[e]=i,i}}};o(Ll,"isCompositeCstNode");o(af,"isLeafCstNode");o(M2,"isRootCstNode")});function NOe(t){return typeof t=="string"?t:typeof t>"u"?"undefined":typeof t.toString=="function"?t.toString():Object.prototype.toString.call(t)}function ok(t){return!!t&&typeof t[Symbol.iterator]=="function"}function en(...t){if(t.length===1){let e=t[0];if(e instanceof ao)return e;if(ok(e))return new ao(()=>e[Symbol.iterator](),r=>r.next());if(typeof e.length=="number")return new ao(()=>({index:0}),r=>r.index<e.length?{done:!1,value:e[r.index++]}:Ia)}return t.length>1?new ao(()=>({collIndex:0,arrIndex:0}),e=>{do{if(e.iterator){let r=e.iterator.next();if(!r.done)return r;e.iterator=void 0}if(e.array){if(e.arrIndex<e.array.length)return{done:!1,value:e.array[e.arrIndex++]};e.array=void 0,e.arrIndex=0}if(e.collIndex<t.length){let r=t[e.collIndex++];ok(r)?e.iterator=r[Symbol.iterator]():r&&typeof r.length=="number"&&(e.array=r)}}while(e.iterator||e.array||e.collIndex<t.length);return Ia}):I2}var ao,I2,Ia,_c,zm,Ps=N(()=>{"use strict";ao=class t{static{o(this,"StreamImpl")}constructor(e,r){this.startFn=e,this.nextFn=r}iterator(){let e={state:this.startFn(),next:o(()=>this.nextFn(e.state),"next"),[Symbol.iterator]:()=>e};return e}[Symbol.iterator](){return this.iterator()}isEmpty(){return!!this.iterator().next().done}count(){let e=this.iterator(),r=0,n=e.next();for(;!n.done;)r++,n=e.next();return r}toArray(){let e=[],r=this.iterator(),n;do n=r.next(),n.value!==void 0&&e.push(n.value);while(!n.done);return e}toSet(){return new Set(this)}toMap(e,r){let n=this.map(i=>[e?e(i):i,r?r(i):i]);return new Map(n)}toString(){return this.join()}concat(e){return new t(()=>({first:this.startFn(),firstDone:!1,iterator:e[Symbol.iterator]()}),r=>{let n;if(!r.firstDone){do if(n=this.nextFn(r.first),!n.done)return n;while(!n.done);r.firstDone=!0}do if(n=r.iterator.next(),!n.done)return n;while(!n.done);return Ia})}join(e=","){let r=this.iterator(),n="",i,a=!1;do i=r.next(),i.done||(a&&(n+=e),n+=NOe(i.value)),a=!0;while(!i.done);return n}indexOf(e,r=0){let n=this.iterator(),i=0,a=n.next();for(;!a.done;){if(i>=r&&a.value===e)return i;a=n.next(),i++}return-1}every(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(!e(n.value))return!1;n=r.next()}return!0}some(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(e(n.value))return!0;n=r.next()}return!1}forEach(e){let r=this.iterator(),n=0,i=r.next();for(;!i.done;)e(i.value,n),i=r.next(),n++}map(e){return new t(this.startFn,r=>{let{done:n,value:i}=this.nextFn(r);return n?Ia:{done:!1,value:e(i)}})}filter(e){return new t(this.startFn,r=>{let n;do if(n=this.nextFn(r),!n.done&&e(n.value))return n;while(!n.done);return Ia})}nonNullable(){return this.filter(e=>e!=null)}reduce(e,r){let n=this.iterator(),i=r,a=n.next();for(;!a.done;)i===void 0?i=a.value:i=e(i,a.value),a=n.next();return i}reduceRight(e,r){return this.recursiveReduce(this.iterator(),e,r)}recursiveReduce(e,r,n){let i=e.next();if(i.done)return n;let a=this.recursiveReduce(e,r,n);return a===void 0?i.value:r(a,i.value)}find(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(e(n.value))return n.value;n=r.next()}}findIndex(e){let r=this.iterator(),n=0,i=r.next();for(;!i.done;){if(e(i.value))return n;i=r.next(),n++}return-1}includes(e){let r=this.iterator(),n=r.next();for(;!n.done;){if(n.value===e)return!0;n=r.next()}return!1}flatMap(e){return new t(()=>({this:this.startFn()}),r=>{do{if(r.iterator){let a=r.iterator.next();if(a.done)r.iterator=void 0;else return a}let{done:n,value:i}=this.nextFn(r.this);if(!n){let a=e(i);if(ok(a))r.iterator=a[Symbol.iterator]();else return{done:!1,value:a}}}while(r.iterator);return Ia})}flat(e){if(e===void 0&&(e=1),e<=0)return this;let r=e>1?this.flat(e-1):this;return new t(()=>({this:r.startFn()}),n=>{do{if(n.iterator){let s=n.iterator.next();if(s.done)n.iterator=void 0;else return s}let{done:i,value:a}=r.nextFn(n.this);if(!i)if(ok(a))n.iterator=a[Symbol.iterator]();else return{done:!1,value:a}}while(n.iterator);return Ia})}head(){let r=this.iterator().next();if(!r.done)return r.value}tail(e=1){return new t(()=>{let r=this.startFn();for(let n=0;n<e;n++)if(this.nextFn(r).done)return r;return r},this.nextFn)}limit(e){return new t(()=>({size:0,state:this.startFn()}),r=>(r.size++,r.size>e?Ia:this.nextFn(r.state)))}distinct(e){return new t(()=>({set:new Set,internalState:this.startFn()}),r=>{let n;do if(n=this.nextFn(r.internalState),!n.done){let i=e?e(n.value):n.value;if(!r.set.has(i))return r.set.add(i),n}while(!n.done);return Ia})}exclude(e,r){let n=new Set;for(let i of e){let a=r?r(i):i;n.add(a)}return this.filter(i=>{let a=r?r(i):i;return!n.has(a)})}};o(NOe,"toString");o(ok,"isIterable");I2=new ao(()=>{},()=>Ia),Ia=Object.freeze({done:!0,value:void 0});o(en,"stream");_c=class extends ao{static{o(this,"TreeStreamImpl")}constructor(e,r,n){super(()=>({iterators:n?.includeRoot?[[e][Symbol.iterator]()]:[r(e)[Symbol.iterator]()],pruned:!1}),i=>{for(i.pruned&&(i.iterators.pop(),i.pruned=!1);i.iterators.length>0;){let s=i.iterators[i.iterators.length-1].next();if(s.done)i.iterators.pop();else return i.iterators.push(r(s.value)[Symbol.iterator]()),s}return Ia})}iterator(){let e={state:this.startFn(),next:o(()=>this.nextFn(e.state),"next"),prune:o(()=>{e.state.pruned=!0},"prune"),[Symbol.iterator]:()=>e};return e}};(function(t){function e(a){return a.reduce((s,l)=>s+l,0)}o(e,"sum"),t.sum=e;function r(a){return a.reduce((s,l)=>s*l,0)}o(r,"product"),t.product=r;function n(a){return a.reduce((s,l)=>Math.min(s,l))}o(n,"min"),t.min=n;function i(a){return a.reduce((s,l)=>Math.max(s,l))}o(i,"max"),t.max=i})(zm||(zm={}))});var ck={};hr(ck,{DefaultNameRegexp:()=>lk,RangeComparison:()=>Dc,compareRange:()=>cae,findCommentNode:()=>AR,findDeclarationNodeAtOffset:()=>IOe,findLeafNodeAtOffset:()=>_R,findLeafNodeBeforeOffset:()=>uae,flattenCst:()=>MOe,getInteriorNodes:()=>BOe,getNextNode:()=>OOe,getPreviousNode:()=>fae,getStartlineNode:()=>POe,inRange:()=>CR,isChildNode:()=>SR,isCommentNode:()=>ER,streamCst:()=>Kd,toDocumentSegment:()=>Qd,tokenToRange:()=>Gm});function Kd(t){return new _c(t,e=>Ll(e)?e.content:[],{includeRoot:!0})}function MOe(t){return Kd(t).filter(af)}function SR(t,e){for(;t.container;)if(t=t.container,t===e)return!0;return!1}function Gm(t){return{start:{character:t.startColumn-1,line:t.startLine-1},end:{character:t.endColumn,line:t.endLine-1}}}function Qd(t){if(!t)return;let{offset:e,end:r,range:n}=t;return{range:n,offset:e,end:r,length:r-e}}function cae(t,e){if(t.end.line<e.start.line||t.end.line===e.start.line&&t.end.character<=e.start.character)return Dc.Before;if(t.start.line>e.end.line||t.start.line===e.end.line&&t.start.character>=e.end.character)return Dc.After;let r=t.start.line>e.start.line||t.start.line===e.start.line&&t.start.character>=e.start.character,n=t.end.line<e.end.line||t.end.line===e.end.line&&t.end.character<=e.end.character;return r&&n?Dc.Inside:r?Dc.OverlapBack:n?Dc.OverlapFront:Dc.Outside}function CR(t,e){return cae(t,e)>Dc.After}function IOe(t,e,r=lk){if(t){if(e>0){let n=e-t.offset,i=t.text.charAt(n);r.test(i)||e--}return _R(t,e)}}function AR(t,e){if(t){let r=fae(t,!0);if(r&&ER(r,e))return r;if(M2(t)){let n=t.content.findIndex(i=>!i.hidden);for(let i=n-1;i>=0;i--){let a=t.content[i];if(ER(a,e))return a}}}}function ER(t,e){return af(t)&&e.includes(t.tokenType.name)}function _R(t,e){if(af(t))return t;if(Ll(t)){let r=hae(t,e,!1);if(r)return _R(r,e)}}function uae(t,e){if(af(t))return t;if(Ll(t)){let r=hae(t,e,!0);if(r)return uae(r,e)}}function hae(t,e,r){let n=0,i=t.content.length-1,a;for(;n<=i;){let s=Math.floor((n+i)/2),l=t.content[s];if(l.offset<=e&&l.end>e)return l;l.end<=e?(a=r?l:void 0,n=s+1):i=s-1}return a}function fae(t,e=!0){for(;t.container;){let r=t.container,n=r.content.indexOf(t);for(;n>0;){n--;let i=r.content[n];if(e||!i.hidden)return i}t=r}}function OOe(t,e=!0){for(;t.container;){let r=t.container,n=r.content.indexOf(t),i=r.content.length-1;for(;n<i;){n++;let a=r.content[n];if(e||!a.hidden)return a}t=r}}function POe(t){if(t.range.start.character===0)return t;let e=t.range.start.line,r=t,n;for(;t.container;){let i=t.container,a=n??i.content.indexOf(t);if(a===0?(t=i,n=void 0):(n=a-1,t=i.content[n]),t.range.start.line!==e)break;r=t}return r}function BOe(t,e){let r=FOe(t,e);return r?r.parent.content.slice(r.a+1,r.b):[]}function FOe(t,e){let r=lae(t),n=lae(e),i;for(let a=0;a<r.length&&a<n.length;a++){let s=r[a],l=n[a];if(s.parent===l.parent)i={parent:s.parent,a:s.index,b:l.index};else break}return i}function lae(t){let e=[];for(;t.container;){let r=t.container,n=r.content.indexOf(t);e.push({parent:r,index:n}),t=r}return e.reverse()}var Dc,lk,Nl=N(()=>{"use strict";Rl();Ps();o(Kd,"streamCst");o(MOe,"flattenCst");o(SR,"isChildNode");o(Gm,"tokenToRange");o(Qd,"toDocumentSegment");(function(t){t[t.Before=0]="Before",t[t.After=1]="After",t[t.OverlapFront=2]="OverlapFront",t[t.OverlapBack=3]="OverlapBack",t[t.Inside=4]="Inside",t[t.Outside=5]="Outside"})(Dc||(Dc={}));o(cae,"compareRange");o(CR,"inRange");lk=/^[\w\p{L}]$/u;o(IOe,"findDeclarationNodeAtOffset");o(AR,"findCommentNode");o(ER,"isCommentNode");o(_R,"findLeafNodeAtOffset");o(uae,"findLeafNodeBeforeOffset");o(hae,"binarySearch");o(fae,"getPreviousNode");o(OOe,"getNextNode");o(POe,"getStartlineNode");o(BOe,"getInteriorNodes");o(FOe,"getCommonParent");o(lae,"getParentChain")});function Lc(t){throw new Error("Error! The input value was not handled.")}var Zd,uk=N(()=>{"use strict";Zd=class extends Error{static{o(this,"ErrorWithLocation")}constructor(e,r){super(e?`${r} at ${e.range.start.line}:${e.range.start.character}`:r)}};o(Lc,"assertUnreachable")});var U2={};hr(U2,{AbstractElement:()=>Hm,AbstractRule:()=>Vm,AbstractType:()=>Um,Action:()=>cg,Alternatives:()=>ug,ArrayLiteral:()=>Wm,ArrayType:()=>qm,Assignment:()=>hg,BooleanLiteral:()=>Ym,CharacterRange:()=>fg,Condition:()=>O2,Conjunction:()=>Xm,CrossReference:()=>dg,Disjunction:()=>jm,EndOfFile:()=>pg,Grammar:()=>Km,GrammarImport:()=>B2,Group:()=>mg,InferredType:()=>Qm,Interface:()=>Zm,Keyword:()=>gg,LangiumGrammarAstReflection:()=>Cg,LangiumGrammarTerminals:()=>$Oe,NamedArgument:()=>F2,NegatedToken:()=>yg,Negation:()=>Jm,NumberLiteral:()=>eg,Parameter:()=>tg,ParameterReference:()=>rg,ParserRule:()=>ng,ReferenceType:()=>ig,RegexToken:()=>vg,ReturnType:()=>$2,RuleCall:()=>xg,SimpleType:()=>ag,StringLiteral:()=>sg,TerminalAlternatives:()=>bg,TerminalGroup:()=>wg,TerminalRule:()=>Jd,TerminalRuleCall:()=>Tg,Type:()=>og,TypeAttribute:()=>z2,TypeDefinition:()=>hk,UnionType:()=>lg,UnorderedGroup:()=>kg,UntilToken:()=>Eg,ValueLiteral:()=>P2,Wildcard:()=>Sg,isAbstractElement:()=>G2,isAbstractRule:()=>zOe,isAbstractType:()=>GOe,isAction:()=>Mu,isAlternatives:()=>mk,isArrayLiteral:()=>qOe,isArrayType:()=>DR,isAssignment:()=>Ml,isBooleanLiteral:()=>LR,isCharacterRange:()=>FR,isCondition:()=>VOe,isConjunction:()=>RR,isCrossReference:()=>ep,isDisjunction:()=>NR,isEndOfFile:()=>$R,isFeatureName:()=>UOe,isGrammar:()=>YOe,isGrammarImport:()=>XOe,isGroup:()=>sf,isInferredType:()=>fk,isInterface:()=>dk,isKeyword:()=>Ho,isNamedArgument:()=>jOe,isNegatedToken:()=>zR,isNegation:()=>MR,isNumberLiteral:()=>KOe,isParameter:()=>QOe,isParameterReference:()=>IR,isParserRule:()=>Oa,isPrimitiveType:()=>dae,isReferenceType:()=>OR,isRegexToken:()=>GR,isReturnType:()=>PR,isRuleCall:()=>Il,isSimpleType:()=>pk,isStringLiteral:()=>ZOe,isTerminalAlternatives:()=>VR,isTerminalGroup:()=>UR,isTerminalRule:()=>so,isTerminalRuleCall:()=>gk,isType:()=>V2,isTypeAttribute:()=>JOe,isTypeDefinition:()=>HOe,isUnionType:()=>BR,isUnorderedGroup:()=>yk,isUntilToken:()=>HR,isValueLiteral:()=>WOe,isWildcard:()=>WR,reflection:()=>lr});function zOe(t){return lr.isInstance(t,Vm)}function GOe(t){return lr.isInstance(t,Um)}function VOe(t){return lr.isInstance(t,O2)}function UOe(t){return dae(t)||t==="current"||t==="entry"||t==="extends"||t==="false"||t==="fragment"||t==="grammar"||t==="hidden"||t==="import"||t==="interface"||t==="returns"||t==="terminal"||t==="true"||t==="type"||t==="infer"||t==="infers"||t==="with"||typeof t=="string"&&/\^?[_a-zA-Z][\w_]*/.test(t)}function dae(t){return t==="string"||t==="number"||t==="boolean"||t==="Date"||t==="bigint"}function HOe(t){return lr.isInstance(t,hk)}function WOe(t){return lr.isInstance(t,P2)}function G2(t){return lr.isInstance(t,Hm)}function qOe(t){return lr.isInstance(t,Wm)}function DR(t){return lr.isInstance(t,qm)}function LR(t){return lr.isInstance(t,Ym)}function RR(t){return lr.isInstance(t,Xm)}function NR(t){return lr.isInstance(t,jm)}function YOe(t){return lr.isInstance(t,Km)}function XOe(t){return lr.isInstance(t,B2)}function fk(t){return lr.isInstance(t,Qm)}function dk(t){return lr.isInstance(t,Zm)}function jOe(t){return lr.isInstance(t,F2)}function MR(t){return lr.isInstance(t,Jm)}function KOe(t){return lr.isInstance(t,eg)}function QOe(t){return lr.isInstance(t,tg)}function IR(t){return lr.isInstance(t,rg)}function Oa(t){return lr.isInstance(t,ng)}function OR(t){return lr.isInstance(t,ig)}function PR(t){return lr.isInstance(t,$2)}function pk(t){return lr.isInstance(t,ag)}function ZOe(t){return lr.isInstance(t,sg)}function so(t){return lr.isInstance(t,Jd)}function V2(t){return lr.isInstance(t,og)}function JOe(t){return lr.isInstance(t,z2)}function BR(t){return lr.isInstance(t,lg)}function Mu(t){return lr.isInstance(t,cg)}function mk(t){return lr.isInstance(t,ug)}function Ml(t){return lr.isInstance(t,hg)}function FR(t){return lr.isInstance(t,fg)}function ep(t){return lr.isInstance(t,dg)}function $R(t){return lr.isInstance(t,pg)}function sf(t){return lr.isInstance(t,mg)}function Ho(t){return lr.isInstance(t,gg)}function zR(t){return lr.isInstance(t,yg)}function GR(t){return lr.isInstance(t,vg)}function Il(t){return lr.isInstance(t,xg)}function VR(t){return lr.isInstance(t,bg)}function UR(t){return lr.isInstance(t,wg)}function gk(t){return lr.isInstance(t,Tg)}function yk(t){return lr.isInstance(t,kg)}function HR(t){return lr.isInstance(t,Eg)}function WR(t){return lr.isInstance(t,Sg)}var $Oe,Vm,Um,O2,hk,P2,Hm,Wm,qm,Ym,Xm,jm,Km,B2,Qm,Zm,F2,Jm,eg,tg,rg,ng,ig,$2,ag,sg,Jd,og,z2,lg,cg,ug,hg,fg,dg,pg,mg,gg,yg,vg,xg,bg,wg,Tg,kg,Eg,Sg,Cg,lr,Rc=N(()=>{"use strict";Rl();$Oe={ID:/\^?[_a-zA-Z][\w_]*/,STRING:/"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/,NUMBER:/NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity)/,RegexLiteral:/\/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/[a-z]*/,WS:/\s+/,ML_COMMENT:/\/\*[\s\S]*?\*\//,SL_COMMENT:/\/\/[^\n\r]*/},Vm="AbstractRule";o(zOe,"isAbstractRule");Um="AbstractType";o(GOe,"isAbstractType");O2="Condition";o(VOe,"isCondition");o(UOe,"isFeatureName");o(dae,"isPrimitiveType");hk="TypeDefinition";o(HOe,"isTypeDefinition");P2="ValueLiteral";o(WOe,"isValueLiteral");Hm="AbstractElement";o(G2,"isAbstractElement");Wm="ArrayLiteral";o(qOe,"isArrayLiteral");qm="ArrayType";o(DR,"isArrayType");Ym="BooleanLiteral";o(LR,"isBooleanLiteral");Xm="Conjunction";o(RR,"isConjunction");jm="Disjunction";o(NR,"isDisjunction");Km="Grammar";o(YOe,"isGrammar");B2="GrammarImport";o(XOe,"isGrammarImport");Qm="InferredType";o(fk,"isInferredType");Zm="Interface";o(dk,"isInterface");F2="NamedArgument";o(jOe,"isNamedArgument");Jm="Negation";o(MR,"isNegation");eg="NumberLiteral";o(KOe,"isNumberLiteral");tg="Parameter";o(QOe,"isParameter");rg="ParameterReference";o(IR,"isParameterReference");ng="ParserRule";o(Oa,"isParserRule");ig="ReferenceType";o(OR,"isReferenceType");$2="ReturnType";o(PR,"isReturnType");ag="SimpleType";o(pk,"isSimpleType");sg="StringLiteral";o(ZOe,"isStringLiteral");Jd="TerminalRule";o(so,"isTerminalRule");og="Type";o(V2,"isType");z2="TypeAttribute";o(JOe,"isTypeAttribute");lg="UnionType";o(BR,"isUnionType");cg="Action";o(Mu,"isAction");ug="Alternatives";o(mk,"isAlternatives");hg="Assignment";o(Ml,"isAssignment");fg="CharacterRange";o(FR,"isCharacterRange");dg="CrossReference";o(ep,"isCrossReference");pg="EndOfFile";o($R,"isEndOfFile");mg="Group";o(sf,"isGroup");gg="Keyword";o(Ho,"isKeyword");yg="NegatedToken";o(zR,"isNegatedToken");vg="RegexToken";o(GR,"isRegexToken");xg="RuleCall";o(Il,"isRuleCall");bg="TerminalAlternatives";o(VR,"isTerminalAlternatives");wg="TerminalGroup";o(UR,"isTerminalGroup");Tg="TerminalRuleCall";o(gk,"isTerminalRuleCall");kg="UnorderedGroup";o(yk,"isUnorderedGroup");Eg="UntilToken";o(HR,"isUntilToken");Sg="Wildcard";o(WR,"isWildcard");Cg=class extends Xd{static{o(this,"LangiumGrammarAstReflection")}getAllTypes(){return[Hm,Vm,Um,cg,ug,Wm,qm,hg,Ym,fg,O2,Xm,dg,jm,pg,Km,B2,mg,Qm,Zm,gg,F2,yg,Jm,eg,tg,rg,ng,ig,vg,$2,xg,ag,sg,bg,wg,Jd,Tg,og,z2,hk,lg,kg,Eg,P2,Sg]}computeIsSubtype(e,r){switch(e){case cg:case ug:case hg:case fg:case dg:case pg:case mg:case gg:case yg:case vg:case xg:case bg:case wg:case Tg:case kg:case Eg:case Sg:return this.isSubtype(Hm,r);case Wm:case eg:case sg:return this.isSubtype(P2,r);case qm:case ig:case ag:case lg:return this.isSubtype(hk,r);case Ym:return this.isSubtype(O2,r)||this.isSubtype(P2,r);case Xm:case jm:case Jm:case rg:return this.isSubtype(O2,r);case Qm:case Zm:case og:return this.isSubtype(Um,r);case ng:return this.isSubtype(Vm,r)||this.isSubtype(Um,r);case Jd:return this.isSubtype(Vm,r);default:return!1}}getReferenceType(e){let r=`${e.container.$type}:${e.property}`;switch(r){case"Action:type":case"CrossReference:type":case"Interface:superTypes":case"ParserRule:returnType":case"SimpleType:typeRef":return Um;case"Grammar:hiddenTokens":case"ParserRule:hiddenTokens":case"RuleCall:rule":return Vm;case"Grammar:usedGrammars":return Km;case"NamedArgument:parameter":case"ParameterReference:parameter":return tg;case"TerminalRuleCall:rule":return Jd;default:throw new Error(`${r} is not a valid reference id.`)}}getTypeMetaData(e){switch(e){case Hm:return{name:Hm,properties:[{name:"cardinality"},{name:"lookahead"}]};case Wm:return{name:Wm,properties:[{name:"elements",defaultValue:[]}]};case qm:return{name:qm,properties:[{name:"elementType"}]};case Ym:return{name:Ym,properties:[{name:"true",defaultValue:!1}]};case Xm:return{name:Xm,properties:[{name:"left"},{name:"right"}]};case jm:return{name:jm,properties:[{name:"left"},{name:"right"}]};case Km:return{name:Km,properties:[{name:"definesHiddenTokens",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"imports",defaultValue:[]},{name:"interfaces",defaultValue:[]},{name:"isDeclared",defaultValue:!1},{name:"name"},{name:"rules",defaultValue:[]},{name:"types",defaultValue:[]},{name:"usedGrammars",defaultValue:[]}]};case B2:return{name:B2,properties:[{name:"path"}]};case Qm:return{name:Qm,properties:[{name:"name"}]};case Zm:return{name:Zm,properties:[{name:"attributes",defaultValue:[]},{name:"name"},{name:"superTypes",defaultValue:[]}]};case F2:return{name:F2,properties:[{name:"calledByName",defaultValue:!1},{name:"parameter"},{name:"value"}]};case Jm:return{name:Jm,properties:[{name:"value"}]};case eg:return{name:eg,properties:[{name:"value"}]};case tg:return{name:tg,properties:[{name:"name"}]};case rg:return{name:rg,properties:[{name:"parameter"}]};case ng:return{name:ng,properties:[{name:"dataType"},{name:"definesHiddenTokens",defaultValue:!1},{name:"definition"},{name:"entry",defaultValue:!1},{name:"fragment",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"inferredType"},{name:"name"},{name:"parameters",defaultValue:[]},{name:"returnType"},{name:"wildcard",defaultValue:!1}]};case ig:return{name:ig,properties:[{name:"referenceType"}]};case $2:return{name:$2,properties:[{name:"name"}]};case ag:return{name:ag,properties:[{name:"primitiveType"},{name:"stringType"},{name:"typeRef"}]};case sg:return{name:sg,properties:[{name:"value"}]};case Jd:return{name:Jd,properties:[{name:"definition"},{name:"fragment",defaultValue:!1},{name:"hidden",defaultValue:!1},{name:"name"},{name:"type"}]};case og:return{name:og,properties:[{name:"name"},{name:"type"}]};case z2:return{name:z2,properties:[{name:"defaultValue"},{name:"isOptional",defaultValue:!1},{name:"name"},{name:"type"}]};case lg:return{name:lg,properties:[{name:"types",defaultValue:[]}]};case cg:return{name:cg,properties:[{name:"cardinality"},{name:"feature"},{name:"inferredType"},{name:"lookahead"},{name:"operator"},{name:"type"}]};case ug:return{name:ug,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case hg:return{name:hg,properties:[{name:"cardinality"},{name:"feature"},{name:"lookahead"},{name:"operator"},{name:"terminal"}]};case fg:return{name:fg,properties:[{name:"cardinality"},{name:"left"},{name:"lookahead"},{name:"right"}]};case dg:return{name:dg,properties:[{name:"cardinality"},{name:"deprecatedSyntax",defaultValue:!1},{name:"lookahead"},{name:"terminal"},{name:"type"}]};case pg:return{name:pg,properties:[{name:"cardinality"},{name:"lookahead"}]};case mg:return{name:mg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"guardCondition"},{name:"lookahead"}]};case gg:return{name:gg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"value"}]};case yg:return{name:yg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case vg:return{name:vg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"regex"}]};case xg:return{name:xg,properties:[{name:"arguments",defaultValue:[]},{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case bg:return{name:bg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case wg:return{name:wg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Tg:return{name:Tg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case kg:return{name:kg,properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case Eg:return{name:Eg,properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case Sg:return{name:Sg,properties:[{name:"cardinality"},{name:"lookahead"}]};default:return{name:e,properties:[]}}}},lr=new Cg});var xk={};hr(xk,{assignMandatoryProperties:()=>XR,copyAstNode:()=>YR,findLocalReferences:()=>tPe,findRootNode:()=>H2,getContainerOfType:()=>tp,getDocument:()=>Pa,hasContainerOfType:()=>ePe,linkContentToContainer:()=>vk,streamAllContents:()=>Nc,streamAst:()=>Wo,streamContents:()=>W2,streamReferences:()=>Ag});function vk(t){for(let[e,r]of Object.entries(t))e.startsWith("$")||(Array.isArray(r)?r.forEach((n,i)=>{ii(n)&&(n.$container=t,n.$containerProperty=e,n.$containerIndex=i)}):ii(r)&&(r.$container=t,r.$containerProperty=e))}function tp(t,e){let r=t;for(;r;){if(e(r))return r;r=r.$container}}function ePe(t,e){let r=t;for(;r;){if(e(r))return!0;r=r.$container}return!1}function Pa(t){let r=H2(t).$document;if(!r)throw new Error("AST node has no document.");return r}function H2(t){for(;t.$container;)t=t.$container;return t}function W2(t,e){if(!t)throw new Error("Node must be an AstNode.");let r=e?.range;return new ao(()=>({keys:Object.keys(t),keyIndex:0,arrayIndex:0}),n=>{for(;n.keyIndex<n.keys.length;){let i=n.keys[n.keyIndex];if(!i.startsWith("$")){let a=t[i];if(ii(a)){if(n.keyIndex++,qR(a,r))return{done:!1,value:a}}else if(Array.isArray(a)){for(;n.arrayIndex<a.length;){let s=n.arrayIndex++,l=a[s];if(ii(l)&&qR(l,r))return{done:!1,value:l}}n.arrayIndex=0}}n.keyIndex++}return Ia})}function Nc(t,e){if(!t)throw new Error("Root node must be an AstNode.");return new _c(t,r=>W2(r,e))}function Wo(t,e){if(t){if(e?.range&&!qR(t,e.range))return new _c(t,()=>[])}else throw new Error("Root node must be an AstNode.");return new _c(t,r=>W2(r,e),{includeRoot:!0})}function qR(t,e){var r;if(!e)return!0;let n=(r=t.$cstNode)===null||r===void 0?void 0:r.range;return n?CR(n,e):!1}function Ag(t){return new ao(()=>({keys:Object.keys(t),keyIndex:0,arrayIndex:0}),e=>{for(;e.keyIndex<e.keys.length;){let r=e.keys[e.keyIndex];if(!r.startsWith("$")){let n=t[r];if(va(n))return e.keyIndex++,{done:!1,value:{reference:n,container:t,property:r}};if(Array.isArray(n)){for(;e.arrayIndex<n.length;){let i=e.arrayIndex++,a=n[i];if(va(a))return{done:!1,value:{reference:a,container:t,property:r,index:i}}}e.arrayIndex=0}}e.keyIndex++}return Ia})}function tPe(t,e=Pa(t).parseResult.value){let r=[];return Wo(e).forEach(n=>{Ag(n).forEach(i=>{i.reference.ref===t&&r.push(i.reference)})}),en(r)}function XR(t,e){let r=t.getTypeMetaData(e.$type),n=e;for(let i of r.properties)i.defaultValue!==void 0&&n[i.name]===void 0&&(n[i.name]=pae(i.defaultValue))}function pae(t){return Array.isArray(t)?[...t.map(pae)]:t}function YR(t,e){let r={$type:t.$type};for(let[n,i]of Object.entries(t))if(!n.startsWith("$"))if(ii(i))r[n]=YR(i,e);else if(va(i))r[n]=e(r,n,i.$refNode,i.$refText);else if(Array.isArray(i)){let a=[];for(let s of i)ii(s)?a.push(YR(s,e)):va(s)?a.push(e(r,n,s.$refNode,s.$refText)):a.push(s);r[n]=a}else r[n]=i;return vk(r),r}var is=N(()=>{"use strict";Rl();Ps();Nl();o(vk,"linkContentToContainer");o(tp,"getContainerOfType");o(ePe,"hasContainerOfType");o(Pa,"getDocument");o(H2,"findRootNode");o(W2,"streamContents");o(Nc,"streamAllContents");o(Wo,"streamAst");o(qR,"isAstNodeInRange");o(Ag,"streamReferences");o(tPe,"findLocalReferences");o(XR,"assignMandatoryProperties");o(pae,"copyDefaultValue");o(YR,"copyAstNode")});function ar(t){return t.charCodeAt(0)}function bk(t,e){Array.isArray(t)?t.forEach(function(r){e.push(r)}):e.push(t)}function _g(t,e){if(t[e]===!0)throw"duplicate flag "+e;let r=t[e];t[e]=!0}function rp(t){if(t===void 0)throw Error("Internal Error - Should never get here!");return!0}function q2(){throw Error("Internal Error - Should never get here!")}function jR(t){return t.type==="Character"}var KR=N(()=>{"use strict";o(ar,"cc");o(bk,"insertToSet");o(_g,"addFlag");o(rp,"ASSERT_EXISTS");o(q2,"ASSERT_NEVER_REACH_HERE");o(jR,"isCharacter")});var Y2,X2,QR,mae=N(()=>{"use strict";KR();Y2=[];for(let t=ar("0");t<=ar("9");t++)Y2.push(t);X2=[ar("_")].concat(Y2);for(let t=ar("a");t<=ar("z");t++)X2.push(t);for(let t=ar("A");t<=ar("Z");t++)X2.push(t);QR=[ar(" "),ar("\f"),ar(`
+`),ar("\r"),ar(" "),ar("\v"),ar(" "),ar("\xA0"),ar("\u1680"),ar("\u2000"),ar("\u2001"),ar("\u2002"),ar("\u2003"),ar("\u2004"),ar("\u2005"),ar("\u2006"),ar("\u2007"),ar("\u2008"),ar("\u2009"),ar("\u200A"),ar("\u2028"),ar("\u2029"),ar("\u202F"),ar("\u205F"),ar("\u3000"),ar("\uFEFF")]});var rPe,wk,nPe,np,gae=N(()=>{"use strict";KR();mae();rPe=/[0-9a-fA-F]/,wk=/[0-9]/,nPe=/[1-9]/,np=class{static{o(this,"RegExpParser")}constructor(){this.idx=0,this.input="",this.groupIdx=0}saveState(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}}restoreState(e){this.idx=e.idx,this.input=e.input,this.groupIdx=e.groupIdx}pattern(e){this.idx=0,this.input=e,this.groupIdx=0,this.consumeChar("/");let r=this.disjunction();this.consumeChar("/");let n={type:"Flags",loc:{begin:this.idx,end:e.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};for(;this.isRegExpFlag();)switch(this.popChar()){case"g":_g(n,"global");break;case"i":_g(n,"ignoreCase");break;case"m":_g(n,"multiLine");break;case"u":_g(n,"unicode");break;case"y":_g(n,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:r,loc:this.loc(0)}}disjunction(){let e=[],r=this.idx;for(e.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),e.push(this.alternative());return{type:"Disjunction",value:e,loc:this.loc(r)}}alternative(){let e=[],r=this.idx;for(;this.isTerm();)e.push(this.term());return{type:"Alternative",value:e,loc:this.loc(r)}}term(){return this.isAssertion()?this.assertion():this.atom()}assertion(){let e=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(e)};case"$":return{type:"EndAnchor",loc:this.loc(e)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(e)};case"B":return{type:"NonWordBoundary",loc:this.loc(e)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");let r;switch(this.popChar()){case"=":r="Lookahead";break;case"!":r="NegativeLookahead";break}rp(r);let n=this.disjunction();return this.consumeChar(")"),{type:r,value:n,loc:this.loc(e)}}return q2()}quantifier(e=!1){let r,n=this.idx;switch(this.popChar()){case"*":r={atLeast:0,atMost:1/0};break;case"+":r={atLeast:1,atMost:1/0};break;case"?":r={atLeast:0,atMost:1};break;case"{":let i=this.integerIncludingZero();switch(this.popChar()){case"}":r={atLeast:i,atMost:i};break;case",":let a;this.isDigit()?(a=this.integerIncludingZero(),r={atLeast:i,atMost:a}):r={atLeast:i,atMost:1/0},this.consumeChar("}");break}if(e===!0&&r===void 0)return;rp(r);break}if(!(e===!0&&r===void 0)&&rp(r))return this.peekChar(0)==="?"?(this.consumeChar("?"),r.greedy=!1):r.greedy=!0,r.type="Quantifier",r.loc=this.loc(n),r}atom(){let e,r=this.idx;switch(this.peekChar()){case".":e=this.dotAll();break;case"\\":e=this.atomEscape();break;case"[":e=this.characterClass();break;case"(":e=this.group();break}return e===void 0&&this.isPatternCharacter()&&(e=this.patternCharacter()),rp(e)?(e.loc=this.loc(r),this.isQuantifier()&&(e.quantifier=this.quantifier()),e):q2()}dotAll(){return this.consumeChar("."),{type:"Set",complement:!0,value:[ar(`
+`),ar("\r"),ar("\u2028"),ar("\u2029")]}}atomEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}decimalEscapeAtom(){return{type:"GroupBackReference",value:this.positiveInteger()}}characterClassEscape(){let e,r=!1;switch(this.popChar()){case"d":e=Y2;break;case"D":e=Y2,r=!0;break;case"s":e=QR;break;case"S":e=QR,r=!0;break;case"w":e=X2;break;case"W":e=X2,r=!0;break}return rp(e)?{type:"Set",value:e,complement:r}:q2()}controlEscapeAtom(){let e;switch(this.popChar()){case"f":e=ar("\f");break;case"n":e=ar(`
+`);break;case"r":e=ar("\r");break;case"t":e=ar(" ");break;case"v":e=ar("\v");break}return rp(e)?{type:"Character",value:e}:q2()}controlLetterEscapeAtom(){this.consumeChar("c");let e=this.popChar();if(/[a-zA-Z]/.test(e)===!1)throw Error("Invalid ");return{type:"Character",value:e.toUpperCase().charCodeAt(0)-64}}nulCharacterAtom(){return this.consumeChar("0"),{type:"Character",value:ar("\0")}}hexEscapeSequenceAtom(){return this.consumeChar("x"),this.parseHexDigits(2)}regExpUnicodeEscapeSequenceAtom(){return this.consumeChar("u"),this.parseHexDigits(4)}identityEscapeAtom(){let e=this.popChar();return{type:"Character",value:ar(e)}}classPatternCharacterAtom(){switch(this.peekChar()){case`
+`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:let e=this.popChar();return{type:"Character",value:ar(e)}}}characterClass(){let e=[],r=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),r=!0);this.isClassAtom();){let n=this.classAtom(),i=n.type==="Character";if(jR(n)&&this.isRangeDash()){this.consumeChar("-");let a=this.classAtom(),s=a.type==="Character";if(jR(a)){if(a.value<n.value)throw Error("Range out of order in character class");e.push({from:n.value,to:a.value})}else bk(n.value,e),e.push(ar("-")),bk(a.value,e)}else bk(n.value,e)}return this.consumeChar("]"),{type:"Set",complement:r,value:e}}classAtom(){switch(this.peekChar()){case"]":case`
+`:case"\r":case"\u2028":case"\u2029":throw Error("TBD");case"\\":return this.classEscape();default:return this.classPatternCharacterAtom()}}classEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"b":return this.consumeChar("b"),{type:"Character",value:ar("\b")};case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}group(){let e=!0;switch(this.consumeChar("("),this.peekChar(0)){case"?":this.consumeChar("?"),this.consumeChar(":"),e=!1;break;default:this.groupIdx++;break}let r=this.disjunction();this.consumeChar(")");let n={type:"Group",capturing:e,value:r};return e&&(n.idx=this.groupIdx),n}positiveInteger(){let e=this.popChar();if(nPe.test(e)===!1)throw Error("Expecting a positive integer");for(;wk.test(this.peekChar(0));)e+=this.popChar();return parseInt(e,10)}integerIncludingZero(){let e=this.popChar();if(wk.test(e)===!1)throw Error("Expecting an integer");for(;wk.test(this.peekChar(0));)e+=this.popChar();return parseInt(e,10)}patternCharacter(){let e=this.popChar();switch(e){case`
+`:case"\r":case"\u2028":case"\u2029":case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":throw Error("TBD");default:return{type:"Character",value:ar(e)}}}isRegExpFlag(){switch(this.peekChar(0)){case"g":case"i":case"m":case"u":case"y":return!0;default:return!1}}isRangeDash(){return this.peekChar()==="-"&&this.isClassAtom(1)}isDigit(){return wk.test(this.peekChar(0))}isClassAtom(e=0){switch(this.peekChar(e)){case"]":case`
+`:case"\r":case"\u2028":case"\u2029":return!1;default:return!0}}isTerm(){return this.isAtom()||this.isAssertion()}isAtom(){if(this.isPatternCharacter())return!0;switch(this.peekChar(0)){case".":case"\\":case"[":case"(":return!0;default:return!1}}isAssertion(){switch(this.peekChar(0)){case"^":case"$":return!0;case"\\":switch(this.peekChar(1)){case"b":case"B":return!0;default:return!1}case"(":return this.peekChar(1)==="?"&&(this.peekChar(2)==="="||this.peekChar(2)==="!");default:return!1}}isQuantifier(){let e=this.saveState();try{return this.quantifier(!0)!==void 0}catch{return!1}finally{this.restoreState(e)}}isPatternCharacter(){switch(this.peekChar()){case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":case"/":case`
+`:case"\r":case"\u2028":case"\u2029":return!1;default:return!0}}parseHexDigits(e){let r="";for(let i=0;i<e;i++){let a=this.popChar();if(rPe.test(a)===!1)throw Error("Expecting a HexDecimal digits");r+=a}return{type:"Character",value:parseInt(r,16)}}peekChar(e=0){return this.input[this.idx+e]}popChar(){let e=this.peekChar(0);return this.consumeChar(void 0),e}consumeChar(e){if(e!==void 0&&this.input[this.idx]!==e)throw Error("Expected: '"+e+"' but found: '"+this.input[this.idx]+"' at offset: "+this.idx);if(this.idx>=this.input.length)throw Error("Unexpected end of input");this.idx++}loc(e){return{begin:e,end:this.idx}}}});var Mc,yae=N(()=>{"use strict";Mc=class{static{o(this,"BaseRegExpVisitor")}visitChildren(e){for(let r in e){let n=e[r];e.hasOwnProperty(r)&&(n.type!==void 0?this.visit(n):Array.isArray(n)&&n.forEach(i=>{this.visit(i)},this))}}visit(e){switch(e.type){case"Pattern":this.visitPattern(e);break;case"Flags":this.visitFlags(e);break;case"Disjunction":this.visitDisjunction(e);break;case"Alternative":this.visitAlternative(e);break;case"StartAnchor":this.visitStartAnchor(e);break;case"EndAnchor":this.visitEndAnchor(e);break;case"WordBoundary":this.visitWordBoundary(e);break;case"NonWordBoundary":this.visitNonWordBoundary(e);break;case"Lookahead":this.visitLookahead(e);break;case"NegativeLookahead":this.visitNegativeLookahead(e);break;case"Character":this.visitCharacter(e);break;case"Set":this.visitSet(e);break;case"Group":this.visitGroup(e);break;case"GroupBackReference":this.visitGroupBackReference(e);break;case"Quantifier":this.visitQuantifier(e);break}this.visitChildren(e)}visitPattern(e){}visitFlags(e){}visitDisjunction(e){}visitAlternative(e){}visitStartAnchor(e){}visitEndAnchor(e){}visitWordBoundary(e){}visitNonWordBoundary(e){}visitLookahead(e){}visitNegativeLookahead(e){}visitCharacter(e){}visitSet(e){}visitGroup(e){}visitGroupBackReference(e){}visitQuantifier(e){}}});var j2=N(()=>{"use strict";gae();yae()});var Tk={};hr(Tk,{NEWLINE_REGEXP:()=>JR,escapeRegExp:()=>ap,getCaseInsensitivePattern:()=>tN,getTerminalParts:()=>iPe,isMultilineComment:()=>eN,isWhitespace:()=>Dg,partialMatches:()=>rN,partialRegExp:()=>bae,whitespaceCharacters:()=>xae});function iPe(t){try{typeof t!="string"&&(t=t.source),t=`/${t}/`;let e=vae.pattern(t),r=[];for(let n of e.value.value)ip.reset(t),ip.visit(n),r.push({start:ip.startRegexp,end:ip.endRegex});return r}catch{return[]}}function eN(t){try{return typeof t=="string"&&(t=new RegExp(t)),t=t.toString(),ip.reset(t),ip.visit(vae.pattern(t)),ip.multiline}catch{return!1}}function Dg(t){let e=typeof t=="string"?new RegExp(t):t;return xae.some(r=>e.test(r))}function ap(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function tN(t){return Array.prototype.map.call(t,e=>/\w/.test(e)?`[${e.toLowerCase()}${e.toUpperCase()}]`:ap(e)).join("")}function rN(t,e){let r=bae(t),n=e.match(r);return!!n&&n[0].length>0}function bae(t){typeof t=="string"&&(t=new RegExp(t));let e=t,r=t.source,n=0;function i(){let a="",s;function l(h){a+=r.substr(n,h),n+=h}o(l,"appendRaw");function u(h){a+="(?:"+r.substr(n,h)+"|$)",n+=h}for(o(u,"appendOptional");n<r.length;)switch(r[n]){case"\\":switch(r[n+1]){case"c":u(3);break;case"x":u(4);break;case"u":e.unicode?r[n+2]==="{"?u(r.indexOf("}",n)-n+1):u(6):u(2);break;case"p":case"P":e.unicode?u(r.indexOf("}",n)-n+1):u(2);break;case"k":u(r.indexOf(">",n)-n+1);break;default:u(2);break}break;case"[":s=/\[(?:\\.|.)*?\]/g,s.lastIndex=n,s=s.exec(r)||[],u(s[0].length);break;case"|":case"^":case"$":case"*":case"+":case"?":l(1);break;case"{":s=/\{\d+,?\d*\}/g,s.lastIndex=n,s=s.exec(r),s?l(s[0].length):u(1);break;case"(":if(r[n+1]==="?")switch(r[n+2]){case":":a+="(?:",n+=3,a+=i()+"|$)";break;case"=":a+="(?=",n+=3,a+=i()+")";break;case"!":s=n,n+=3,i(),a+=r.substr(s,n-s);break;case"<":switch(r[n+3]){case"=":case"!":s=n,n+=4,i(),a+=r.substr(s,n-s);break;default:l(r.indexOf(">",n)-n+1),a+=i()+"|$)";break}break}else l(1),a+=i()+"|$)";break;case")":return++n,a;default:u(1);break}return a}return o(i,"process"),new RegExp(i(),t.flags)}var JR,vae,ZR,ip,xae,Lg=N(()=>{"use strict";j2();JR=/\r?\n/gm,vae=new np,ZR=class extends Mc{static{o(this,"TerminalRegExpVisitor")}constructor(){super(...arguments),this.isStarting=!0,this.endRegexpStack=[],this.multiline=!1}get endRegex(){return this.endRegexpStack.join("")}reset(e){this.multiline=!1,this.regex=e,this.startRegexp="",this.isStarting=!0,this.endRegexpStack=[]}visitGroup(e){e.quantifier&&(this.isStarting=!1,this.endRegexpStack=[])}visitCharacter(e){let r=String.fromCharCode(e.value);if(!this.multiline&&r===`
+`&&(this.multiline=!0),e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{let n=ap(r);this.endRegexpStack.push(n),this.isStarting&&(this.startRegexp+=n)}}visitSet(e){if(!this.multiline){let r=this.regex.substring(e.loc.begin,e.loc.end),n=new RegExp(r);this.multiline=!!`
+`.match(n)}if(e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{let r=this.regex.substring(e.loc.begin,e.loc.end);this.endRegexpStack.push(r),this.isStarting&&(this.startRegexp+=r)}}visitChildren(e){e.type==="Group"&&e.quantifier||super.visitChildren(e)}},ip=new ZR;o(iPe,"getTerminalParts");o(eN,"isMultilineComment");xae=`\f
+\r \v \xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF`.split("");o(Dg,"isWhitespace");o(ap,"escapeRegExp");o(tN,"getCaseInsensitivePattern");o(rN,"partialMatches");o(bae,"partialRegExp")});var Ek={};hr(Ek,{findAssignment:()=>hN,findNameAssignment:()=>kk,findNodeForKeyword:()=>cN,findNodeForProperty:()=>Q2,findNodesForKeyword:()=>aPe,findNodesForKeywordInternal:()=>uN,findNodesForProperty:()=>oN,getActionAtElement:()=>Sae,getActionType:()=>Aae,getAllReachableRules:()=>K2,getCrossReferenceTerminal:()=>aN,getEntryRule:()=>wae,getExplicitRuleType:()=>Rg,getHiddenRules:()=>Tae,getRuleType:()=>fN,getRuleTypeName:()=>uPe,getTypeName:()=>J2,isArrayCardinality:()=>oPe,isArrayOperator:()=>lPe,isCommentTerminal:()=>sN,isDataType:()=>cPe,isDataTypeRule:()=>Z2,isOptionalCardinality:()=>sPe,terminalRegex:()=>Ng});function wae(t){return t.rules.find(e=>Oa(e)&&e.entry)}function Tae(t){return t.rules.filter(e=>so(e)&&e.hidden)}function K2(t,e){let r=new Set,n=wae(t);if(!n)return new Set(t.rules);let i=[n].concat(Tae(t));for(let s of i)kae(s,r,e);let a=new Set;for(let s of t.rules)(r.has(s.name)||so(s)&&s.hidden)&&a.add(s);return a}function kae(t,e,r){e.add(t.name),Nc(t).forEach(n=>{if(Il(n)||r&&gk(n)){let i=n.rule.ref;i&&!e.has(i.name)&&kae(i,e,r)}})}function aN(t){if(t.terminal)return t.terminal;if(t.type.ref){let e=kk(t.type.ref);return e?.terminal}}function sN(t){return t.hidden&&!Dg(Ng(t))}function oN(t,e){return!t||!e?[]:lN(t,e,t.astNode,!0)}function Q2(t,e,r){if(!t||!e)return;let n=lN(t,e,t.astNode,!0);if(n.length!==0)return r!==void 0?r=Math.max(0,Math.min(r,n.length-1)):r=0,n[r]}function lN(t,e,r,n){if(!n){let i=tp(t.grammarSource,Ml);if(i&&i.feature===e)return[t]}return Ll(t)&&t.astNode===r?t.content.flatMap(i=>lN(i,e,r,!1)):[]}function aPe(t,e){return t?uN(t,e,t?.astNode):[]}function cN(t,e,r){if(!t)return;let n=uN(t,e,t?.astNode);if(n.length!==0)return r!==void 0?r=Math.max(0,Math.min(r,n.length-1)):r=0,n[r]}function uN(t,e,r){if(t.astNode!==r)return[];if(Ho(t.grammarSource)&&t.grammarSource.value===e)return[t];let n=Kd(t).iterator(),i,a=[];do if(i=n.next(),!i.done){let s=i.value;s.astNode===r?Ho(s.grammarSource)&&s.grammarSource.value===e&&a.push(s):n.prune()}while(!i.done);return a}function hN(t){var e;let r=t.astNode;for(;r===((e=t.container)===null||e===void 0?void 0:e.astNode);){let n=tp(t.grammarSource,Ml);if(n)return n;t=t.container}}function kk(t){let e=t;return fk(e)&&(Mu(e.$container)?e=e.$container.$container:Oa(e.$container)?e=e.$container:Lc(e.$container)),Eae(t,e,new Map)}function Eae(t,e,r){var n;function i(a,s){let l;return tp(a,Ml)||(l=Eae(s,s,r)),r.set(t,l),l}if(o(i,"go"),r.has(t))return r.get(t);r.set(t,void 0);for(let a of Nc(e)){if(Ml(a)&&a.feature.toLowerCase()==="name")return r.set(t,a),a;if(Il(a)&&Oa(a.rule.ref))return i(a,a.rule.ref);if(pk(a)&&(!((n=a.typeRef)===null||n===void 0)&&n.ref))return i(a,a.typeRef.ref)}}function Sae(t){let e=t.$container;if(sf(e)){let r=e.elements,n=r.indexOf(t);for(let i=n-1;i>=0;i--){let a=r[i];if(Mu(a))return a;{let s=Nc(r[i]).find(Mu);if(s)return s}}}if(G2(e))return Sae(e)}function sPe(t,e){return t==="?"||t==="*"||sf(e)&&!!e.guardCondition}function oPe(t){return t==="*"||t==="+"}function lPe(t){return t==="+="}function Z2(t){return Cae(t,new Set)}function Cae(t,e){if(e.has(t))return!0;e.add(t);for(let r of Nc(t))if(Il(r)){if(!r.rule.ref||Oa(r.rule.ref)&&!Cae(r.rule.ref,e))return!1}else{if(Ml(r))return!1;if(Mu(r))return!1}return!!t.definition}function cPe(t){return iN(t.type,new Set)}function iN(t,e){if(e.has(t))return!0;if(e.add(t),DR(t))return!1;if(OR(t))return!1;if(BR(t))return t.types.every(r=>iN(r,e));if(pk(t)){if(t.primitiveType!==void 0)return!0;if(t.stringType!==void 0)return!0;if(t.typeRef!==void 0){let r=t.typeRef.ref;return V2(r)?iN(r.type,e):!1}else return!1}else return!1}function Rg(t){if(t.inferredType)return t.inferredType.name;if(t.dataType)return t.dataType;if(t.returnType){let e=t.returnType.ref;if(e){if(Oa(e))return e.name;if(dk(e)||V2(e))return e.name}}}function J2(t){var e;if(Oa(t))return Z2(t)?t.name:(e=Rg(t))!==null&&e!==void 0?e:t.name;if(dk(t)||V2(t)||PR(t))return t.name;if(Mu(t)){let r=Aae(t);if(r)return r}else if(fk(t))return t.name;throw new Error("Cannot get name of Unknown Type")}function Aae(t){var e;if(t.inferredType)return t.inferredType.name;if(!((e=t.type)===null||e===void 0)&&e.ref)return J2(t.type.ref)}function uPe(t){var e,r,n;return so(t)?(r=(e=t.type)===null||e===void 0?void 0:e.name)!==null&&r!==void 0?r:"string":Z2(t)?t.name:(n=Rg(t))!==null&&n!==void 0?n:t.name}function fN(t){var e,r,n;return so(t)?(r=(e=t.type)===null||e===void 0?void 0:e.name)!==null&&r!==void 0?r:"string":(n=Rg(t))!==null&&n!==void 0?n:t.name}function Ng(t){let e={s:!1,i:!1,u:!1},r=Mg(t.definition,e),n=Object.entries(e).filter(([,i])=>i).map(([i])=>i).join("");return new RegExp(r,n)}function Mg(t,e){if(VR(t))return hPe(t);if(UR(t))return fPe(t);if(FR(t))return mPe(t);if(gk(t)){let r=t.rule.ref;if(!r)throw new Error("Missing rule reference.");return Iu(Mg(r.definition),{cardinality:t.cardinality,lookahead:t.lookahead})}else{if(zR(t))return pPe(t);if(HR(t))return dPe(t);if(GR(t)){let r=t.regex.lastIndexOf("/"),n=t.regex.substring(1,r),i=t.regex.substring(r+1);return e&&(e.i=i.includes("i"),e.s=i.includes("s"),e.u=i.includes("u")),Iu(n,{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1})}else{if(WR(t))return Iu(dN,{cardinality:t.cardinality,lookahead:t.lookahead});throw new Error(`Invalid terminal element: ${t?.$type}`)}}}function hPe(t){return Iu(t.elements.map(e=>Mg(e)).join("|"),{cardinality:t.cardinality,lookahead:t.lookahead})}function fPe(t){return Iu(t.elements.map(e=>Mg(e)).join(""),{cardinality:t.cardinality,lookahead:t.lookahead})}function dPe(t){return Iu(`${dN}*?${Mg(t.terminal)}`,{cardinality:t.cardinality,lookahead:t.lookahead})}function pPe(t){return Iu(`(?!${Mg(t.terminal)})${dN}*?`,{cardinality:t.cardinality,lookahead:t.lookahead})}function mPe(t){return t.right?Iu(`[${nN(t.left)}-${nN(t.right)}]`,{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1}):Iu(nN(t.left),{cardinality:t.cardinality,lookahead:t.lookahead,wrap:!1})}function nN(t){return ap(t.value)}function Iu(t,e){var r;return(e.wrap!==!1||e.lookahead)&&(t=`(${(r=e.lookahead)!==null&&r!==void 0?r:""}${t})`),e.cardinality?`${t}${e.cardinality}`:t}var dN,Ol=N(()=>{"use strict";uk();Rc();Rl();is();Nl();Lg();o(wae,"getEntryRule");o(Tae,"getHiddenRules");o(K2,"getAllReachableRules");o(kae,"ruleDfs");o(aN,"getCrossReferenceTerminal");o(sN,"isCommentTerminal");o(oN,"findNodesForProperty");o(Q2,"findNodeForProperty");o(lN,"findNodesForPropertyInternal");o(aPe,"findNodesForKeyword");o(cN,"findNodeForKeyword");o(uN,"findNodesForKeywordInternal");o(hN,"findAssignment");o(kk,"findNameAssignment");o(Eae,"findNameAssignmentInternal");o(Sae,"getActionAtElement");o(sPe,"isOptionalCardinality");o(oPe,"isArrayCardinality");o(lPe,"isArrayOperator");o(Z2,"isDataTypeRule");o(Cae,"isDataTypeRuleInternal");o(cPe,"isDataType");o(iN,"isDataTypeInternal");o(Rg,"getExplicitRuleType");o(J2,"getTypeName");o(Aae,"getActionType");o(uPe,"getRuleTypeName");o(fN,"getRuleType");o(Ng,"terminalRegex");dN=/[\s\S]/.source;o(Mg,"abstractElementToRegex");o(hPe,"terminalAlternativesToRegex");o(fPe,"terminalGroupToRegex");o(dPe,"untilTokenToRegex");o(pPe,"negateTokenToRegex");o(mPe,"characterRangeToRegex");o(nN,"keywordToRegex");o(Iu,"withCardinality")});function pN(t){let e=[],r=t.Grammar;for(let n of r.rules)so(n)&&sN(n)&&eN(Ng(n))&&e.push(n.name);return{multilineCommentRules:e,nameRegexp:lk}}var mN=N(()=>{"use strict";Nl();Ol();Lg();Rc();o(pN,"createGrammarConfig")});var gN=N(()=>{"use strict"});function Ig(t){console&&console.error&&console.error(`Error: ${t}`)}function ex(t){console&&console.warn&&console.warn(`Warning: ${t}`)}var _ae=N(()=>{"use strict";o(Ig,"PRINT_ERROR");o(ex,"PRINT_WARNING")});function tx(t){let e=new Date().getTime(),r=t();return{time:new Date().getTime()-e,value:r}}var Dae=N(()=>{"use strict";o(tx,"timer")});function rx(t){function e(){}o(e,"FakeConstructor"),e.prototype=t;let r=new e;function n(){return typeof r.bar}return o(n,"fakeAccess"),n(),n(),t;(0,eval)(t)}var Lae=N(()=>{"use strict";o(rx,"toFastProperties")});var Og=N(()=>{"use strict";_ae();Dae();Lae()});function gPe(t){return yPe(t)?t.LABEL:t.name}function yPe(t){return yi(t.LABEL)&&t.LABEL!==""}function Sk(t){return Je(t,Pg)}function Pg(t){function e(r){return Je(r,Pg)}if(o(e,"convertDefinition"),t instanceof on){let r={type:"NonTerminal",name:t.nonTerminalName,idx:t.idx};return yi(t.label)&&(r.label=t.label),r}else{if(t instanceof Dn)return{type:"Alternative",definition:e(t.definition)};if(t instanceof ln)return{type:"Option",idx:t.idx,definition:e(t.definition)};if(t instanceof Ln)return{type:"RepetitionMandatory",idx:t.idx,definition:e(t.definition)};if(t instanceof Rn)return{type:"RepetitionMandatoryWithSeparator",idx:t.idx,separator:Pg(new kr({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof wn)return{type:"RepetitionWithSeparator",idx:t.idx,separator:Pg(new kr({terminalType:t.separator})),definition:e(t.definition)};if(t instanceof Or)return{type:"Repetition",idx:t.idx,definition:e(t.definition)};if(t instanceof Tn)return{type:"Alternation",idx:t.idx,definition:e(t.definition)};if(t instanceof kr){let r={type:"Terminal",name:t.terminalType.name,label:gPe(t.terminalType),idx:t.idx};yi(t.label)&&(r.terminalLabel=t.label);let n=t.terminalType.PATTERN;return t.terminalType.PATTERN&&(r.pattern=zo(n)?n.source:n),r}else{if(t instanceof as)return{type:"Rule",name:t.name,orgText:t.orgText,definition:e(t.definition)};throw Error("non exhaustive match")}}}var oo,on,as,Dn,ln,Ln,Rn,Or,wn,Tn,kr,Ck=N(()=>{"use strict";qt();o(gPe,"tokenLabel");o(yPe,"hasTokenLabel");oo=class{static{o(this,"AbstractProduction")}get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){this._definition=e}accept(e){e.visit(this),Ae(this.definition,r=>{r.accept(e)})}},on=class extends oo{static{o(this,"NonTerminal")}constructor(e){super([]),this.idx=1,ma(this,Os(e,r=>r!==void 0))}set definition(e){}get definition(){return this.referencedRule!==void 0?this.referencedRule.definition:[]}accept(e){e.visit(this)}},as=class extends oo{static{o(this,"Rule")}constructor(e){super(e.definition),this.orgText="",ma(this,Os(e,r=>r!==void 0))}},Dn=class extends oo{static{o(this,"Alternative")}constructor(e){super(e.definition),this.ignoreAmbiguities=!1,ma(this,Os(e,r=>r!==void 0))}},ln=class extends oo{static{o(this,"Option")}constructor(e){super(e.definition),this.idx=1,ma(this,Os(e,r=>r!==void 0))}},Ln=class extends oo{static{o(this,"RepetitionMandatory")}constructor(e){super(e.definition),this.idx=1,ma(this,Os(e,r=>r!==void 0))}},Rn=class extends oo{static{o(this,"RepetitionMandatoryWithSeparator")}constructor(e){super(e.definition),this.idx=1,ma(this,Os(e,r=>r!==void 0))}},Or=class extends oo{static{o(this,"Repetition")}constructor(e){super(e.definition),this.idx=1,ma(this,Os(e,r=>r!==void 0))}},wn=class extends oo{static{o(this,"RepetitionWithSeparator")}constructor(e){super(e.definition),this.idx=1,ma(this,Os(e,r=>r!==void 0))}},Tn=class extends oo{static{o(this,"Alternation")}get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){super(e.definition),this.idx=1,this.ignoreAmbiguities=!1,this.hasPredicates=!1,ma(this,Os(e,r=>r!==void 0))}},kr=class{static{o(this,"Terminal")}constructor(e){this.idx=1,ma(this,Os(e,r=>r!==void 0))}accept(e){e.visit(this)}};o(Sk,"serializeGrammar");o(Pg,"serializeProduction")});var ss,Rae=N(()=>{"use strict";Ck();ss=class{static{o(this,"GAstVisitor")}visit(e){let r=e;switch(r.constructor){case on:return this.visitNonTerminal(r);case Dn:return this.visitAlternative(r);case ln:return this.visitOption(r);case Ln:return this.visitRepetitionMandatory(r);case Rn:return this.visitRepetitionMandatoryWithSeparator(r);case wn:return this.visitRepetitionWithSeparator(r);case Or:return this.visitRepetition(r);case Tn:return this.visitAlternation(r);case kr:return this.visitTerminal(r);case as:return this.visitRule(r);default:throw Error("non exhaustive match")}}visitNonTerminal(e){}visitAlternative(e){}visitOption(e){}visitRepetition(e){}visitRepetitionMandatory(e){}visitRepetitionMandatoryWithSeparator(e){}visitRepetitionWithSeparator(e){}visitAlternation(e){}visitTerminal(e){}visitRule(e){}}});function yN(t){return t instanceof Dn||t instanceof ln||t instanceof Or||t instanceof Ln||t instanceof Rn||t instanceof wn||t instanceof kr||t instanceof as}function sp(t,e=[]){return t instanceof ln||t instanceof Or||t instanceof wn?!0:t instanceof Tn?A2(t.definition,n=>sp(n,e)):t instanceof on&&qn(e,t)?!1:t instanceof oo?(t instanceof on&&e.push(t),Ma(t.definition,n=>sp(n,e))):!1}function vN(t){return t instanceof Tn}function Bs(t){if(t instanceof on)return"SUBRULE";if(t instanceof ln)return"OPTION";if(t instanceof Tn)return"OR";if(t instanceof Ln)return"AT_LEAST_ONE";if(t instanceof Rn)return"AT_LEAST_ONE_SEP";if(t instanceof wn)return"MANY_SEP";if(t instanceof Or)return"MANY";if(t instanceof kr)return"CONSUME";throw Error("non exhaustive match")}var Nae=N(()=>{"use strict";qt();Ck();o(yN,"isSequenceProd");o(sp,"isOptionalProd");o(vN,"isBranchingProd");o(Bs,"getProductionDslName")});var os=N(()=>{"use strict";Ck();Rae();Nae()});function Mae(t,e,r){return[new ln({definition:[new kr({terminalType:t.separator})].concat(t.definition)})].concat(e,r)}var Ou,Ak=N(()=>{"use strict";qt();os();Ou=class{static{o(this,"RestWalker")}walk(e,r=[]){Ae(e.definition,(n,i)=>{let a=gi(e.definition,i+1);if(n instanceof on)this.walkProdRef(n,a,r);else if(n instanceof kr)this.walkTerminal(n,a,r);else if(n instanceof Dn)this.walkFlat(n,a,r);else if(n instanceof ln)this.walkOption(n,a,r);else if(n instanceof Ln)this.walkAtLeastOne(n,a,r);else if(n instanceof Rn)this.walkAtLeastOneSep(n,a,r);else if(n instanceof wn)this.walkManySep(n,a,r);else if(n instanceof Or)this.walkMany(n,a,r);else if(n instanceof Tn)this.walkOr(n,a,r);else throw Error("non exhaustive match")})}walkTerminal(e,r,n){}walkProdRef(e,r,n){}walkFlat(e,r,n){let i=r.concat(n);this.walk(e,i)}walkOption(e,r,n){let i=r.concat(n);this.walk(e,i)}walkAtLeastOne(e,r,n){let i=[new ln({definition:e.definition})].concat(r,n);this.walk(e,i)}walkAtLeastOneSep(e,r,n){let i=Mae(e,r,n);this.walk(e,i)}walkMany(e,r,n){let i=[new ln({definition:e.definition})].concat(r,n);this.walk(e,i)}walkManySep(e,r,n){let i=Mae(e,r,n);this.walk(e,i)}walkOr(e,r,n){let i=r.concat(n);Ae(e.definition,a=>{let s=new Dn({definition:[a]});this.walk(s,i)})}};o(Mae,"restForRepetitionWithSeparator")});function op(t){if(t instanceof on)return op(t.referencedRule);if(t instanceof kr)return bPe(t);if(yN(t))return vPe(t);if(vN(t))return xPe(t);throw Error("non exhaustive match")}function vPe(t){let e=[],r=t.definition,n=0,i=r.length>n,a,s=!0;for(;i&&s;)a=r[n],s=sp(a),e=e.concat(op(a)),n=n+1,i=r.length>n;return Bm(e)}function xPe(t){let e=Je(t.definition,r=>op(r));return Bm(qr(e))}function bPe(t){return[t.terminalType]}var xN=N(()=>{"use strict";qt();os();o(op,"first");o(vPe,"firstForSequence");o(xPe,"firstForBranching");o(bPe,"firstForTerminal")});var _k,bN=N(()=>{"use strict";_k="_~IN~_"});function Iae(t){let e={};return Ae(t,r=>{let n=new wN(r).startWalking();ma(e,n)}),e}function wPe(t,e){return t.name+e+_k}var wN,Oae=N(()=>{"use strict";Ak();xN();qt();bN();os();wN=class extends Ou{static{o(this,"ResyncFollowsWalker")}constructor(e){super(),this.topProd=e,this.follows={}}startWalking(){return this.walk(this.topProd),this.follows}walkTerminal(e,r,n){}walkProdRef(e,r,n){let i=wPe(e.referencedRule,e.idx)+this.topProd.name,a=r.concat(n),s=new Dn({definition:a}),l=op(s);this.follows[i]=l}};o(Iae,"computeAllProdsFollows");o(wPe,"buildBetweenProdsFollowPrefix")});function Bg(t){let e=t.toString();if(Dk.hasOwnProperty(e))return Dk[e];{let r=TPe.pattern(e);return Dk[e]=r,r}}function Pae(){Dk={}}var Dk,TPe,Lk=N(()=>{"use strict";j2();Dk={},TPe=new np;o(Bg,"getRegExpAst");o(Pae,"clearRegExpParserCache")});function $ae(t,e=!1){try{let r=Bg(t);return TN(r.value,{},r.flags.ignoreCase)}catch(r){if(r.message===Fae)e&&ex(`${nx} Unable to optimize: < ${t.toString()} >
+ Complement Sets cannot be automatically optimized.
+ This will disable the lexer's first char optimizations.
+ See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{let n="";e&&(n=`
+ This will disable the lexer's first char optimizations.
+ See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),Ig(`${nx}
+ Failed parsing: < ${t.toString()} >
+ Using the @chevrotain/regexp-to-ast library
+ Please open an issue at: https://github.com/chevrotain/chevrotain/issues`+n)}}return[]}function TN(t,e,r){switch(t.type){case"Disjunction":for(let i=0;i<t.value.length;i++)TN(t.value[i],e,r);break;case"Alternative":let n=t.value;for(let i=0;i<n.length;i++){let a=n[i];switch(a.type){case"EndAnchor":case"GroupBackReference":case"Lookahead":case"NegativeLookahead":case"StartAnchor":case"WordBoundary":case"NonWordBoundary":continue}let s=a;switch(s.type){case"Character":Rk(s.value,e,r);break;case"Set":if(s.complement===!0)throw Error(Fae);Ae(s.value,u=>{if(typeof u=="number")Rk(u,e,r);else{let h=u;if(r===!0)for(let f=h.from;f<=h.to;f++)Rk(f,e,r);else{for(let f=h.from;f<=h.to&&f<Fg;f++)Rk(f,e,r);if(h.to>=Fg){let f=h.from>=Fg?h.from:Fg,d=h.to,p=Ic(f),m=Ic(d);for(let g=p;g<=m;g++)e[g]=g}}}});break;case"Group":TN(s.value,e,r);break;default:throw Error("Non Exhaustive Match")}let l=s.quantifier!==void 0&&s.quantifier.atLeast===0;if(s.type==="Group"&&kN(s)===!1||s.type!=="Group"&&l===!1)break}break;default:throw Error("non exhaustive match!")}return br(e)}function Rk(t,e,r){let n=Ic(t);e[n]=n,r===!0&&kPe(t,e)}function kPe(t,e){let r=String.fromCharCode(t),n=r.toUpperCase();if(n!==r){let i=Ic(n.charCodeAt(0));e[i]=i}else{let i=r.toLowerCase();if(i!==r){let a=Ic(i.charCodeAt(0));e[a]=a}}}function Bae(t,e){return ns(t.value,r=>{if(typeof r=="number")return qn(e,r);{let n=r;return ns(e,i=>n.from<=i&&i<=n.to)!==void 0}})}function kN(t){let e=t.quantifier;return e&&e.atLeast===0?!0:t.value?Pt(t.value)?Ma(t.value,kN):kN(t.value):!1}function Nk(t,e){if(e instanceof RegExp){let r=Bg(e),n=new EN(t);return n.visit(r),n.found}else return ns(e,r=>qn(t,r.charCodeAt(0)))!==void 0}var Fae,nx,EN,zae=N(()=>{"use strict";j2();qt();Og();Lk();SN();Fae="Complement Sets are not supported for first char optimization",nx=`Unable to use "first char" lexer optimizations:
+`;o($ae,"getOptimizedStartCodesIndices");o(TN,"firstCharOptimizedIndices");o(Rk,"addOptimizedIdxToResult");o(kPe,"handleIgnoreCase");o(Bae,"findCode");o(kN,"isWholeOptional");EN=class extends Mc{static{o(this,"CharCodeFinder")}constructor(e){super(),this.targetCharCodes=e,this.found=!1}visitChildren(e){if(this.found!==!0){switch(e.type){case"Lookahead":this.visitLookahead(e);return;case"NegativeLookahead":this.visitNegativeLookahead(e);return}super.visitChildren(e)}}visitCharacter(e){qn(this.targetCharCodes,e.value)&&(this.found=!0)}visitSet(e){e.complement?Bae(e,this.targetCharCodes)===void 0&&(this.found=!0):Bae(e,this.targetCharCodes)!==void 0&&(this.found=!0)}};o(Nk,"canMatchCharCode")});function Uae(t,e){e=Qh(e,{useSticky:AN,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",`
+`],tracer:o((b,w)=>w(),"tracer")});let r=e.tracer;r("initCharCodeToOptimizedIndexMap",()=>{GPe()});let n;r("Reject Lexer.NA",()=>{n=Jh(t,b=>b[lp]===Xn.NA)});let i=!1,a;r("Transform Patterns",()=>{i=!1,a=Je(n,b=>{let w=b[lp];if(zo(w)){let C=w.source;return C.length===1&&C!=="^"&&C!=="$"&&C!=="."&&!w.ignoreCase?C:C.length===2&&C[0]==="\\"&&!qn(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],C[1])?C[1]:e.useSticky?Vae(w):Gae(w)}else{if(Si(w))return i=!0,{exec:w};if(typeof w=="object")return i=!0,w;if(typeof w=="string"){if(w.length===1)return w;{let C=w.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),T=new RegExp(C);return e.useSticky?Vae(T):Gae(T)}}else throw Error("non exhaustive match")}})});let s,l,u,h,f;r("misc mapping",()=>{s=Je(n,b=>b.tokenTypeIdx),l=Je(n,b=>{let w=b.GROUP;if(w!==Xn.SKIPPED){if(yi(w))return w;if(pr(w))return!1;throw Error("non exhaustive match")}}),u=Je(n,b=>{let w=b.LONGER_ALT;if(w)return Pt(w)?Je(w,T=>UT(n,T)):[UT(n,w)]}),h=Je(n,b=>b.PUSH_MODE),f=Je(n,b=>Bt(b,"POP_MODE"))});let d;r("Line Terminator Handling",()=>{let b=Qae(e.lineTerminatorCharacters);d=Je(n,w=>!1),e.positionTracking!=="onlyOffset"&&(d=Je(n,w=>Bt(w,"LINE_BREAKS")?!!w.LINE_BREAKS:Kae(w,b)===!1&&Nk(b,w.PATTERN)))});let p,m,g,y;r("Misc Mapping #2",()=>{p=Je(n,Xae),m=Je(a,$Pe),g=Xr(n,(b,w)=>{let C=w.GROUP;return yi(C)&&C!==Xn.SKIPPED&&(b[C]=[]),b},{}),y=Je(a,(b,w)=>({pattern:a[w],longerAlt:u[w],canLineTerminator:d[w],isCustom:p[w],short:m[w],group:l[w],push:h[w],pop:f[w],tokenTypeIdx:s[w],tokenType:n[w]}))});let v=!0,x=[];return e.safeMode||r("First Char Optimization",()=>{x=Xr(n,(b,w,C)=>{if(typeof w.PATTERN=="string"){let T=w.PATTERN.charCodeAt(0),E=Ic(T);CN(b,E,y[C])}else if(Pt(w.START_CHARS_HINT)){let T;Ae(w.START_CHARS_HINT,E=>{let A=typeof E=="string"?E.charCodeAt(0):E,S=Ic(A);T!==S&&(T=S,CN(b,S,y[C]))})}else if(zo(w.PATTERN))if(w.PATTERN.unicode)v=!1,e.ensureOptimizations&&Ig(`${nx} Unable to analyze < ${w.PATTERN.toString()} > pattern.
+ The regexp unicode flag is not currently supported by the regexp-to-ast library.
+ This will disable the lexer's first char optimizations.
+ For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{let T=$ae(w.PATTERN,e.ensureOptimizations);ur(T)&&(v=!1),Ae(T,E=>{CN(b,E,y[C])})}else e.ensureOptimizations&&Ig(`${nx} TokenType: <${w.name}> is using a custom token pattern without providing <start_chars_hint> parameter.
+ This will disable the lexer's first char optimizations.
+ For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),v=!1;return b},[])}),{emptyGroups:g,patternIdxToConfig:y,charCodeToPatternIdxToConfig:x,hasCustom:i,canBeOptimized:v}}function Hae(t,e){let r=[],n=SPe(t);r=r.concat(n.errors);let i=CPe(n.valid),a=i.valid;return r=r.concat(i.errors),r=r.concat(EPe(a)),r=r.concat(IPe(a)),r=r.concat(OPe(a,e)),r=r.concat(PPe(a)),r}function EPe(t){let e=[],r=Yr(t,n=>zo(n[lp]));return e=e.concat(_Pe(r)),e=e.concat(RPe(r)),e=e.concat(NPe(r)),e=e.concat(MPe(r)),e=e.concat(DPe(r)),e}function SPe(t){let e=Yr(t,i=>!Bt(i,lp)),r=Je(e,i=>({message:"Token Type: ->"+i.name+"<- missing static 'PATTERN' property",type:Yn.MISSING_PATTERN,tokenTypes:[i]})),n=Zh(t,e);return{errors:r,valid:n}}function CPe(t){let e=Yr(t,i=>{let a=i[lp];return!zo(a)&&!Si(a)&&!Bt(a,"exec")&&!yi(a)}),r=Je(e,i=>({message:"Token Type: ->"+i.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:Yn.INVALID_PATTERN,tokenTypes:[i]})),n=Zh(t,e);return{errors:r,valid:n}}function _Pe(t){class e extends Mc{static{o(this,"EndAnchorFinder")}constructor(){super(...arguments),this.found=!1}visitEndAnchor(a){this.found=!0}}let r=Yr(t,i=>{let a=i.PATTERN;try{let s=Bg(a),l=new e;return l.visit(s),l.found}catch{return APe.test(a.source)}});return Je(r,i=>({message:`Unexpected RegExp Anchor Error:
+ Token Type: ->`+i.name+`<- static 'PATTERN' cannot contain end of input anchor '$'
+ See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:Yn.EOI_ANCHOR_FOUND,tokenTypes:[i]}))}function DPe(t){let e=Yr(t,n=>n.PATTERN.test(""));return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'PATTERN' must not match an empty string",type:Yn.EMPTY_MATCH_PATTERN,tokenTypes:[n]}))}function RPe(t){class e extends Mc{static{o(this,"StartAnchorFinder")}constructor(){super(...arguments),this.found=!1}visitStartAnchor(a){this.found=!0}}let r=Yr(t,i=>{let a=i.PATTERN;try{let s=Bg(a),l=new e;return l.visit(s),l.found}catch{return LPe.test(a.source)}});return Je(r,i=>({message:`Unexpected RegExp Anchor Error:
+ Token Type: ->`+i.name+`<- static 'PATTERN' cannot contain start of input anchor '^'
+ See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:Yn.SOI_ANCHOR_FOUND,tokenTypes:[i]}))}function NPe(t){let e=Yr(t,n=>{let i=n[lp];return i instanceof RegExp&&(i.multiline||i.global)});return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:Yn.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[n]}))}function MPe(t){let e=[],r=Je(t,a=>Xr(t,(s,l)=>(a.PATTERN.source===l.PATTERN.source&&!qn(e,l)&&l.PATTERN!==Xn.NA&&(e.push(l),s.push(l)),s),[]));r=Tc(r);let n=Yr(r,a=>a.length>1);return Je(n,a=>{let s=Je(a,u=>u.name);return{message:`The same RegExp pattern ->${ia(a).PATTERN}<-has been used in all of the following Token Types: ${s.join(", ")} <-`,type:Yn.DUPLICATE_PATTERNS_FOUND,tokenTypes:a}})}function IPe(t){let e=Yr(t,n=>{if(!Bt(n,"GROUP"))return!1;let i=n.GROUP;return i!==Xn.SKIPPED&&i!==Xn.NA&&!yi(i)});return Je(e,n=>({message:"Token Type: ->"+n.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:Yn.INVALID_GROUP_TYPE_FOUND,tokenTypes:[n]}))}function OPe(t,e){let r=Yr(t,i=>i.PUSH_MODE!==void 0&&!qn(e,i.PUSH_MODE));return Je(r,i=>({message:`Token Type: ->${i.name}<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->${i.PUSH_MODE}<-which does not exist`,type:Yn.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[i]}))}function PPe(t){let e=[],r=Xr(t,(n,i,a)=>{let s=i.PATTERN;return s===Xn.NA||(yi(s)?n.push({str:s,idx:a,tokenType:i}):zo(s)&&FPe(s)&&n.push({str:s.source,idx:a,tokenType:i})),n},[]);return Ae(t,(n,i)=>{Ae(r,({str:a,idx:s,tokenType:l})=>{if(i<s&&BPe(a,n.PATTERN)){let u=`Token: ->${l.name}<- can never be matched.
+Because it appears AFTER the Token Type ->${n.name}<-in the lexer's definition.
+See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:u,type:Yn.UNREACHABLE_PATTERN,tokenTypes:[n,l]})}})}),e}function BPe(t,e){if(zo(e)){let r=e.exec(t);return r!==null&&r.index===0}else{if(Si(e))return e(t,0,[],{});if(Bt(e,"exec"))return e.exec(t,0,[],{});if(typeof e=="string")return e===t;throw Error("non exhaustive match")}}function FPe(t){return ns([".","\\","[","]","|","^","$","(",")","?","*","+","{"],r=>t.source.indexOf(r)!==-1)===void 0}function Gae(t){let e=t.ignoreCase?"i":"";return new RegExp(`^(?:${t.source})`,e)}function Vae(t){let e=t.ignoreCase?"iy":"y";return new RegExp(`${t.source}`,e)}function Wae(t,e,r){let n=[];return Bt(t,$g)||n.push({message:"A MultiMode Lexer cannot be initialized without a <"+$g+`> property in its definition
+`,type:Yn.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),Bt(t,Mk)||n.push({message:"A MultiMode Lexer cannot be initialized without a <"+Mk+`> property in its definition
+`,type:Yn.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),Bt(t,Mk)&&Bt(t,$g)&&!Bt(t.modes,t.defaultMode)&&n.push({message:`A MultiMode Lexer cannot be initialized with a ${$g}: <${t.defaultMode}>which does not exist
+`,type:Yn.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),Bt(t,Mk)&&Ae(t.modes,(i,a)=>{Ae(i,(s,l)=>{if(pr(s))n.push({message:`A Lexer cannot be initialized using an undefined Token Type. Mode:<${a}> at index: <${l}>
+`,type:Yn.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED});else if(Bt(s,"LONGER_ALT")){let u=Pt(s.LONGER_ALT)?s.LONGER_ALT:[s.LONGER_ALT];Ae(u,h=>{!pr(h)&&!qn(i,h)&&n.push({message:`A MultiMode Lexer cannot be initialized with a longer_alt <${h.name}> on token <${s.name}> outside of mode <${a}>
+`,type:Yn.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE})})}})}),n}function qae(t,e,r){let n=[],i=!1,a=Tc(qr(br(t.modes))),s=Jh(a,u=>u[lp]===Xn.NA),l=Qae(r);return e&&Ae(s,u=>{let h=Kae(u,l);if(h!==!1){let d={message:zPe(u,h),type:h.issue,tokenType:u};n.push(d)}else Bt(u,"LINE_BREAKS")?u.LINE_BREAKS===!0&&(i=!0):Nk(l,u.PATTERN)&&(i=!0)}),e&&!i&&n.push({message:`Warning: No LINE_BREAKS Found.
+ This Lexer has been defined to track line and column information,
+ But none of the Token Types can be identified as matching a line terminator.
+ See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS
+ for details.`,type:Yn.NO_LINE_BREAKS_FLAGS}),n}function Yae(t){let e={},r=zr(t);return Ae(r,n=>{let i=t[n];if(Pt(i))e[n]=[];else throw Error("non exhaustive match")}),e}function Xae(t){let e=t.PATTERN;if(zo(e))return!1;if(Si(e))return!0;if(Bt(e,"exec"))return!0;if(yi(e))return!1;throw Error("non exhaustive match")}function $Pe(t){return yi(t)&&t.length===1?t.charCodeAt(0):!1}function Kae(t,e){if(Bt(t,"LINE_BREAKS"))return!1;if(zo(t.PATTERN)){try{Nk(e,t.PATTERN)}catch(r){return{issue:Yn.IDENTIFY_TERMINATOR,errMsg:r.message}}return!1}else{if(yi(t.PATTERN))return!1;if(Xae(t))return{issue:Yn.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}}function zPe(t,e){if(e.issue===Yn.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern.
+ The problem is in the <${t.name}> Token Type
+ Root cause: ${e.errMsg}.
+ For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR`;if(e.issue===Yn.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the <line_breaks> option.
+ The problem is in the <${t.name}> Token Type
+ For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK`;throw Error("non exhaustive match")}function Qae(t){return Je(t,r=>yi(r)?r.charCodeAt(0):r)}function CN(t,e,r){t[e]===void 0?t[e]=[r]:t[e].push(r)}function Ic(t){return t<Fg?t:Ik[t]}function GPe(){if(ur(Ik)){Ik=new Array(65536);for(let t=0;t<65536;t++)Ik[t]=t>255?255+~~(t/255):t}}var lp,$g,Mk,AN,APe,LPe,jae,Fg,Ik,SN=N(()=>{"use strict";j2();ix();qt();Og();zae();Lk();lp="PATTERN",$g="defaultMode",Mk="modes",AN=typeof new RegExp("(?:)").sticky=="boolean";o(Uae,"analyzeTokenTypes");o(Hae,"validatePatterns");o(EPe,"validateRegExpPattern");o(SPe,"findMissingPatterns");o(CPe,"findInvalidPatterns");APe=/[^\\][$]/;o(_Pe,"findEndOfInputAnchor");o(DPe,"findEmptyMatchRegExps");LPe=/[^\\[][\^]|^\^/;o(RPe,"findStartOfInputAnchor");o(NPe,"findUnsupportedFlags");o(MPe,"findDuplicatePatterns");o(IPe,"findInvalidGroupType");o(OPe,"findModesThatDoNotExist");o(PPe,"findUnreachablePatterns");o(BPe,"testTokenType");o(FPe,"noMetaChar");o(Gae,"addStartOfInput");o(Vae,"addStickyFlag");o(Wae,"performRuntimeChecks");o(qae,"performWarningRuntimeChecks");o(Yae,"cloneEmptyGroups");o(Xae,"isCustomPattern");o($Pe,"isShortPattern");jae={test:o(function(t){let e=t.length;for(let r=this.lastIndex;r<e;r++){let n=t.charCodeAt(r);if(n===10)return this.lastIndex=r+1,!0;if(n===13)return t.charCodeAt(r+1)===10?this.lastIndex=r+2:this.lastIndex=r+1,!0}return!1},"test"),lastIndex:0};o(Kae,"checkLineBreaksIssues");o(zPe,"buildLineBreakIssueMessage");o(Qae,"getCharCodes");o(CN,"addToMapOfArrays");Fg=256,Ik=[];o(Ic,"charCodeToOptimizedIndex");o(GPe,"initCharCodeToOptimizedIndexMap")});function Pu(t,e){let r=t.tokenTypeIdx;return r===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[r]===!0}function zg(t,e){return t.tokenTypeIdx===e.tokenTypeIdx}function Bu(t){let e=VPe(t);UPe(e),WPe(e),HPe(e),Ae(e,r=>{r.isParent=r.categoryMatches.length>0})}function VPe(t){let e=an(t),r=t,n=!0;for(;n;){r=Tc(qr(Je(r,a=>a.CATEGORIES)));let i=Zh(r,e);e=e.concat(i),ur(i)?n=!1:r=i}return e}function UPe(t){Ae(t,e=>{_N(e)||(ese[Zae]=e,e.tokenTypeIdx=Zae++),Jae(e)&&!Pt(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Jae(e)||(e.CATEGORIES=[]),qPe(e)||(e.categoryMatches=[]),YPe(e)||(e.categoryMatchesMap={})})}function HPe(t){Ae(t,e=>{e.categoryMatches=[],Ae(e.categoryMatchesMap,(r,n)=>{e.categoryMatches.push(ese[n].tokenTypeIdx)})})}function WPe(t){Ae(t,e=>{tse([],e)})}function tse(t,e){Ae(t,r=>{e.categoryMatchesMap[r.tokenTypeIdx]=!0}),Ae(e.CATEGORIES,r=>{let n=t.concat(e);qn(n,r)||tse(n,r)})}function _N(t){return Bt(t,"tokenTypeIdx")}function Jae(t){return Bt(t,"CATEGORIES")}function qPe(t){return Bt(t,"categoryMatches")}function YPe(t){return Bt(t,"categoryMatchesMap")}function rse(t){return Bt(t,"tokenTypeIdx")}var Zae,ese,cp=N(()=>{"use strict";qt();o(Pu,"tokenStructuredMatcher");o(zg,"tokenStructuredMatcherNoCategories");Zae=1,ese={};o(Bu,"augmentTokenTypes");o(VPe,"expandCategories");o(UPe,"assignTokenDefaultProps");o(HPe,"assignCategoriesTokensProp");o(WPe,"assignCategoriesMapProp");o(tse,"singleAssignCategoriesToksMap");o(_N,"hasShortKeyProperty");o(Jae,"hasCategoriesProperty");o(qPe,"hasExtendingTokensTypesProperty");o(YPe,"hasExtendingTokensTypesMapProperty");o(rse,"isTokenType")});var Gg,DN=N(()=>{"use strict";Gg={buildUnableToPopLexerModeMessage(t){return`Unable to pop Lexer Mode after encountering Token ->${t.image}<- The Mode Stack is empty`},buildUnexpectedCharactersMessage(t,e,r,n,i){return`unexpected character: ->${t.charAt(e)}<- at offset: ${e}, skipped ${r} characters.`}}});var Yn,ax,Xn,ix=N(()=>{"use strict";SN();qt();Og();cp();DN();Lk();(function(t){t[t.MISSING_PATTERN=0]="MISSING_PATTERN",t[t.INVALID_PATTERN=1]="INVALID_PATTERN",t[t.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",t[t.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",t[t.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",t[t.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",t[t.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",t[t.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",t[t.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",t[t.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",t[t.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",t[t.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",t[t.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",t[t.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",t[t.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",t[t.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",t[t.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK",t[t.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE=17]="MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE"})(Yn||(Yn={}));ax={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[`
+`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:Gg,traceInitPerf:!1,skipValidations:!1,recoveryEnabled:!0};Object.freeze(ax);Xn=class{static{o(this,"Lexer")}constructor(e,r=ax){if(this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},this.TRACE_INIT=(i,a)=>{if(this.traceInitPerf===!0){this.traceInitIndent++;let s=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent<this.traceInitMaxIdent&&console.log(`${s}--> <${i}>`);let{time:l,value:u}=tx(a),h=l>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&h(`${s}<-- <${i}> time: ${l}ms`),this.traceInitIndent--,u}else return a()},typeof r=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object.
+a boolean 2nd argument is no longer supported`);this.config=ma({},ax,r);let n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",()=>{let i,a=!0;this.TRACE_INIT("Lexer Config handling",()=>{if(this.config.lineTerminatorsPattern===ax.lineTerminatorsPattern)this.config.lineTerminatorsPattern=jae;else if(this.config.lineTerminatorCharacters===ax.lineTerminatorCharacters)throw Error(`Error: Missing <lineTerminatorCharacters> property on the Lexer config.
+ For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(r.safeMode&&r.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');this.trackStartLines=/full|onlyStart/i.test(this.config.positionTracking),this.trackEndLines=/full/i.test(this.config.positionTracking),Pt(e)?i={modes:{defaultMode:an(e)},defaultMode:$g}:(a=!1,i=an(e))}),this.config.skipValidations===!1&&(this.TRACE_INIT("performRuntimeChecks",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(Wae(i,this.trackStartLines,this.config.lineTerminatorCharacters))}),this.TRACE_INIT("performWarningRuntimeChecks",()=>{this.lexerDefinitionWarning=this.lexerDefinitionWarning.concat(qae(i,this.trackStartLines,this.config.lineTerminatorCharacters))})),i.modes=i.modes?i.modes:{},Ae(i.modes,(l,u)=>{i.modes[u]=Jh(l,h=>pr(h))});let s=zr(i.modes);if(Ae(i.modes,(l,u)=>{this.TRACE_INIT(`Mode: <${u}> processing`,()=>{if(this.modes.push(u),this.config.skipValidations===!1&&this.TRACE_INIT("validatePatterns",()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(Hae(l,s))}),ur(this.lexerDefinitionErrors)){Bu(l);let h;this.TRACE_INIT("analyzeTokenTypes",()=>{h=Uae(l,{lineTerminatorCharacters:this.config.lineTerminatorCharacters,positionTracking:r.positionTracking,ensureOptimizations:r.ensureOptimizations,safeMode:r.safeMode,tracer:this.TRACE_INIT})}),this.patternIdxToConfig[u]=h.patternIdxToConfig,this.charCodeToPatternIdxToConfig[u]=h.charCodeToPatternIdxToConfig,this.emptyGroups=ma({},this.emptyGroups,h.emptyGroups),this.hasCustom=h.hasCustom||this.hasCustom,this.canModeBeOptimized[u]=h.canBeOptimized}})}),this.defaultMode=i.defaultMode,!ur(this.lexerDefinitionErrors)&&!this.config.deferDefinitionErrorsHandling){let u=Je(this.lexerDefinitionErrors,h=>h.message).join(`-----------------------
+`);throw new Error(`Errors detected in definition of Lexer:
+`+u)}Ae(this.lexerDefinitionWarning,l=>{ex(l.message)}),this.TRACE_INIT("Choosing sub-methods implementations",()=>{if(AN?(this.chopInput=ta,this.match=this.matchWithTest):(this.updateLastIndex=ni,this.match=this.matchWithExec),a&&(this.handleModes=ni),this.trackStartLines===!1&&(this.computeNewColumn=ta),this.trackEndLines===!1&&(this.updateTokenEndLineColumnLocation=ni),/full/i.test(this.config.positionTracking))this.createTokenInstance=this.createFullToken;else if(/onlyStart/i.test(this.config.positionTracking))this.createTokenInstance=this.createStartOnlyToken;else if(/onlyOffset/i.test(this.config.positionTracking))this.createTokenInstance=this.createOffsetOnlyToken;else throw Error(`Invalid <positionTracking> config option: "${this.config.positionTracking}"`);this.hasCustom?(this.addToken=this.addTokenUsingPush,this.handlePayload=this.handlePayloadWithCustom):(this.addToken=this.addTokenUsingMemberAccess,this.handlePayload=this.handlePayloadNoCustom)}),this.TRACE_INIT("Failed Optimization Warnings",()=>{let l=Xr(this.canModeBeOptimized,(u,h,f)=>(h===!1&&u.push(f),u),[]);if(r.ensureOptimizations&&!ur(l))throw Error(`Lexer Modes: < ${l.join(", ")} > cannot be optimized.
+ Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode.
+ Or inspect the console log for details on how to resolve these issues.`)}),this.TRACE_INIT("clearRegExpParserCache",()=>{Pae()}),this.TRACE_INIT("toFastProperties",()=>{rx(this)})})}tokenize(e,r=this.defaultMode){if(!ur(this.lexerDefinitionErrors)){let i=Je(this.lexerDefinitionErrors,a=>a.message).join(`-----------------------
+`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer:
+`+i)}return this.tokenizeInternal(e,r)}tokenizeInternal(e,r){let n,i,a,s,l,u,h,f,d,p,m,g,y,v,x,b,w=e,C=w.length,T=0,E=0,A=this.hasCustom?0:Math.floor(e.length/10),S=new Array(A),_=[],I=this.trackStartLines?1:void 0,D=this.trackStartLines?1:void 0,k=Yae(this.emptyGroups),L=this.trackStartLines,R=this.config.lineTerminatorsPattern,O=0,M=[],B=[],F=[],P=[];Object.freeze(P);let z;function $(){return M}o($,"getPossiblePatternsSlow");function H(le){let he=Ic(le),K=B[he];return K===void 0?P:K}o(H,"getPossiblePatternsOptimized");let Q=o(le=>{if(F.length===1&&le.tokenType.PUSH_MODE===void 0){let he=this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(le);_.push({offset:le.startOffset,line:le.startLine,column:le.startColumn,length:le.image.length,message:he})}else{F.pop();let he=ga(F);M=this.patternIdxToConfig[he],B=this.charCodeToPatternIdxToConfig[he],O=M.length;let K=this.canModeBeOptimized[he]&&this.config.safeMode===!1;B&&K?z=H:z=$}},"pop_mode");function j(le){F.push(le),B=this.charCodeToPatternIdxToConfig[le],M=this.patternIdxToConfig[le],O=M.length,O=M.length;let he=this.canModeBeOptimized[le]&&this.config.safeMode===!1;B&&he?z=H:z=$}o(j,"push_mode"),j.call(this,r);let ie,ne=this.config.recoveryEnabled;for(;T<C;){u=null;let le=w.charCodeAt(T),he=z(le),K=he.length;for(n=0;n<K;n++){ie=he[n];let X=ie.pattern;h=null;let te=ie.short;if(te!==!1?le===te&&(u=X):ie.isCustom===!0?(b=X.exec(w,T,S,k),b!==null?(u=b[0],b.payload!==void 0&&(h=b.payload)):u=null):(this.updateLastIndex(X,T),u=this.match(X,e,T)),u!==null){if(l=ie.longerAlt,l!==void 0){let J=l.length;for(a=0;a<J;a++){let se=M[l[a]],ue=se.pattern;if(f=null,se.isCustom===!0?(b=ue.exec(w,T,S,k),b!==null?(s=b[0],b.payload!==void 0&&(f=b.payload)):s=null):(this.updateLastIndex(ue,T),s=this.match(ue,e,T)),s&&s.length>u.length){u=s,h=f,ie=se;break}}}break}}if(u!==null){if(d=u.length,p=ie.group,p!==void 0&&(m=ie.tokenTypeIdx,g=this.createTokenInstance(u,T,m,ie.tokenType,I,D,d),this.handlePayload(g,h),p===!1?E=this.addToken(S,E,g):k[p].push(g)),e=this.chopInput(e,d),T=T+d,D=this.computeNewColumn(D,d),L===!0&&ie.canLineTerminator===!0){let X=0,te,J;R.lastIndex=0;do te=R.test(u),te===!0&&(J=R.lastIndex-1,X++);while(te===!0);X!==0&&(I=I+X,D=d-J,this.updateTokenEndLineColumnLocation(g,p,J,X,I,D,d))}this.handleModes(ie,Q,j,g)}else{let X=T,te=I,J=D,se=ne===!1;for(;se===!1&&T<C;)for(e=this.chopInput(e,1),T++,i=0;i<O;i++){let ue=M[i],Z=ue.pattern,Se=ue.short;if(Se!==!1?w.charCodeAt(T)===Se&&(se=!0):ue.isCustom===!0?se=Z.exec(w,T,S,k)!==null:(this.updateLastIndex(Z,T),se=Z.exec(e)!==null),se===!0)break}if(y=T-X,D=this.computeNewColumn(D,y),x=this.config.errorMessageProvider.buildUnexpectedCharactersMessage(w,X,y,te,J),_.push({offset:X,line:te,column:J,length:y,message:x}),ne===!1)break}}return this.hasCustom||(S.length=E),{tokens:S,groups:k,errors:_}}handleModes(e,r,n,i){if(e.pop===!0){let a=e.push;r(i),a!==void 0&&n.call(this,a)}else e.push!==void 0&&n.call(this,e.push)}chopInput(e,r){return e.substring(r)}updateLastIndex(e,r){e.lastIndex=r}updateTokenEndLineColumnLocation(e,r,n,i,a,s,l){let u,h;r!==void 0&&(u=n===l-1,h=u?-1:0,i===1&&u===!0||(e.endLine=a+h,e.endColumn=s-1+-h))}computeNewColumn(e,r){return e+r}createOffsetOnlyToken(e,r,n,i){return{image:e,startOffset:r,tokenTypeIdx:n,tokenType:i}}createStartOnlyToken(e,r,n,i,a,s){return{image:e,startOffset:r,startLine:a,startColumn:s,tokenTypeIdx:n,tokenType:i}}createFullToken(e,r,n,i,a,s,l){return{image:e,startOffset:r,endOffset:r+l-1,startLine:a,endLine:a,startColumn:s,endColumn:s+l-1,tokenTypeIdx:n,tokenType:i}}addTokenUsingPush(e,r,n){return e.push(n),r}addTokenUsingMemberAccess(e,r,n){return e[r]=n,r++,r}handlePayloadNoCustom(e,r){}handlePayloadWithCustom(e,r){r!==null&&(e.payload=r)}matchWithTest(e,r,n){return e.test(r)===!0?r.substring(n,e.lastIndex):null}matchWithExec(e,r){let n=e.exec(r);return n!==null?n[0]:null}};Xn.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.";Xn.NA=/NOT_APPLICABLE/});function Fu(t){return LN(t)?t.LABEL:t.name}function LN(t){return yi(t.LABEL)&&t.LABEL!==""}function of(t){return jPe(t)}function jPe(t){let e=t.pattern,r={};if(r.name=t.name,pr(e)||(r.PATTERN=e),Bt(t,XPe))throw`The parent property is no longer supported.
+See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return Bt(t,nse)&&(r.CATEGORIES=t[nse]),Bu([r]),Bt(t,ise)&&(r.LABEL=t[ise]),Bt(t,ase)&&(r.GROUP=t[ase]),Bt(t,ose)&&(r.POP_MODE=t[ose]),Bt(t,sse)&&(r.PUSH_MODE=t[sse]),Bt(t,lse)&&(r.LONGER_ALT=t[lse]),Bt(t,cse)&&(r.LINE_BREAKS=t[cse]),Bt(t,use)&&(r.START_CHARS_HINT=t[use]),r}function $u(t,e,r,n,i,a,s,l){return{image:e,startOffset:r,endOffset:n,startLine:i,endLine:a,startColumn:s,endColumn:l,tokenTypeIdx:t.tokenTypeIdx,tokenType:t}}function sx(t,e){return Pu(t,e)}var XPe,nse,ise,ase,sse,ose,lse,cse,use,lo,up=N(()=>{"use strict";qt();ix();cp();o(Fu,"tokenLabel");o(LN,"hasTokenLabel");XPe="parent",nse="categories",ise="label",ase="group",sse="push_mode",ose="pop_mode",lse="longer_alt",cse="line_breaks",use="start_chars_hint";o(of,"createToken");o(jPe,"createTokenInternal");lo=of({name:"EOF",pattern:Xn.NA});Bu([lo]);o($u,"createTokenInstance");o(sx,"tokenMatcher")});var zu,hse,Pl,Vg=N(()=>{"use strict";up();qt();os();zu={buildMismatchTokenMessage({expected:t,actual:e,previous:r,ruleName:n}){return`Expecting ${LN(t)?`--> ${Fu(t)} <--`:`token of type --> ${t.name} <--`} but found --> '${e.image}' <--`},buildNotAllInputParsedMessage({firstRedundant:t,ruleName:e}){return"Redundant input, expecting EOF but found: "+t.image},buildNoViableAltMessage({expectedPathsPerAlt:t,actual:e,previous:r,customUserDescription:n,ruleName:i}){let a="Expecting: ",l=`
+but found: '`+ia(e).image+"'";if(n)return a+n+l;{let u=Xr(t,(p,m)=>p.concat(m),[]),h=Je(u,p=>`[${Je(p,m=>Fu(m)).join(", ")}]`),d=`one of these possible Token sequences:
+${Je(h,(p,m)=>` ${m+1}. ${p}`).join(`
+`)}`;return a+d+l}},buildEarlyExitMessage({expectedIterationPaths:t,actual:e,customUserDescription:r,ruleName:n}){let i="Expecting: ",s=`
+but found: '`+ia(e).image+"'";if(r)return i+r+s;{let u=`expecting at least one iteration which starts with one of these possible Token sequences::
+ <${Je(t,h=>`[${Je(h,f=>Fu(f)).join(",")}]`).join(" ,")}>`;return i+u+s}}};Object.freeze(zu);hse={buildRuleNotFoundError(t,e){return"Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<-
+inside top level rule: ->`+t.name+"<-"}},Pl={buildDuplicateFoundError(t,e){function r(f){return f instanceof kr?f.terminalType.name:f instanceof on?f.nonTerminalName:""}o(r,"getExtraProductionArgument");let n=t.name,i=ia(e),a=i.idx,s=Bs(i),l=r(i),u=a>0,h=`->${s}${u?a:""}<- ${l?`with argument: ->${l}<-`:""}
+ appears more than once (${e.length} times) in the top level rule: ->${n}<-.
+ For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES
+ `;return h=h.replace(/[ \t]+/g," "),h=h.replace(/\s\s+/g,`
+`),h},buildNamespaceConflictError(t){return`Namespace conflict found in grammar.
+The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <${t.name}>.
+To resolve this make sure each Terminal and Non-Terminal names are unique
+This is easy to accomplish by using the convention that Terminal names start with an uppercase letter
+and Non-Terminal names start with a lower case letter.`},buildAlternationPrefixAmbiguityError(t){let e=Je(t.prefixPath,i=>Fu(i)).join(", "),r=t.alternation.idx===0?"":t.alternation.idx;return`Ambiguous alternatives: <${t.ambiguityIndices.join(" ,")}> due to common lookahead prefix
+in <OR${r}> inside <${t.topLevelRule.name}> Rule,
+<${e}> may appears as a prefix path in all these alternatives.
+See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
+For Further details.`},buildAlternationAmbiguityError(t){let e=Je(t.prefixPath,i=>Fu(i)).join(", "),r=t.alternation.idx===0?"":t.alternation.idx,n=`Ambiguous Alternatives Detected: <${t.ambiguityIndices.join(" ,")}> in <OR${r}> inside <${t.topLevelRule.name}> Rule,
+<${e}> may appears as a prefix path in all these alternatives.
+`;return n=n+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
+For Further details.`,n},buildEmptyRepetitionError(t){let e=Bs(t.repetition);return t.repetition.idx!==0&&(e+=t.repetition.idx),`The repetition <${e}> within Rule <${t.topLevelRule.name}> can never consume any tokens.
+This could lead to an infinite loop.`},buildTokenNameError(t){return"deprecated"},buildEmptyAlternationError(t){return`Ambiguous empty alternative: <${t.emptyChoiceIdx+1}> in <OR${t.alternation.idx}> inside <${t.topLevelRule.name}> Rule.
+Only the last alternative may be an empty alternative.`},buildTooManyAlternativesError(t){return`An Alternation cannot have more than 256 alternatives:
+<OR${t.alternation.idx}> inside <${t.topLevelRule.name}> Rule.
+ has ${t.alternation.definition.length+1} alternatives.`},buildLeftRecursionError(t){let e=t.topLevelRule.name,r=Je(t.leftRecursionPath,a=>a.name),n=`${e} --> ${r.concat([e]).join(" --> ")}`;return`Left Recursion found in grammar.
+rule: <${e}> can be invoked from itself (directly or indirectly)
+without consuming any Tokens. The grammar path that causes this is:
+ ${n}
+ To fix this refactor your grammar to remove the left recursion.
+see: https://en.wikipedia.org/wiki/LL_parser#Left_factoring.`},buildInvalidRuleNameError(t){return"deprecated"},buildDuplicateRuleNameError(t){let e;return t.topLevelRule instanceof as?e=t.topLevelRule.name:e=t.topLevelRule,`Duplicate definition, rule: ->${e}<- is already defined in the grammar: ->${t.grammarName}<-`}}});function fse(t,e){let r=new RN(t,e);return r.resolveRefs(),r.errors}var RN,dse=N(()=>{"use strict";Fs();qt();os();o(fse,"resolveGrammar");RN=class extends ss{static{o(this,"GastRefResolverVisitor")}constructor(e,r){super(),this.nameToTopRule=e,this.errMsgProvider=r,this.errors=[]}resolveRefs(){Ae(br(this.nameToTopRule),e=>{this.currTopLevel=e,e.accept(this)})}visitNonTerminal(e){let r=this.nameToTopRule[e.nonTerminalName];if(r)e.referencedRule=r;else{let n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,e);this.errors.push({message:n,type:zi.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:e.nonTerminalName})}}}});function Fk(t,e,r=[]){r=an(r);let n=[],i=0;function a(l){return l.concat(gi(t,i+1))}o(a,"remainingPathWith");function s(l){let u=Fk(a(l),e,r);return n.concat(u)}for(o(s,"getAlternativesForProd");r.length<e&&i<t.length;){let l=t[i];if(l instanceof Dn)return s(l.definition);if(l instanceof on)return s(l.definition);if(l instanceof ln)n=s(l.definition);else if(l instanceof Ln){let u=l.definition.concat([new Or({definition:l.definition})]);return s(u)}else if(l instanceof Rn){let u=[new Dn({definition:l.definition}),new Or({definition:[new kr({terminalType:l.separator})].concat(l.definition)})];return s(u)}else if(l instanceof wn){let u=l.definition.concat([new Or({definition:[new kr({terminalType:l.separator})].concat(l.definition)})]);n=s(u)}else if(l instanceof Or){let u=l.definition.concat([new Or({definition:l.definition})]);n=s(u)}else{if(l instanceof Tn)return Ae(l.definition,u=>{ur(u.definition)===!1&&(n=s(u.definition))}),n;if(l instanceof kr)r.push(l.terminalType);else throw Error("non exhaustive match")}i++}return n.push({partialPath:r,suffixDef:gi(t,i)}),n}function $k(t,e,r,n){let i="EXIT_NONE_TERMINAL",a=[i],s="EXIT_ALTERNATIVE",l=!1,u=e.length,h=u-n-1,f=[],d=[];for(d.push({idx:-1,def:t,ruleStack:[],occurrenceStack:[]});!ur(d);){let p=d.pop();if(p===s){l&&ga(d).idx<=h&&d.pop();continue}let m=p.def,g=p.idx,y=p.ruleStack,v=p.occurrenceStack;if(ur(m))continue;let x=m[0];if(x===i){let b={idx:g,def:gi(m),ruleStack:Nu(y),occurrenceStack:Nu(v)};d.push(b)}else if(x instanceof kr)if(g<u-1){let b=g+1,w=e[b];if(r(w,x.terminalType)){let C={idx:b,def:gi(m),ruleStack:y,occurrenceStack:v};d.push(C)}}else if(g===u-1)f.push({nextTokenType:x.terminalType,nextTokenOccurrence:x.idx,ruleStack:y,occurrenceStack:v}),l=!0;else throw Error("non exhaustive match");else if(x instanceof on){let b=an(y);b.push(x.nonTerminalName);let w=an(v);w.push(x.idx);let C={idx:g,def:x.definition.concat(a,gi(m)),ruleStack:b,occurrenceStack:w};d.push(C)}else if(x instanceof ln){let b={idx:g,def:gi(m),ruleStack:y,occurrenceStack:v};d.push(b),d.push(s);let w={idx:g,def:x.definition.concat(gi(m)),ruleStack:y,occurrenceStack:v};d.push(w)}else if(x instanceof Ln){let b=new Or({definition:x.definition,idx:x.idx}),w=x.definition.concat([b],gi(m)),C={idx:g,def:w,ruleStack:y,occurrenceStack:v};d.push(C)}else if(x instanceof Rn){let b=new kr({terminalType:x.separator}),w=new Or({definition:[b].concat(x.definition),idx:x.idx}),C=x.definition.concat([w],gi(m)),T={idx:g,def:C,ruleStack:y,occurrenceStack:v};d.push(T)}else if(x instanceof wn){let b={idx:g,def:gi(m),ruleStack:y,occurrenceStack:v};d.push(b),d.push(s);let w=new kr({terminalType:x.separator}),C=new Or({definition:[w].concat(x.definition),idx:x.idx}),T=x.definition.concat([C],gi(m)),E={idx:g,def:T,ruleStack:y,occurrenceStack:v};d.push(E)}else if(x instanceof Or){let b={idx:g,def:gi(m),ruleStack:y,occurrenceStack:v};d.push(b),d.push(s);let w=new Or({definition:x.definition,idx:x.idx}),C=x.definition.concat([w],gi(m)),T={idx:g,def:C,ruleStack:y,occurrenceStack:v};d.push(T)}else if(x instanceof Tn)for(let b=x.definition.length-1;b>=0;b--){let w=x.definition[b],C={idx:g,def:w.definition.concat(gi(m)),ruleStack:y,occurrenceStack:v};d.push(C),d.push(s)}else if(x instanceof Dn)d.push({idx:g,def:x.definition.concat(gi(m)),ruleStack:y,occurrenceStack:v});else if(x instanceof as)d.push(KPe(x,g,y,v));else throw Error("non exhaustive match")}return f}function KPe(t,e,r,n){let i=an(r);i.push(t.name);let a=an(n);return a.push(1),{idx:e,def:t.definition,ruleStack:i,occurrenceStack:a}}var NN,Ok,Ug,Pk,ox,Bk,lx,cx=N(()=>{"use strict";qt();xN();Ak();os();NN=class extends Ou{static{o(this,"AbstractNextPossibleTokensWalker")}constructor(e,r){super(),this.topProd=e,this.path=r,this.possibleTokTypes=[],this.nextProductionName="",this.nextProductionOccurrence=0,this.found=!1,this.isAtEndOfPath=!1}startWalking(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=an(this.path.ruleStack).reverse(),this.occurrenceStack=an(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes}walk(e,r=[]){this.found||super.walk(e,r)}walkProdRef(e,r,n){if(e.referencedRule.name===this.nextProductionName&&e.idx===this.nextProductionOccurrence){let i=r.concat(n);this.updateExpectedNext(),this.walk(e.referencedRule,i)}}updateExpectedNext(){ur(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())}},Ok=class extends NN{static{o(this,"NextAfterTokenWalker")}constructor(e,r){super(e,r),this.path=r,this.nextTerminalName="",this.nextTerminalOccurrence=0,this.nextTerminalName=this.path.lastTok.name,this.nextTerminalOccurrence=this.path.lastTokOccurrence}walkTerminal(e,r,n){if(this.isAtEndOfPath&&e.terminalType.name===this.nextTerminalName&&e.idx===this.nextTerminalOccurrence&&!this.found){let i=r.concat(n),a=new Dn({definition:i});this.possibleTokTypes=op(a),this.found=!0}}},Ug=class extends Ou{static{o(this,"AbstractNextTerminalAfterProductionWalker")}constructor(e,r){super(),this.topRule=e,this.occurrence=r,this.result={token:void 0,occurrence:void 0,isEndOfRule:void 0}}startWalking(){return this.walk(this.topRule),this.result}},Pk=class extends Ug{static{o(this,"NextTerminalAfterManyWalker")}walkMany(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof kr&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkMany(e,r,n)}},ox=class extends Ug{static{o(this,"NextTerminalAfterManySepWalker")}walkManySep(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof kr&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkManySep(e,r,n)}},Bk=class extends Ug{static{o(this,"NextTerminalAfterAtLeastOneWalker")}walkAtLeastOne(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof kr&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkAtLeastOne(e,r,n)}},lx=class extends Ug{static{o(this,"NextTerminalAfterAtLeastOneSepWalker")}walkAtLeastOneSep(e,r,n){if(e.idx===this.occurrence){let i=ia(r.concat(n));this.result.isEndOfRule=i===void 0,i instanceof kr&&(this.result.token=i.terminalType,this.result.occurrence=i.idx)}else super.walkAtLeastOneSep(e,r,n)}};o(Fk,"possiblePathsFrom");o($k,"nextPossibleTokensAfter");o(KPe,"expandTopLevelRule")});function ux(t){if(t instanceof ln||t==="Option")return jn.OPTION;if(t instanceof Or||t==="Repetition")return jn.REPETITION;if(t instanceof Ln||t==="RepetitionMandatory")return jn.REPETITION_MANDATORY;if(t instanceof Rn||t==="RepetitionMandatoryWithSeparator")return jn.REPETITION_MANDATORY_WITH_SEPARATOR;if(t instanceof wn||t==="RepetitionWithSeparator")return jn.REPETITION_WITH_SEPARATOR;if(t instanceof Tn||t==="Alternation")return jn.ALTERNATION;throw Error("non exhaustive match")}function Gk(t){let{occurrence:e,rule:r,prodType:n,maxLookahead:i}=t,a=ux(n);return a===jn.ALTERNATION?Hg(e,r,i):Wg(e,r,a,i)}function mse(t,e,r,n,i,a){let s=Hg(t,e,r),l=wse(s)?zg:Pu;return a(s,n,l,i)}function gse(t,e,r,n,i,a){let s=Wg(t,e,i,r),l=wse(s)?zg:Pu;return a(s[0],l,n)}function yse(t,e,r,n){let i=t.length,a=Ma(t,s=>Ma(s,l=>l.length===1));if(e)return function(s){let l=Je(s,u=>u.GATE);for(let u=0;u<i;u++){let h=t[u],f=h.length,d=l[u];if(!(d!==void 0&&d.call(this)===!1))e:for(let p=0;p<f;p++){let m=h[p],g=m.length;for(let y=0;y<g;y++){let v=this.LA(y+1);if(r(v,m[y])===!1)continue e}return u}}};if(a&&!n){let s=Je(t,u=>qr(u)),l=Xr(s,(u,h,f)=>(Ae(h,d=>{Bt(u,d.tokenTypeIdx)||(u[d.tokenTypeIdx]=f),Ae(d.categoryMatches,p=>{Bt(u,p)||(u[p]=f)})}),u),{});return function(){let u=this.LA(1);return l[u.tokenTypeIdx]}}else return function(){for(let s=0;s<i;s++){let l=t[s],u=l.length;e:for(let h=0;h<u;h++){let f=l[h],d=f.length;for(let p=0;p<d;p++){let m=this.LA(p+1);if(r(m,f[p])===!1)continue e}return s}}}}function vse(t,e,r){let n=Ma(t,a=>a.length===1),i=t.length;if(n&&!r){let a=qr(t);if(a.length===1&&ur(a[0].categoryMatches)){let l=a[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===l}}else{let s=Xr(a,(l,u,h)=>(l[u.tokenTypeIdx]=!0,Ae(u.categoryMatches,f=>{l[f]=!0}),l),[]);return function(){let l=this.LA(1);return s[l.tokenTypeIdx]===!0}}}else return function(){e:for(let a=0;a<i;a++){let s=t[a],l=s.length;for(let u=0;u<l;u++){let h=this.LA(u+1);if(e(h,s[u])===!1)continue e}return!0}return!1}}function pse(t){let e=new Array(t);for(let r=0;r<t;r++)e[r]=[];return e}function MN(t){let e=[""];for(let r=0;r<t.length;r++){let n=t[r],i=[];for(let a=0;a<e.length;a++){let s=e[a];i.push(s+"_"+n.tokenTypeIdx);for(let l=0;l<n.categoryMatches.length;l++){let u="_"+n.categoryMatches[l];i.push(s+u)}}e=i}return e}function QPe(t,e,r){for(let n=0;n<t.length;n++){if(n===r)continue;let i=t[n];for(let a=0;a<e.length;a++){let s=e[a];if(i[s]===!0)return!1}}return!0}function xse(t,e){let r=Je(t,s=>Fk([s],1)),n=pse(r.length),i=Je(r,s=>{let l={};return Ae(s,u=>{let h=MN(u.partialPath);Ae(h,f=>{l[f]=!0})}),l}),a=r;for(let s=1;s<=e;s++){let l=a;a=pse(l.length);for(let u=0;u<l.length;u++){let h=l[u];for(let f=0;f<h.length;f++){let d=h[f].partialPath,p=h[f].suffixDef,m=MN(d);if(QPe(i,m,u)||ur(p)||d.length===e){let y=n[u];if(Vk(y,d)===!1){y.push(d);for(let v=0;v<m.length;v++){let x=m[v];i[u][x]=!0}}}else{let y=Fk(p,s+1,d);a[u]=a[u].concat(y),Ae(y,v=>{let x=MN(v.partialPath);Ae(x,b=>{i[u][b]=!0})})}}}}return n}function Hg(t,e,r,n){let i=new zk(t,jn.ALTERNATION,n);return e.accept(i),xse(i.result,r)}function Wg(t,e,r,n){let i=new zk(t,r);e.accept(i);let a=i.result,l=new IN(e,t,r).startWalking(),u=new Dn({definition:a}),h=new Dn({definition:l});return xse([u,h],n)}function Vk(t,e){e:for(let r=0;r<t.length;r++){let n=t[r];if(n.length===e.length){for(let i=0;i<n.length;i++){let a=e[i],s=n[i];if((a===s||s.categoryMatchesMap[a.tokenTypeIdx]!==void 0)===!1)continue e}return!0}}return!1}function bse(t,e){return t.length<e.length&&Ma(t,(r,n)=>{let i=e[n];return r===i||i.categoryMatchesMap[r.tokenTypeIdx]})}function wse(t){return Ma(t,e=>Ma(e,r=>Ma(r,n=>ur(n.categoryMatches))))}var jn,IN,zk,qg=N(()=>{"use strict";qt();cx();Ak();cp();os();(function(t){t[t.OPTION=0]="OPTION",t[t.REPETITION=1]="REPETITION",t[t.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",t[t.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",t[t.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",t[t.ALTERNATION=5]="ALTERNATION"})(jn||(jn={}));o(ux,"getProdType");o(Gk,"getLookaheadPaths");o(mse,"buildLookaheadFuncForOr");o(gse,"buildLookaheadFuncForOptionalProd");o(yse,"buildAlternativesLookAheadFunc");o(vse,"buildSingleAlternativeLookaheadFunction");IN=class extends Ou{static{o(this,"RestDefinitionFinderWalker")}constructor(e,r,n){super(),this.topProd=e,this.targetOccurrence=r,this.targetProdType=n}startWalking(){return this.walk(this.topProd),this.restDef}checkIsTarget(e,r,n,i){return e.idx===this.targetOccurrence&&this.targetProdType===r?(this.restDef=n.concat(i),!0):!1}walkOption(e,r,n){this.checkIsTarget(e,jn.OPTION,r,n)||super.walkOption(e,r,n)}walkAtLeastOne(e,r,n){this.checkIsTarget(e,jn.REPETITION_MANDATORY,r,n)||super.walkOption(e,r,n)}walkAtLeastOneSep(e,r,n){this.checkIsTarget(e,jn.REPETITION_MANDATORY_WITH_SEPARATOR,r,n)||super.walkOption(e,r,n)}walkMany(e,r,n){this.checkIsTarget(e,jn.REPETITION,r,n)||super.walkOption(e,r,n)}walkManySep(e,r,n){this.checkIsTarget(e,jn.REPETITION_WITH_SEPARATOR,r,n)||super.walkOption(e,r,n)}},zk=class extends ss{static{o(this,"InsideDefinitionFinderVisitor")}constructor(e,r,n){super(),this.targetOccurrence=e,this.targetProdType=r,this.targetRef=n,this.result=[]}checkIsTarget(e,r){e.idx===this.targetOccurrence&&this.targetProdType===r&&(this.targetRef===void 0||e===this.targetRef)&&(this.result=e.definition)}visitOption(e){this.checkIsTarget(e,jn.OPTION)}visitRepetition(e){this.checkIsTarget(e,jn.REPETITION)}visitRepetitionMandatory(e){this.checkIsTarget(e,jn.REPETITION_MANDATORY)}visitRepetitionMandatoryWithSeparator(e){this.checkIsTarget(e,jn.REPETITION_MANDATORY_WITH_SEPARATOR)}visitRepetitionWithSeparator(e){this.checkIsTarget(e,jn.REPETITION_WITH_SEPARATOR)}visitAlternation(e){this.checkIsTarget(e,jn.ALTERNATION)}};o(pse,"initializeArrayOfArrays");o(MN,"pathToHashKeys");o(QPe,"isUniquePrefixHash");o(xse,"lookAheadSequenceFromAlternatives");o(Hg,"getLookaheadPathsForOr");o(Wg,"getLookaheadPathsForOptionalProd");o(Vk,"containsPath");o(bse,"isStrictPrefixOfPath");o(wse,"areTokenCategoriesNotUsed")});function Tse(t){let e=t.lookaheadStrategy.validate({rules:t.rules,tokenTypes:t.tokenTypes,grammarName:t.grammarName});return Je(e,r=>Object.assign({type:zi.CUSTOM_LOOKAHEAD_VALIDATION},r))}function kse(t,e,r,n){let i=ya(t,u=>ZPe(u,r)),a=iBe(t,e,r),s=ya(t,u=>tBe(u,r)),l=ya(t,u=>eBe(u,t,n,r));return i.concat(a,s,l)}function ZPe(t,e){let r=new ON;t.accept(r);let n=r.allProductions,i=IL(n,JPe),a=Os(i,l=>l.length>1);return Je(br(a),l=>{let u=ia(l),h=e.buildDuplicateFoundError(t,l),f=Bs(u),d={message:h,type:zi.DUPLICATE_PRODUCTIONS,ruleName:t.name,dslName:f,occurrence:u.idx},p=Ese(u);return p&&(d.parameter=p),d})}function JPe(t){return`${Bs(t)}_#_${t.idx}_#_${Ese(t)}`}function Ese(t){return t instanceof kr?t.terminalType.name:t instanceof on?t.nonTerminalName:""}function eBe(t,e,r,n){let i=[];if(Xr(e,(s,l)=>l.name===t.name?s+1:s,0)>1){let s=n.buildDuplicateRuleNameError({topLevelRule:t,grammarName:r});i.push({message:s,type:zi.DUPLICATE_RULE_NAME,ruleName:t.name})}return i}function Sse(t,e,r){let n=[],i;return qn(e,t)||(i=`Invalid rule override, rule: ->${t}<- cannot be overridden in the grammar: ->${r}<-as it is not defined in any of the super grammars `,n.push({message:i,type:zi.INVALID_RULE_OVERRIDE,ruleName:t})),n}function BN(t,e,r,n=[]){let i=[],a=Uk(e.definition);if(ur(a))return[];{let s=t.name;qn(a,t)&&i.push({message:r.buildLeftRecursionError({topLevelRule:t,leftRecursionPath:n}),type:zi.LEFT_RECURSION,ruleName:s});let u=Zh(a,n.concat([t])),h=ya(u,f=>{let d=an(n);return d.push(f),BN(t,f,r,d)});return i.concat(h)}}function Uk(t){let e=[];if(ur(t))return e;let r=ia(t);if(r instanceof on)e.push(r.referencedRule);else if(r instanceof Dn||r instanceof ln||r instanceof Ln||r instanceof Rn||r instanceof wn||r instanceof Or)e=e.concat(Uk(r.definition));else if(r instanceof Tn)e=qr(Je(r.definition,a=>Uk(a.definition)));else if(!(r instanceof kr))throw Error("non exhaustive match");let n=sp(r),i=t.length>1;if(n&&i){let a=gi(t);return e.concat(Uk(a))}else return e}function Cse(t,e){let r=new hx;t.accept(r);let n=r.alternations;return ya(n,a=>{let s=Nu(a.definition);return ya(s,(l,u)=>{let h=$k([l],[],Pu,1);return ur(h)?[{message:e.buildEmptyAlternationError({topLevelRule:t,alternation:a,emptyChoiceIdx:u}),type:zi.NONE_LAST_EMPTY_ALT,ruleName:t.name,occurrence:a.idx,alternative:u+1}]:[]})})}function Ase(t,e,r){let n=new hx;t.accept(n);let i=n.alternations;return i=Jh(i,s=>s.ignoreAmbiguities===!0),ya(i,s=>{let l=s.idx,u=s.maxLookahead||e,h=Hg(l,t,u,s),f=rBe(h,s,t,r),d=nBe(h,s,t,r);return f.concat(d)})}function tBe(t,e){let r=new hx;t.accept(r);let n=r.alternations;return ya(n,a=>a.definition.length>255?[{message:e.buildTooManyAlternativesError({topLevelRule:t,alternation:a}),type:zi.TOO_MANY_ALTS,ruleName:t.name,occurrence:a.idx}]:[])}function _se(t,e,r){let n=[];return Ae(t,i=>{let a=new PN;i.accept(a);let s=a.allProductions;Ae(s,l=>{let u=ux(l),h=l.maxLookahead||e,f=l.idx,p=Wg(f,i,u,h)[0];if(ur(qr(p))){let m=r.buildEmptyRepetitionError({topLevelRule:i,repetition:l});n.push({message:m,type:zi.NO_NON_EMPTY_LOOKAHEAD,ruleName:i.name})}})}),n}function rBe(t,e,r,n){let i=[],a=Xr(t,(l,u,h)=>(e.definition[h].ignoreAmbiguities===!0||Ae(u,f=>{let d=[h];Ae(t,(p,m)=>{h!==m&&Vk(p,f)&&e.definition[m].ignoreAmbiguities!==!0&&d.push(m)}),d.length>1&&!Vk(i,f)&&(i.push(f),l.push({alts:d,path:f}))}),l),[]);return Je(a,l=>{let u=Je(l.alts,f=>f+1);return{message:n.buildAlternationAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:u,prefixPath:l.path}),type:zi.AMBIGUOUS_ALTS,ruleName:r.name,occurrence:e.idx,alternatives:l.alts}})}function nBe(t,e,r,n){let i=Xr(t,(s,l,u)=>{let h=Je(l,f=>({idx:u,path:f}));return s.concat(h)},[]);return Tc(ya(i,s=>{if(e.definition[s.idx].ignoreAmbiguities===!0)return[];let u=s.idx,h=s.path,f=Yr(i,p=>e.definition[p.idx].ignoreAmbiguities!==!0&&p.idx<u&&bse(p.path,h));return Je(f,p=>{let m=[p.idx+1,u+1],g=e.idx===0?"":e.idx;return{message:n.buildAlternationPrefixAmbiguityError({topLevelRule:r,alternation:e,ambiguityIndices:m,prefixPath:p.path}),type:zi.AMBIGUOUS_PREFIX_ALTS,ruleName:r.name,occurrence:g,alternatives:m}})}))}function iBe(t,e,r){let n=[],i=Je(e,a=>a.name);return Ae(t,a=>{let s=a.name;if(qn(i,s)){let l=r.buildNamespaceConflictError(a);n.push({message:l,type:zi.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:s})}}),n}var ON,hx,PN,fx=N(()=>{"use strict";qt();Fs();os();qg();cx();cp();o(Tse,"validateLookahead");o(kse,"validateGrammar");o(ZPe,"validateDuplicateProductions");o(JPe,"identifyProductionForDuplicates");o(Ese,"getExtraProductionArgument");ON=class extends ss{static{o(this,"OccurrenceValidationCollector")}constructor(){super(...arguments),this.allProductions=[]}visitNonTerminal(e){this.allProductions.push(e)}visitOption(e){this.allProductions.push(e)}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}visitAlternation(e){this.allProductions.push(e)}visitTerminal(e){this.allProductions.push(e)}};o(eBe,"validateRuleDoesNotAlreadyExist");o(Sse,"validateRuleIsOverridden");o(BN,"validateNoLeftRecursion");o(Uk,"getFirstNoneTerminal");hx=class extends ss{static{o(this,"OrCollector")}constructor(){super(...arguments),this.alternations=[]}visitAlternation(e){this.alternations.push(e)}};o(Cse,"validateEmptyOrAlternative");o(Ase,"validateAmbiguousAlternationAlternatives");PN=class extends ss{static{o(this,"RepetitionCollector")}constructor(){super(...arguments),this.allProductions=[]}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}};o(tBe,"validateTooManyAlts");o(_se,"validateSomeNonEmptyLookaheadPath");o(rBe,"checkAlternativesAmbiguities");o(nBe,"checkPrefixAlternativesAmbiguities");o(iBe,"checkTerminalAndNoneTerminalsNameSpace")});function Dse(t){let e=Qh(t,{errMsgProvider:hse}),r={};return Ae(t.rules,n=>{r[n.name]=n}),fse(r,e.errMsgProvider)}function Lse(t){return t=Qh(t,{errMsgProvider:Pl}),kse(t.rules,t.tokenTypes,t.errMsgProvider,t.grammarName)}var Rse=N(()=>{"use strict";qt();dse();fx();Vg();o(Dse,"resolveGrammar");o(Lse,"validateGrammar")});function lf(t){return qn(Pse,t.name)}var Nse,Mse,Ise,Ose,Pse,Yg,hp,dx,px,mx,Xg=N(()=>{"use strict";qt();Nse="MismatchedTokenException",Mse="NoViableAltException",Ise="EarlyExitException",Ose="NotAllInputParsedException",Pse=[Nse,Mse,Ise,Ose];Object.freeze(Pse);o(lf,"isRecognitionException");Yg=class extends Error{static{o(this,"RecognitionException")}constructor(e,r){super(e),this.token=r,this.resyncedTokens=[],Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}},hp=class extends Yg{static{o(this,"MismatchedTokenException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Nse}},dx=class extends Yg{static{o(this,"NoViableAltException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Mse}},px=class extends Yg{static{o(this,"NotAllInputParsedException")}constructor(e,r){super(e,r),this.name=Ose}},mx=class extends Yg{static{o(this,"EarlyExitException")}constructor(e,r,n){super(e,r),this.previousToken=n,this.name=Ise}}});function aBe(t,e,r,n,i,a,s){let l=this.getKeyForAutomaticLookahead(n,i),u=this.firstAfterRepMap[l];if(u===void 0){let p=this.getCurrRuleFullName(),m=this.getGAstProductions()[p];u=new a(m,i).startWalking(),this.firstAfterRepMap[l]=u}let h=u.token,f=u.occurrence,d=u.isEndOfRule;this.RULE_STACK.length===1&&d&&h===void 0&&(h=lo,f=1),!(h===void 0||f===void 0)&&this.shouldInRepetitionRecoveryBeTried(h,f,s)&&this.tryInRepetitionRecovery(t,e,r,h)}var FN,zN,$N,Hk,GN=N(()=>{"use strict";up();qt();Xg();bN();Fs();FN={},zN="InRuleRecoveryException",$N=class extends Error{static{o(this,"InRuleRecoveryException")}constructor(e){super(e),this.name=zN}},Hk=class{static{o(this,"Recoverable")}initRecoverable(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=Bt(e,"recoveryEnabled")?e.recoveryEnabled:ls.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=aBe)}getTokenToInsert(e){let r=$u(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return r.isInsertedInRecovery=!0,r}canTokenTypeBeInsertedInRecovery(e){return!0}canTokenTypeBeDeletedInRecovery(e){return!0}tryInRepetitionRecovery(e,r,n,i){let a=this.findReSyncTokenType(),s=this.exportLexerState(),l=[],u=!1,h=this.LA(1),f=this.LA(1),d=o(()=>{let p=this.LA(0),m=this.errorMessageProvider.buildMismatchTokenMessage({expected:i,actual:h,previous:p,ruleName:this.getCurrRuleFullName()}),g=new hp(m,h,this.LA(0));g.resyncedTokens=Nu(l),this.SAVE_ERROR(g)},"generateErrorMessage");for(;!u;)if(this.tokenMatcher(f,i)){d();return}else if(n.call(this)){d(),e.apply(this,r);return}else this.tokenMatcher(f,a)?u=!0:(f=this.SKIP_TOKEN(),this.addToResyncTokens(f,l));this.importLexerState(s)}shouldInRepetitionRecoveryBeTried(e,r,n){return!(n===!1||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,r)))}getFollowsForInRuleRecovery(e,r){let n=this.getCurrentGrammarPath(e,r);return this.getNextPossibleTokenTypes(n)}tryInRuleRecovery(e,r){if(this.canRecoverWithSingleTokenInsertion(e,r))return this.getTokenToInsert(e);if(this.canRecoverWithSingleTokenDeletion(e)){let n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new $N("sad sad panda")}canPerformInRuleRecovery(e,r){return this.canRecoverWithSingleTokenInsertion(e,r)||this.canRecoverWithSingleTokenDeletion(e)}canRecoverWithSingleTokenInsertion(e,r){if(!this.canTokenTypeBeInsertedInRecovery(e)||ur(r))return!1;let n=this.LA(1);return ns(r,a=>this.tokenMatcher(n,a))!==void 0}canRecoverWithSingleTokenDeletion(e){return this.canTokenTypeBeDeletedInRecovery(e)?this.tokenMatcher(this.LA(2),e):!1}isInCurrentRuleReSyncSet(e){let r=this.getCurrFollowKey(),n=this.getFollowSetFromFollowKey(r);return qn(n,e)}findReSyncTokenType(){let e=this.flattenFollowSet(),r=this.LA(1),n=2;for(;;){let i=ns(e,a=>sx(r,a));if(i!==void 0)return i;r=this.LA(n),n++}}getCurrFollowKey(){if(this.RULE_STACK.length===1)return FN;let e=this.getLastExplicitRuleShortName(),r=this.getLastExplicitRuleOccurrenceIndex(),n=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:r,inRule:this.shortRuleNameToFullName(n)}}buildFullFollowKeyStack(){let e=this.RULE_STACK,r=this.RULE_OCCURRENCE_STACK;return Je(e,(n,i)=>i===0?FN:{ruleName:this.shortRuleNameToFullName(n),idxInCallingRule:r[i],inRule:this.shortRuleNameToFullName(e[i-1])})}flattenFollowSet(){let e=Je(this.buildFullFollowKeyStack(),r=>this.getFollowSetFromFollowKey(r));return qr(e)}getFollowSetFromFollowKey(e){if(e===FN)return[lo];let r=e.ruleName+e.idxInCallingRule+_k+e.inRule;return this.resyncFollows[r]}addToResyncTokens(e,r){return this.tokenMatcher(e,lo)||r.push(e),r}reSyncTo(e){let r=[],n=this.LA(1);for(;this.tokenMatcher(n,e)===!1;)n=this.SKIP_TOKEN(),this.addToResyncTokens(n,r);return Nu(r)}attemptInRepetitionRecovery(e,r,n,i,a,s,l){}getCurrentGrammarPath(e,r){let n=this.getHumanReadableRuleStack(),i=an(this.RULE_OCCURRENCE_STACK);return{ruleStack:n,occurrenceStack:i,lastTok:e,lastTokOccurrence:r}}getHumanReadableRuleStack(){return Je(this.RULE_STACK,e=>this.shortRuleNameToFullName(e))}};o(aBe,"attemptInRepetitionRecovery")});function Wk(t,e,r){return r|e|t}var qk=N(()=>{"use strict";o(Wk,"getKeyForAutomaticLookahead")});var Gu,VN=N(()=>{"use strict";qt();Vg();Fs();fx();qg();Gu=class{static{o(this,"LLkLookaheadStrategy")}constructor(e){var r;this.maxLookahead=(r=e?.maxLookahead)!==null&&r!==void 0?r:ls.maxLookahead}validate(e){let r=this.validateNoLeftRecursion(e.rules);if(ur(r)){let n=this.validateEmptyOrAlternatives(e.rules),i=this.validateAmbiguousAlternationAlternatives(e.rules,this.maxLookahead),a=this.validateSomeNonEmptyLookaheadPath(e.rules,this.maxLookahead);return[...r,...n,...i,...a]}return r}validateNoLeftRecursion(e){return ya(e,r=>BN(r,r,Pl))}validateEmptyOrAlternatives(e){return ya(e,r=>Cse(r,Pl))}validateAmbiguousAlternationAlternatives(e,r){return ya(e,n=>Ase(n,r,Pl))}validateSomeNonEmptyLookaheadPath(e,r){return _se(e,r,Pl)}buildLookaheadForAlternation(e){return mse(e.prodOccurrence,e.rule,e.maxLookahead,e.hasPredicates,e.dynamicTokensEnabled,yse)}buildLookaheadForOptional(e){return gse(e.prodOccurrence,e.rule,e.maxLookahead,e.dynamicTokensEnabled,ux(e.prodType),vse)}}});function sBe(t){Yk.reset(),t.accept(Yk);let e=Yk.dslMethods;return Yk.reset(),e}var Xk,UN,Yk,Bse=N(()=>{"use strict";qt();Fs();qk();os();VN();Xk=class{static{o(this,"LooksAhead")}initLooksAhead(e){this.dynamicTokensEnabled=Bt(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:ls.dynamicTokensEnabled,this.maxLookahead=Bt(e,"maxLookahead")?e.maxLookahead:ls.maxLookahead,this.lookaheadStrategy=Bt(e,"lookaheadStrategy")?e.lookaheadStrategy:new Gu({maxLookahead:this.maxLookahead}),this.lookAheadFuncsCache=new Map}preComputeLookaheadFunctions(e){Ae(e,r=>{this.TRACE_INIT(`${r.name} Rule Lookahead`,()=>{let{alternation:n,repetition:i,option:a,repetitionMandatory:s,repetitionMandatoryWithSeparator:l,repetitionWithSeparator:u}=sBe(r);Ae(n,h=>{let f=h.idx===0?"":h.idx;this.TRACE_INIT(`${Bs(h)}${f}`,()=>{let d=this.lookaheadStrategy.buildLookaheadForAlternation({prodOccurrence:h.idx,rule:r,maxLookahead:h.maxLookahead||this.maxLookahead,hasPredicates:h.hasPredicates,dynamicTokensEnabled:this.dynamicTokensEnabled}),p=Wk(this.fullRuleNameToShort[r.name],256,h.idx);this.setLaFuncCache(p,d)})}),Ae(i,h=>{this.computeLookaheadFunc(r,h.idx,768,"Repetition",h.maxLookahead,Bs(h))}),Ae(a,h=>{this.computeLookaheadFunc(r,h.idx,512,"Option",h.maxLookahead,Bs(h))}),Ae(s,h=>{this.computeLookaheadFunc(r,h.idx,1024,"RepetitionMandatory",h.maxLookahead,Bs(h))}),Ae(l,h=>{this.computeLookaheadFunc(r,h.idx,1536,"RepetitionMandatoryWithSeparator",h.maxLookahead,Bs(h))}),Ae(u,h=>{this.computeLookaheadFunc(r,h.idx,1280,"RepetitionWithSeparator",h.maxLookahead,Bs(h))})})})}computeLookaheadFunc(e,r,n,i,a,s){this.TRACE_INIT(`${s}${r===0?"":r}`,()=>{let l=this.lookaheadStrategy.buildLookaheadForOptional({prodOccurrence:r,rule:e,maxLookahead:a||this.maxLookahead,dynamicTokensEnabled:this.dynamicTokensEnabled,prodType:i}),u=Wk(this.fullRuleNameToShort[e.name],n,r);this.setLaFuncCache(u,l)})}getKeyForAutomaticLookahead(e,r){let n=this.getLastExplicitRuleShortName();return Wk(n,e,r)}getLaFuncFromCache(e){return this.lookAheadFuncsCache.get(e)}setLaFuncCache(e,r){this.lookAheadFuncsCache.set(e,r)}},UN=class extends ss{static{o(this,"DslMethodsCollectorVisitor")}constructor(){super(...arguments),this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}reset(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}visitOption(e){this.dslMethods.option.push(e)}visitRepetitionWithSeparator(e){this.dslMethods.repetitionWithSeparator.push(e)}visitRepetitionMandatory(e){this.dslMethods.repetitionMandatory.push(e)}visitRepetitionMandatoryWithSeparator(e){this.dslMethods.repetitionMandatoryWithSeparator.push(e)}visitRepetition(e){this.dslMethods.repetition.push(e)}visitAlternation(e){this.dslMethods.alternation.push(e)}},Yk=new UN;o(sBe,"collectMethods")});function qN(t,e){isNaN(t.startOffset)===!0?(t.startOffset=e.startOffset,t.endOffset=e.endOffset):t.endOffset<e.endOffset&&(t.endOffset=e.endOffset)}function YN(t,e){isNaN(t.startOffset)===!0?(t.startOffset=e.startOffset,t.startColumn=e.startColumn,t.startLine=e.startLine,t.endOffset=e.endOffset,t.endColumn=e.endColumn,t.endLine=e.endLine):t.endOffset<e.endOffset&&(t.endOffset=e.endOffset,t.endColumn=e.endColumn,t.endLine=e.endLine)}function Fse(t,e,r){t.children[r]===void 0?t.children[r]=[e]:t.children[r].push(e)}function $se(t,e,r){t.children[e]===void 0?t.children[e]=[r]:t.children[e].push(r)}var zse=N(()=>{"use strict";o(qN,"setNodeLocationOnlyOffset");o(YN,"setNodeLocationFull");o(Fse,"addTerminalToCst");o($se,"addNoneTerminalToCst")});function XN(t,e){Object.defineProperty(t,oBe,{enumerable:!1,configurable:!0,writable:!1,value:e})}var oBe,Gse=N(()=>{"use strict";oBe="name";o(XN,"defineNameProp")});function lBe(t,e){let r=zr(t),n=r.length;for(let i=0;i<n;i++){let a=r[i],s=t[a],l=s.length;for(let u=0;u<l;u++){let h=s[u];h.tokenTypeIdx===void 0&&this[h.name](h.children,e)}}}function Vse(t,e){let r=o(function(){},"derivedConstructor");XN(r,t+"BaseSemantics");let n={visit:o(function(i,a){if(Pt(i)&&(i=i[0]),!pr(i))return this[i.name](i.children,a)},"visit"),validateVisitor:o(function(){let i=cBe(this,e);if(!ur(i)){let a=Je(i,s=>s.msg);throw Error(`Errors Detected in CST Visitor <${this.constructor.name}>:
+ ${a.join(`
+
+`).replace(/\n/g,`
+ `)}`)}},"validateVisitor")};return r.prototype=n,r.prototype.constructor=r,r._RULE_NAMES=e,r}function Use(t,e,r){let n=o(function(){},"derivedConstructor");XN(n,t+"BaseSemanticsWithDefaults");let i=Object.create(r.prototype);return Ae(e,a=>{i[a]=lBe}),n.prototype=i,n.prototype.constructor=n,n}function cBe(t,e){return uBe(t,e)}function uBe(t,e){let r=Yr(e,i=>Si(t[i])===!1),n=Je(r,i=>({msg:`Missing visitor method: <${i}> on ${t.constructor.name} CST Visitor.`,type:jN.MISSING_METHOD,methodName:i}));return Tc(n)}var jN,Hse=N(()=>{"use strict";qt();Gse();o(lBe,"defaultVisit");o(Vse,"createBaseSemanticVisitorConstructor");o(Use,"createBaseVisitorConstructorWithDefaults");(function(t){t[t.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",t[t.MISSING_METHOD=1]="MISSING_METHOD"})(jN||(jN={}));o(cBe,"validateVisitor");o(uBe,"validateMissingCstMethods")});var Zk,Wse=N(()=>{"use strict";zse();qt();Hse();Fs();Zk=class{static{o(this,"TreeBuilder")}initTreeBuilder(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=Bt(e,"nodeLocationTracking")?e.nodeLocationTracking:ls.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=ni,this.cstFinallyStateUpdate=ni,this.cstPostTerminal=ni,this.cstPostNonTerminal=ni,this.cstPostRule=ni;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=YN,this.setNodeLocationFromNode=YN,this.cstPostRule=ni,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=ni,this.setNodeLocationFromNode=ni,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=qN,this.setNodeLocationFromNode=qN,this.cstPostRule=ni,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=ni,this.setNodeLocationFromNode=ni,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=ni,this.setNodeLocationFromNode=ni,this.cstPostRule=ni,this.setInitialNodeLocation=ni;else throw Error(`Invalid <nodeLocationTracking> config option: "${e.nodeLocationTracking}"`)}setInitialNodeLocationOnlyOffsetRecovery(e){e.location={startOffset:NaN,endOffset:NaN}}setInitialNodeLocationOnlyOffsetRegular(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}}setInitialNodeLocationFullRecovery(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}}setInitialNodeLocationFullRegular(e){let r=this.LA(1);e.location={startOffset:r.startOffset,startLine:r.startLine,startColumn:r.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}}cstInvocationStateUpdate(e){let r={name:e,children:Object.create(null)};this.setInitialNodeLocation(r),this.CST_STACK.push(r)}cstFinallyStateUpdate(){this.CST_STACK.pop()}cstPostRuleFull(e){let r=this.LA(0),n=e.location;n.startOffset<=r.startOffset?(n.endOffset=r.endOffset,n.endLine=r.endLine,n.endColumn=r.endColumn):(n.startOffset=NaN,n.startLine=NaN,n.startColumn=NaN)}cstPostRuleOnlyOffset(e){let r=this.LA(0),n=e.location;n.startOffset<=r.startOffset?n.endOffset=r.endOffset:n.startOffset=NaN}cstPostTerminal(e,r){let n=this.CST_STACK[this.CST_STACK.length-1];Fse(n,r,e),this.setNodeLocationFromToken(n.location,r)}cstPostNonTerminal(e,r){let n=this.CST_STACK[this.CST_STACK.length-1];$se(n,r,e),this.setNodeLocationFromNode(n.location,e.location)}getBaseCstVisitorConstructor(){if(pr(this.baseCstVisitorConstructor)){let e=Vse(this.className,zr(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor}getBaseCstVisitorConstructorWithDefaults(){if(pr(this.baseCstVisitorWithDefaultsConstructor)){let e=Use(this.className,zr(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor}getLastExplicitRuleShortName(){let e=this.RULE_STACK;return e[e.length-1]}getPreviousExplicitRuleShortName(){let e=this.RULE_STACK;return e[e.length-2]}getLastExplicitRuleOccurrenceIndex(){let e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]}}});var Jk,qse=N(()=>{"use strict";Fs();Jk=class{static{o(this,"LexerAdapter")}initLexerAdapter(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1}set input(e){if(this.selfAnalysisDone!==!0)throw Error("Missing <performSelfAnalysis> invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length}get input(){return this.tokVector}SKIP_TOKEN(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):jg}LA(e){let r=this.currIdx+e;return r<0||this.tokVectorLength<=r?jg:this.tokVector[r]}consumeToken(){this.currIdx++}exportLexerState(){return this.currIdx}importLexerState(e){this.currIdx=e}resetLexerState(){this.currIdx=-1}moveToTerminatedState(){this.currIdx=this.tokVector.length-1}getLexerPosition(){return this.exportLexerState()}}});var eE,Yse=N(()=>{"use strict";qt();Xg();Fs();Vg();fx();os();eE=class{static{o(this,"RecognizerApi")}ACTION(e){return e.call(this)}consume(e,r,n){return this.consumeInternal(r,e,n)}subrule(e,r,n){return this.subruleInternal(r,e,n)}option(e,r){return this.optionInternal(r,e)}or(e,r){return this.orInternal(r,e)}many(e,r){return this.manyInternal(e,r)}atLeastOne(e,r){return this.atLeastOneInternal(e,r)}CONSUME(e,r){return this.consumeInternal(e,0,r)}CONSUME1(e,r){return this.consumeInternal(e,1,r)}CONSUME2(e,r){return this.consumeInternal(e,2,r)}CONSUME3(e,r){return this.consumeInternal(e,3,r)}CONSUME4(e,r){return this.consumeInternal(e,4,r)}CONSUME5(e,r){return this.consumeInternal(e,5,r)}CONSUME6(e,r){return this.consumeInternal(e,6,r)}CONSUME7(e,r){return this.consumeInternal(e,7,r)}CONSUME8(e,r){return this.consumeInternal(e,8,r)}CONSUME9(e,r){return this.consumeInternal(e,9,r)}SUBRULE(e,r){return this.subruleInternal(e,0,r)}SUBRULE1(e,r){return this.subruleInternal(e,1,r)}SUBRULE2(e,r){return this.subruleInternal(e,2,r)}SUBRULE3(e,r){return this.subruleInternal(e,3,r)}SUBRULE4(e,r){return this.subruleInternal(e,4,r)}SUBRULE5(e,r){return this.subruleInternal(e,5,r)}SUBRULE6(e,r){return this.subruleInternal(e,6,r)}SUBRULE7(e,r){return this.subruleInternal(e,7,r)}SUBRULE8(e,r){return this.subruleInternal(e,8,r)}SUBRULE9(e,r){return this.subruleInternal(e,9,r)}OPTION(e){return this.optionInternal(e,0)}OPTION1(e){return this.optionInternal(e,1)}OPTION2(e){return this.optionInternal(e,2)}OPTION3(e){return this.optionInternal(e,3)}OPTION4(e){return this.optionInternal(e,4)}OPTION5(e){return this.optionInternal(e,5)}OPTION6(e){return this.optionInternal(e,6)}OPTION7(e){return this.optionInternal(e,7)}OPTION8(e){return this.optionInternal(e,8)}OPTION9(e){return this.optionInternal(e,9)}OR(e){return this.orInternal(e,0)}OR1(e){return this.orInternal(e,1)}OR2(e){return this.orInternal(e,2)}OR3(e){return this.orInternal(e,3)}OR4(e){return this.orInternal(e,4)}OR5(e){return this.orInternal(e,5)}OR6(e){return this.orInternal(e,6)}OR7(e){return this.orInternal(e,7)}OR8(e){return this.orInternal(e,8)}OR9(e){return this.orInternal(e,9)}MANY(e){this.manyInternal(0,e)}MANY1(e){this.manyInternal(1,e)}MANY2(e){this.manyInternal(2,e)}MANY3(e){this.manyInternal(3,e)}MANY4(e){this.manyInternal(4,e)}MANY5(e){this.manyInternal(5,e)}MANY6(e){this.manyInternal(6,e)}MANY7(e){this.manyInternal(7,e)}MANY8(e){this.manyInternal(8,e)}MANY9(e){this.manyInternal(9,e)}MANY_SEP(e){this.manySepFirstInternal(0,e)}MANY_SEP1(e){this.manySepFirstInternal(1,e)}MANY_SEP2(e){this.manySepFirstInternal(2,e)}MANY_SEP3(e){this.manySepFirstInternal(3,e)}MANY_SEP4(e){this.manySepFirstInternal(4,e)}MANY_SEP5(e){this.manySepFirstInternal(5,e)}MANY_SEP6(e){this.manySepFirstInternal(6,e)}MANY_SEP7(e){this.manySepFirstInternal(7,e)}MANY_SEP8(e){this.manySepFirstInternal(8,e)}MANY_SEP9(e){this.manySepFirstInternal(9,e)}AT_LEAST_ONE(e){this.atLeastOneInternal(0,e)}AT_LEAST_ONE1(e){return this.atLeastOneInternal(1,e)}AT_LEAST_ONE2(e){this.atLeastOneInternal(2,e)}AT_LEAST_ONE3(e){this.atLeastOneInternal(3,e)}AT_LEAST_ONE4(e){this.atLeastOneInternal(4,e)}AT_LEAST_ONE5(e){this.atLeastOneInternal(5,e)}AT_LEAST_ONE6(e){this.atLeastOneInternal(6,e)}AT_LEAST_ONE7(e){this.atLeastOneInternal(7,e)}AT_LEAST_ONE8(e){this.atLeastOneInternal(8,e)}AT_LEAST_ONE9(e){this.atLeastOneInternal(9,e)}AT_LEAST_ONE_SEP(e){this.atLeastOneSepFirstInternal(0,e)}AT_LEAST_ONE_SEP1(e){this.atLeastOneSepFirstInternal(1,e)}AT_LEAST_ONE_SEP2(e){this.atLeastOneSepFirstInternal(2,e)}AT_LEAST_ONE_SEP3(e){this.atLeastOneSepFirstInternal(3,e)}AT_LEAST_ONE_SEP4(e){this.atLeastOneSepFirstInternal(4,e)}AT_LEAST_ONE_SEP5(e){this.atLeastOneSepFirstInternal(5,e)}AT_LEAST_ONE_SEP6(e){this.atLeastOneSepFirstInternal(6,e)}AT_LEAST_ONE_SEP7(e){this.atLeastOneSepFirstInternal(7,e)}AT_LEAST_ONE_SEP8(e){this.atLeastOneSepFirstInternal(8,e)}AT_LEAST_ONE_SEP9(e){this.atLeastOneSepFirstInternal(9,e)}RULE(e,r,n=Kg){if(qn(this.definedRulesNames,e)){let s={message:Pl.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),type:zi.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);let i=this.defineRule(e,r,n);return this[e]=i,i}OVERRIDE_RULE(e,r,n=Kg){let i=Sse(e,this.definedRulesNames,this.className);this.definitionErrors=this.definitionErrors.concat(i);let a=this.defineRule(e,r,n);return this[e]=a,a}BACKTRACK(e,r){return function(){this.isBackTrackingStack.push(1);let n=this.saveRecogState();try{return e.apply(this,r),!0}catch(i){if(lf(i))return!1;throw i}finally{this.reloadRecogState(n),this.isBackTrackingStack.pop()}}}getGAstProductions(){return this.gastProductionsCache}getSerializedGastProductions(){return Sk(br(this.gastProductionsCache))}}});var tE,Xse=N(()=>{"use strict";qt();qk();Xg();qg();cx();Fs();GN();up();cp();tE=class{static{o(this,"RecognizerEngine")}initRecognizerEngine(e,r){if(this.className=this.constructor.name,this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=zg,this.subruleIdx=0,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},Bt(r,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a <serializedGrammar> property.
+ See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0
+ For Further details.`);if(Pt(e)){if(ur(e))throw Error(`A Token Vocabulary cannot be empty.
+ Note that the first argument for the parser constructor
+ is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument.
+ See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0
+ For Further details.`)}if(Pt(e))this.tokensMap=Xr(e,(a,s)=>(a[s.name]=s,a),{});else if(Bt(e,"modes")&&Ma(qr(br(e.modes)),rse)){let a=qr(br(e.modes)),s=Bm(a);this.tokensMap=Xr(s,(l,u)=>(l[u.name]=u,l),{})}else if(bn(e))this.tokensMap=an(e);else throw new Error("<tokensDictionary> argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=lo;let n=Bt(e,"modes")?qr(br(e.modes)):br(e),i=Ma(n,a=>ur(a.categoryMatches));this.tokenMatcher=i?zg:Pu,Bu(br(this.tokensMap))}defineRule(e,r,n){if(this.selfAnalysisDone)throw Error(`Grammar rule <${e}> may not be defined after the 'performSelfAnalysis' method has been called'
+Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);let i=Bt(n,"resyncEnabled")?n.resyncEnabled:Kg.resyncEnabled,a=Bt(n,"recoveryValueFunc")?n.recoveryValueFunc:Kg.recoveryValueFunc,s=this.ruleShortNameIdx<<12;this.ruleShortNameIdx++,this.shortRuleNameToFull[s]=e,this.fullRuleNameToShort[e]=s;let l;return this.outputCst===!0?l=o(function(...f){try{this.ruleInvocationStateUpdate(s,e,this.subruleIdx),r.apply(this,f);let d=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(d),d}catch(d){return this.invokeRuleCatch(d,i,a)}finally{this.ruleFinallyStateUpdate()}},"invokeRuleWithTry"):l=o(function(...f){try{return this.ruleInvocationStateUpdate(s,e,this.subruleIdx),r.apply(this,f)}catch(d){return this.invokeRuleCatch(d,i,a)}finally{this.ruleFinallyStateUpdate()}},"invokeRuleWithTryCst"),Object.assign(l,{ruleName:e,originalGrammarAction:r})}invokeRuleCatch(e,r,n){let i=this.RULE_STACK.length===1,a=r&&!this.isBackTracking()&&this.recoveryEnabled;if(lf(e)){let s=e;if(a){let l=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(l))if(s.resyncedTokens=this.reSyncTo(l),this.outputCst){let u=this.CST_STACK[this.CST_STACK.length-1];return u.recoveredNode=!0,u}else return n(e);else{if(this.outputCst){let u=this.CST_STACK[this.CST_STACK.length-1];u.recoveredNode=!0,s.partialCstResult=u}throw s}}else{if(i)return this.moveToTerminatedState(),n(e);throw s}}else throw e}optionInternal(e,r){let n=this.getKeyForAutomaticLookahead(512,r);return this.optionInternalLogic(e,r,n)}optionInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof e!="function"){a=e.DEF;let s=e.GATE;if(s!==void 0){let l=i;i=o(()=>s.call(this)&&l.call(this),"lookAheadFunc")}}else a=e;if(i.call(this)===!0)return a.call(this)}atLeastOneInternal(e,r){let n=this.getKeyForAutomaticLookahead(1024,e);return this.atLeastOneInternalLogic(e,r,n)}atLeastOneInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof r!="function"){a=r.DEF;let s=r.GATE;if(s!==void 0){let l=i;i=o(()=>s.call(this)&&l.call(this),"lookAheadFunc")}}else a=r;if(i.call(this)===!0){let s=this.doSingleRepetition(a);for(;i.call(this)===!0&&s===!0;)s=this.doSingleRepetition(a)}else throw this.raiseEarlyExitException(e,jn.REPETITION_MANDATORY,r.ERR_MSG);this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,r],i,1024,e,Bk)}atLeastOneSepFirstInternal(e,r){let n=this.getKeyForAutomaticLookahead(1536,e);this.atLeastOneSepFirstInternalLogic(e,r,n)}atLeastOneSepFirstInternalLogic(e,r,n){let i=r.DEF,a=r.SEP;if(this.getLaFuncFromCache(n).call(this)===!0){i.call(this);let l=o(()=>this.tokenMatcher(this.LA(1),a),"separatorLookAheadFunc");for(;this.tokenMatcher(this.LA(1),a)===!0;)this.CONSUME(a),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,a,l,i,lx],l,1536,e,lx)}else throw this.raiseEarlyExitException(e,jn.REPETITION_MANDATORY_WITH_SEPARATOR,r.ERR_MSG)}manyInternal(e,r){let n=this.getKeyForAutomaticLookahead(768,e);return this.manyInternalLogic(e,r,n)}manyInternalLogic(e,r,n){let i=this.getLaFuncFromCache(n),a;if(typeof r!="function"){a=r.DEF;let l=r.GATE;if(l!==void 0){let u=i;i=o(()=>l.call(this)&&u.call(this),"lookaheadFunction")}}else a=r;let s=!0;for(;i.call(this)===!0&&s===!0;)s=this.doSingleRepetition(a);this.attemptInRepetitionRecovery(this.manyInternal,[e,r],i,768,e,Pk,s)}manySepFirstInternal(e,r){let n=this.getKeyForAutomaticLookahead(1280,e);this.manySepFirstInternalLogic(e,r,n)}manySepFirstInternalLogic(e,r,n){let i=r.DEF,a=r.SEP;if(this.getLaFuncFromCache(n).call(this)===!0){i.call(this);let l=o(()=>this.tokenMatcher(this.LA(1),a),"separatorLookAheadFunc");for(;this.tokenMatcher(this.LA(1),a)===!0;)this.CONSUME(a),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,a,l,i,ox],l,1280,e,ox)}}repetitionSepSecondInternal(e,r,n,i,a){for(;n();)this.CONSUME(r),i.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,r,n,i,a],n,1536,e,a)}doSingleRepetition(e){let r=this.getLexerPosition();return e.call(this),this.getLexerPosition()>r}orInternal(e,r){let n=this.getKeyForAutomaticLookahead(256,r),i=Pt(e)?e:e.DEF,s=this.getLaFuncFromCache(n).call(this,i);if(s!==void 0)return i[s].ALT.call(this);this.raiseNoAltException(r,e.ERR_MSG)}ruleFinallyStateUpdate(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){let e=this.LA(1),r=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new px(r,e))}}subruleInternal(e,r,n){let i;try{let a=n!==void 0?n.ARGS:void 0;return this.subruleIdx=r,i=e.apply(this,a),this.cstPostNonTerminal(i,n!==void 0&&n.LABEL!==void 0?n.LABEL:e.ruleName),i}catch(a){throw this.subruleInternalError(a,n,e.ruleName)}}subruleInternalError(e,r,n){throw lf(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,r!==void 0&&r.LABEL!==void 0?r.LABEL:n),delete e.partialCstResult),e}consumeInternal(e,r,n){let i;try{let a=this.LA(1);this.tokenMatcher(a,e)===!0?(this.consumeToken(),i=a):this.consumeInternalError(e,a,n)}catch(a){i=this.consumeInternalRecovery(e,r,a)}return this.cstPostTerminal(n!==void 0&&n.LABEL!==void 0?n.LABEL:e.name,i),i}consumeInternalError(e,r,n){let i,a=this.LA(0);throw n!==void 0&&n.ERR_MSG?i=n.ERR_MSG:i=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:r,previous:a,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new hp(i,r,a))}consumeInternalRecovery(e,r,n){if(this.recoveryEnabled&&n.name==="MismatchedTokenException"&&!this.isBackTracking()){let i=this.getFollowsForInRuleRecovery(e,r);try{return this.tryInRuleRecovery(e,i)}catch(a){throw a.name===zN?n:a}}else throw n}saveRecogState(){let e=this.errors,r=an(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:r,CST_STACK:this.CST_STACK}}reloadRecogState(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK}ruleInvocationStateUpdate(e,r,n){this.RULE_OCCURRENCE_STACK.push(n),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(r)}isBackTracking(){return this.isBackTrackingStack.length!==0}getCurrRuleFullName(){let e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]}shortRuleNameToFullName(e){return this.shortRuleNameToFull[e]}isAtEndOfInput(){return this.tokenMatcher(this.LA(1),lo)}reset(){this.resetLexerState(),this.subruleIdx=0,this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]}}});var rE,jse=N(()=>{"use strict";Xg();qt();qg();Fs();rE=class{static{o(this,"ErrorHandler")}initErrorHandler(e){this._errors=[],this.errorMessageProvider=Bt(e,"errorMessageProvider")?e.errorMessageProvider:ls.errorMessageProvider}SAVE_ERROR(e){if(lf(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:an(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")}get errors(){return an(this._errors)}set errors(e){this._errors=e}raiseEarlyExitException(e,r,n){let i=this.getCurrRuleFullName(),a=this.getGAstProductions()[i],l=Wg(e,a,r,this.maxLookahead)[0],u=[];for(let f=1;f<=this.maxLookahead;f++)u.push(this.LA(f));let h=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:l,actual:u,previous:this.LA(0),customUserDescription:n,ruleName:i});throw this.SAVE_ERROR(new mx(h,this.LA(1),this.LA(0)))}raiseNoAltException(e,r){let n=this.getCurrRuleFullName(),i=this.getGAstProductions()[n],a=Hg(e,i,this.maxLookahead),s=[];for(let h=1;h<=this.maxLookahead;h++)s.push(this.LA(h));let l=this.LA(0),u=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:a,actual:s,previous:l,customUserDescription:r,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new dx(u,this.LA(1),l))}}});var nE,Kse=N(()=>{"use strict";cx();qt();nE=class{static{o(this,"ContentAssist")}initContentAssist(){}computeContentAssist(e,r){let n=this.gastProductionsCache[e];if(pr(n))throw Error(`Rule ->${e}<- does not exist in this grammar.`);return $k([n],r,this.tokenMatcher,this.maxLookahead)}getNextPossibleTokenTypes(e){let r=ia(e.ruleStack),i=this.getGAstProductions()[r];return new Ok(i,e).startWalking()}}});function yx(t,e,r,n=!1){aE(r);let i=ga(this.recordingProdStack),a=Si(e)?e:e.DEF,s=new t({definition:[],idx:r});return n&&(s.separator=e.SEP),Bt(e,"MAX_LOOKAHEAD")&&(s.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(s),a.call(this),i.definition.push(s),this.recordingProdStack.pop(),sE}function dBe(t,e){aE(e);let r=ga(this.recordingProdStack),n=Pt(t)===!1,i=n===!1?t:t.DEF,a=new Tn({definition:[],idx:e,ignoreAmbiguities:n&&t.IGNORE_AMBIGUITIES===!0});Bt(t,"MAX_LOOKAHEAD")&&(a.maxLookahead=t.MAX_LOOKAHEAD);let s=A2(i,l=>Si(l.GATE));return a.hasPredicates=s,r.definition.push(a),Ae(i,l=>{let u=new Dn({definition:[]});a.definition.push(u),Bt(l,"IGNORE_AMBIGUITIES")?u.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:Bt(l,"GATE")&&(u.ignoreAmbiguities=!0),this.recordingProdStack.push(u),l.ALT.call(this),this.recordingProdStack.pop()}),sE}function Jse(t){return t===0?"":`${t}`}function aE(t){if(t<0||t>Zse){let e=new Error(`Invalid DSL Method idx value: <${t}>
+ Idx value must be a none negative value smaller than ${Zse+1}`);throw e.KNOWN_RECORDER_ERROR=!0,e}}var sE,Qse,Zse,eoe,toe,fBe,iE,roe=N(()=>{"use strict";qt();os();ix();cp();up();Fs();qk();sE={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(sE);Qse=!0,Zse=Math.pow(2,8)-1,eoe=of({name:"RECORDING_PHASE_TOKEN",pattern:Xn.NA});Bu([eoe]);toe=$u(eoe,`This IToken indicates the Parser is in Recording Phase
+ See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(toe);fBe={name:`This CSTNode indicates the Parser is in Recording Phase
+ See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},iE=class{static{o(this,"GastRecorder")}initGastRecorder(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1}enableRecording(){this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",()=>{for(let e=0;e<10;e++){let r=e>0?e:"";this[`CONSUME${r}`]=function(n,i){return this.consumeInternalRecord(n,e,i)},this[`SUBRULE${r}`]=function(n,i){return this.subruleInternalRecord(n,e,i)},this[`OPTION${r}`]=function(n){return this.optionInternalRecord(n,e)},this[`OR${r}`]=function(n){return this.orInternalRecord(n,e)},this[`MANY${r}`]=function(n){this.manyInternalRecord(e,n)},this[`MANY_SEP${r}`]=function(n){this.manySepFirstInternalRecord(e,n)},this[`AT_LEAST_ONE${r}`]=function(n){this.atLeastOneInternalRecord(e,n)},this[`AT_LEAST_ONE_SEP${r}`]=function(n){this.atLeastOneSepFirstInternalRecord(e,n)}}this.consume=function(e,r,n){return this.consumeInternalRecord(r,e,n)},this.subrule=function(e,r,n){return this.subruleInternalRecord(r,e,n)},this.option=function(e,r){return this.optionInternalRecord(r,e)},this.or=function(e,r){return this.orInternalRecord(r,e)},this.many=function(e,r){this.manyInternalRecord(e,r)},this.atLeastOne=function(e,r){this.atLeastOneInternalRecord(e,r)},this.ACTION=this.ACTION_RECORD,this.BACKTRACK=this.BACKTRACK_RECORD,this.LA=this.LA_RECORD})}disableRecording(){this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",()=>{let e=this;for(let r=0;r<10;r++){let n=r>0?r:"";delete e[`CONSUME${n}`],delete e[`SUBRULE${n}`],delete e[`OPTION${n}`],delete e[`OR${n}`],delete e[`MANY${n}`],delete e[`MANY_SEP${n}`],delete e[`AT_LEAST_ONE${n}`],delete e[`AT_LEAST_ONE_SEP${n}`]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})}ACTION_RECORD(e){}BACKTRACK_RECORD(e,r){return()=>!0}LA_RECORD(e){return jg}topLevelRuleRecord(e,r){try{let n=new as({definition:[],name:e});return n.name=e,this.recordingProdStack.push(n),r.call(this),this.recordingProdStack.pop(),n}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+`
+ This error was thrown during the "grammar recording phase" For more info see:
+ https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}}optionInternalRecord(e,r){return yx.call(this,ln,e,r)}atLeastOneInternalRecord(e,r){yx.call(this,Ln,r,e)}atLeastOneSepFirstInternalRecord(e,r){yx.call(this,Rn,r,e,Qse)}manyInternalRecord(e,r){yx.call(this,Or,r,e)}manySepFirstInternalRecord(e,r){yx.call(this,wn,r,e,Qse)}orInternalRecord(e,r){return dBe.call(this,e,r)}subruleInternalRecord(e,r,n){if(aE(r),!e||Bt(e,"ruleName")===!1){let l=new Error(`<SUBRULE${Jse(r)}> argument is invalid expecting a Parser method reference but got: <${JSON.stringify(e)}>
+ inside top level rule: <${this.recordingProdStack[0].name}>`);throw l.KNOWN_RECORDER_ERROR=!0,l}let i=ga(this.recordingProdStack),a=e.ruleName,s=new on({idx:r,nonTerminalName:a,label:n?.LABEL,referencedRule:void 0});return i.definition.push(s),this.outputCst?fBe:sE}consumeInternalRecord(e,r,n){if(aE(r),!_N(e)){let s=new Error(`<CONSUME${Jse(r)}> argument is invalid expecting a TokenType reference but got: <${JSON.stringify(e)}>
+ inside top level rule: <${this.recordingProdStack[0].name}>`);throw s.KNOWN_RECORDER_ERROR=!0,s}let i=ga(this.recordingProdStack),a=new kr({idx:r,terminalType:e,label:n?.LABEL});return i.definition.push(a),toe}};o(yx,"recordProd");o(dBe,"recordOrProd");o(Jse,"getIdxSuffix");o(aE,"assertMethodIdxIsValid")});var oE,noe=N(()=>{"use strict";qt();Og();Fs();oE=class{static{o(this,"PerformanceTracer")}initPerformanceTracer(e){if(Bt(e,"traceInitPerf")){let r=e.traceInitPerf,n=typeof r=="number";this.traceInitMaxIdent=n?r:1/0,this.traceInitPerf=n?r>0:r}else this.traceInitMaxIdent=0,this.traceInitPerf=ls.traceInitPerf;this.traceInitIndent=-1}TRACE_INIT(e,r){if(this.traceInitPerf===!0){this.traceInitIndent++;let n=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent<this.traceInitMaxIdent&&console.log(`${n}--> <${e}>`);let{time:i,value:a}=tx(r),s=i>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&s(`${n}<-- <${e}> time: ${i}ms`),this.traceInitIndent--,a}else return r()}}});function ioe(t,e){e.forEach(r=>{let n=r.prototype;Object.getOwnPropertyNames(n).forEach(i=>{if(i==="constructor")return;let a=Object.getOwnPropertyDescriptor(n,i);a&&(a.get||a.set)?Object.defineProperty(t.prototype,i,a):t.prototype[i]=r.prototype[i]})})}var aoe=N(()=>{"use strict";o(ioe,"applyMixins")});function lE(t=void 0){return function(){return t}}var jg,ls,Kg,zi,vx,xx,Fs=N(()=>{"use strict";qt();Og();Oae();up();Vg();Rse();GN();Bse();Wse();qse();Yse();Xse();jse();Kse();roe();noe();aoe();fx();jg=$u(lo,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(jg);ls=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:zu,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1}),Kg=Object.freeze({recoveryValueFunc:o(()=>{},"recoveryValueFunc"),resyncEnabled:!0});(function(t){t[t.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",t[t.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",t[t.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",t[t.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",t[t.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",t[t.LEFT_RECURSION=5]="LEFT_RECURSION",t[t.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",t[t.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",t[t.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",t[t.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",t[t.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",t[t.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",t[t.TOO_MANY_ALTS=12]="TOO_MANY_ALTS",t[t.CUSTOM_LOOKAHEAD_VALIDATION=13]="CUSTOM_LOOKAHEAD_VALIDATION"})(zi||(zi={}));o(lE,"EMPTY_ALT");vx=class t{static{o(this,"Parser")}static performSelfAnalysis(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")}performSelfAnalysis(){this.TRACE_INIT("performSelfAnalysis",()=>{let e;this.selfAnalysisDone=!0;let r=this.className;this.TRACE_INIT("toFastProps",()=>{rx(this)}),this.TRACE_INIT("Grammar Recording",()=>{try{this.enableRecording(),Ae(this.definedRulesNames,i=>{let s=this[i].originalGrammarAction,l;this.TRACE_INIT(`${i} Rule`,()=>{l=this.topLevelRuleRecord(i,s)}),this.gastProductionsCache[i]=l})}finally{this.disableRecording()}});let n=[];if(this.TRACE_INIT("Grammar Resolving",()=>{n=Dse({rules:br(this.gastProductionsCache)}),this.definitionErrors=this.definitionErrors.concat(n)}),this.TRACE_INIT("Grammar Validations",()=>{if(ur(n)&&this.skipValidations===!1){let i=Lse({rules:br(this.gastProductionsCache),tokenTypes:br(this.tokensMap),errMsgProvider:Pl,grammarName:r}),a=Tse({lookaheadStrategy:this.lookaheadStrategy,rules:br(this.gastProductionsCache),tokenTypes:br(this.tokensMap),grammarName:r});this.definitionErrors=this.definitionErrors.concat(i,a)}}),ur(this.definitionErrors)&&(this.recoveryEnabled&&this.TRACE_INIT("computeAllProdsFollows",()=>{let i=Iae(br(this.gastProductionsCache));this.resyncFollows=i}),this.TRACE_INIT("ComputeLookaheadFunctions",()=>{var i,a;(a=(i=this.lookaheadStrategy).initialize)===null||a===void 0||a.call(i,{rules:br(this.gastProductionsCache)}),this.preComputeLookaheadFunctions(br(this.gastProductionsCache))})),!t.DEFER_DEFINITION_ERRORS_HANDLING&&!ur(this.definitionErrors))throw e=Je(this.definitionErrors,i=>i.message),new Error(`Parser Definition Errors detected:
+ ${e.join(`
+-------------------------------
+`)}`)})}constructor(e,r){this.definitionErrors=[],this.selfAnalysisDone=!1;let n=this;if(n.initErrorHandler(r),n.initLexerAdapter(),n.initLooksAhead(r),n.initRecognizerEngine(e,r),n.initRecoverable(r),n.initTreeBuilder(r),n.initContentAssist(),n.initGastRecorder(r),n.initPerformanceTracer(r),Bt(r,"ignoredIssues"))throw new Error(`The <ignoredIssues> IParserConfig property has been deprecated.
+ Please use the <IGNORE_AMBIGUITIES> flag on the relevant DSL method instead.
+ See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES
+ For further details.`);this.skipValidations=Bt(r,"skipValidations")?r.skipValidations:ls.skipValidations}};vx.DEFER_DEFINITION_ERRORS_HANDLING=!1;ioe(vx,[Hk,Xk,Zk,Jk,tE,eE,rE,nE,iE,oE]);xx=class extends vx{static{o(this,"EmbeddedActionsParser")}constructor(e,r=ls){let n=an(r);n.outputCst=!1,super(e,n)}}});var soe=N(()=>{"use strict";os()});var ooe=N(()=>{"use strict"});var loe=N(()=>{"use strict";soe();ooe()});var coe=N(()=>{"use strict";gN()});var cf=N(()=>{"use strict";gN();Fs();ix();up();qg();VN();Vg();Xg();DN();os();os();loe();coe()});function fp(t,e,r){return`${t.name}_${e}_${r}`}function doe(t){let e={decisionMap:{},decisionStates:[],ruleToStartState:new Map,ruleToStopState:new Map,states:[]};bBe(e,t);let r=t.length;for(let n=0;n<r;n++){let i=t[n],a=dp(e,i,i);a!==void 0&&RBe(e,i,a)}return e}function bBe(t,e){let r=e.length;for(let n=0;n<r;n++){let i=e[n],a=aa(t,i,void 0,{type:mBe}),s=aa(t,i,void 0,{type:Jg});a.stop=s,t.ruleToStartState.set(i,a),t.ruleToStopState.set(i,s)}}function poe(t,e,r){return r instanceof kr?QN(t,e,r.terminalType,r):r instanceof on?LBe(t,e,r):r instanceof Tn?SBe(t,e,r):r instanceof ln?CBe(t,e,r):r instanceof Or?wBe(t,e,r):r instanceof wn?TBe(t,e,r):r instanceof Ln?kBe(t,e,r):r instanceof Rn?EBe(t,e,r):dp(t,e,r)}function wBe(t,e,r){let n=aa(t,e,r,{type:hoe});hf(t,n);let i=e1(t,e,n,r,dp(t,e,r));return goe(t,e,r,i)}function TBe(t,e,r){let n=aa(t,e,r,{type:hoe});hf(t,n);let i=e1(t,e,n,r,dp(t,e,r)),a=QN(t,e,r.separator,r);return goe(t,e,r,i,a)}function kBe(t,e,r){let n=aa(t,e,r,{type:uoe});hf(t,n);let i=e1(t,e,n,r,dp(t,e,r));return moe(t,e,r,i)}function EBe(t,e,r){let n=aa(t,e,r,{type:uoe});hf(t,n);let i=e1(t,e,n,r,dp(t,e,r)),a=QN(t,e,r.separator,r);return moe(t,e,r,i,a)}function SBe(t,e,r){let n=aa(t,e,r,{type:uf});hf(t,n);let i=Je(r.definition,s=>poe(t,e,s));return e1(t,e,n,r,...i)}function CBe(t,e,r){let n=aa(t,e,r,{type:uf});hf(t,n);let i=e1(t,e,n,r,dp(t,e,r));return ABe(t,e,r,i)}function dp(t,e,r){let n=Yr(Je(r.definition,i=>poe(t,e,i)),i=>i!==void 0);return n.length===1?n[0]:n.length===0?void 0:DBe(t,n)}function moe(t,e,r,n,i){let a=n.left,s=n.right,l=aa(t,e,r,{type:xBe});hf(t,l);let u=aa(t,e,r,{type:foe});return a.loopback=l,u.loopback=l,t.decisionMap[fp(e,i?"RepetitionMandatoryWithSeparator":"RepetitionMandatory",r.idx)]=l,Ai(s,l),i===void 0?(Ai(l,a),Ai(l,u)):(Ai(l,u),Ai(l,i.left),Ai(i.right,a)),{left:a,right:u}}function goe(t,e,r,n,i){let a=n.left,s=n.right,l=aa(t,e,r,{type:vBe});hf(t,l);let u=aa(t,e,r,{type:foe}),h=aa(t,e,r,{type:yBe});return l.loopback=h,u.loopback=h,Ai(l,a),Ai(l,u),Ai(s,h),i!==void 0?(Ai(h,u),Ai(h,i.left),Ai(i.right,a)):Ai(h,l),t.decisionMap[fp(e,i?"RepetitionWithSeparator":"Repetition",r.idx)]=l,{left:l,right:u}}function ABe(t,e,r,n){let i=n.left,a=n.right;return Ai(i,a),t.decisionMap[fp(e,"Option",r.idx)]=i,n}function hf(t,e){return t.decisionStates.push(e),e.decision=t.decisionStates.length-1,e.decision}function e1(t,e,r,n,...i){let a=aa(t,e,n,{type:gBe,start:r});r.end=a;for(let l of i)l!==void 0?(Ai(r,l.left),Ai(l.right,a)):Ai(r,a);let s={left:r,right:a};return t.decisionMap[fp(e,_Be(n),n.idx)]=r,s}function _Be(t){if(t instanceof Tn)return"Alternation";if(t instanceof ln)return"Option";if(t instanceof Or)return"Repetition";if(t instanceof wn)return"RepetitionWithSeparator";if(t instanceof Ln)return"RepetitionMandatory";if(t instanceof Rn)return"RepetitionMandatoryWithSeparator";throw new Error("Invalid production type encountered")}function DBe(t,e){let r=e.length;for(let a=0;a<r-1;a++){let s=e[a],l;s.left.transitions.length===1&&(l=s.left.transitions[0]);let u=l instanceof Zg,h=l,f=e[a+1].left;s.left.type===uf&&s.right.type===uf&&l!==void 0&&(u&&h.followState===s.right||l.target===s.right)?(u?h.followState=f:l.target=f,NBe(t,s.right)):Ai(s.right,f)}let n=e[0],i=e[r-1];return{left:n.left,right:i.right}}function QN(t,e,r,n){let i=aa(t,e,n,{type:uf}),a=aa(t,e,n,{type:uf});return ZN(i,new Qg(a,r)),{left:i,right:a}}function LBe(t,e,r){let n=r.referencedRule,i=t.ruleToStartState.get(n),a=aa(t,e,r,{type:uf}),s=aa(t,e,r,{type:uf}),l=new Zg(i,n,s);return ZN(a,l),{left:a,right:s}}function RBe(t,e,r){let n=t.ruleToStartState.get(e);Ai(n,r.left);let i=t.ruleToStopState.get(e);return Ai(r.right,i),{left:n,right:i}}function Ai(t,e){let r=new wx(e);ZN(t,r)}function aa(t,e,r,n){let i=Object.assign({atn:t,production:r,epsilonOnlyTransitions:!1,rule:e,transitions:[],nextTokenWithinRule:[],stateNumber:t.states.length},n);return t.states.push(i),i}function ZN(t,e){t.transitions.length===0&&(t.epsilonOnlyTransitions=e.isEpsilon()),t.transitions.push(e)}function NBe(t,e){t.states.splice(t.states.indexOf(e),1)}var uf,mBe,uoe,hoe,Jg,gBe,yBe,vBe,xBe,foe,bx,Qg,wx,Zg,yoe=N(()=>{"use strict";Im();DL();cf();o(fp,"buildATNKey");uf=1,mBe=2,uoe=4,hoe=5,Jg=7,gBe=8,yBe=9,vBe=10,xBe=11,foe=12,bx=class{static{o(this,"AbstractTransition")}constructor(e){this.target=e}isEpsilon(){return!1}},Qg=class extends bx{static{o(this,"AtomTransition")}constructor(e,r){super(e),this.tokenType=r}},wx=class extends bx{static{o(this,"EpsilonTransition")}constructor(e){super(e)}isEpsilon(){return!0}},Zg=class extends bx{static{o(this,"RuleTransition")}constructor(e,r,n){super(e),this.rule=r,this.followState=n}isEpsilon(){return!0}};o(doe,"createATN");o(bBe,"createRuleStartAndStopATNStates");o(poe,"atom");o(wBe,"repetition");o(TBe,"repetitionSep");o(kBe,"repetitionMandatory");o(EBe,"repetitionMandatorySep");o(SBe,"alternation");o(CBe,"option");o(dp,"block");o(moe,"plus");o(goe,"star");o(ABe,"optional");o(hf,"defineDecisionState");o(e1,"makeAlts");o(_Be,"getProdType");o(DBe,"makeBlock");o(QN,"tokenRef");o(LBe,"ruleRef");o(RBe,"buildRuleHandle");o(Ai,"epsilon");o(aa,"newState");o(ZN,"addTransition");o(NBe,"removeState")});function JN(t,e=!0){return`${e?`a${t.alt}`:""}s${t.state.stateNumber}:${t.stack.map(r=>r.stateNumber.toString()).join("_")}`}var Tx,t1,voe=N(()=>{"use strict";Im();Tx={},t1=class{static{o(this,"ATNConfigSet")}constructor(){this.map={},this.configs=[]}get size(){return this.configs.length}finalize(){this.map={}}add(e){let r=JN(e);r in this.map||(this.map[r]=this.configs.length,this.configs.push(e))}get elements(){return this.configs}get alts(){return Je(this.configs,e=>e.alt)}get key(){let e="";for(let r in this.map)e+=r+":";return e}};o(JN,"getATNConfigKey")});function MBe(t,e){let r={};return n=>{let i=n.toString(),a=r[i];return a!==void 0||(a={atnStartState:t,decision:e,states:{}},r[i]=a),a}}function boe(t,e=!0){let r=new Set;for(let n of t){let i=new Set;for(let a of n){if(a===void 0){if(e)break;return!1}let s=[a.tokenTypeIdx].concat(a.categoryMatches);for(let l of s)if(r.has(l)){if(!i.has(l))return!1}else r.add(l),i.add(l)}}return!0}function IBe(t){let e=t.decisionStates.length,r=Array(e);for(let n=0;n<e;n++)r[n]=MBe(t.decisionStates[n],n);return r}function eM(t,e,r,n){let i=t[e](r),a=i.start;if(a===void 0){let l=WBe(i.atnStartState);a=koe(i,Toe(l)),i.start=a}return OBe.apply(this,[i,a,r,n])}function OBe(t,e,r,n){let i=e,a=1,s=[],l=this.LA(a++);for(;;){let u=GBe(i,l);if(u===void 0&&(u=PBe.apply(this,[t,i,l,a,r,n])),u===Tx)return zBe(s,i,l);if(u.isAcceptState===!0)return u.prediction;i=u,s.push(l),l=this.LA(a++)}}function PBe(t,e,r,n,i,a){let s=VBe(e.configs,r,i);if(s.size===0)return woe(t,e,r,Tx),Tx;let l=Toe(s),u=HBe(s,i);if(u!==void 0)l.isAcceptState=!0,l.prediction=u,l.configs.uniqueAlt=u;else if(jBe(s)){let h=Dl(s.alts);l.isAcceptState=!0,l.prediction=h,l.configs.uniqueAlt=h,BBe.apply(this,[t,n,s.alts,a])}return l=woe(t,e,r,l),l}function BBe(t,e,r,n){let i=[];for(let h=1;h<=e;h++)i.push(this.LA(h).tokenType);let a=t.atnStartState,s=a.rule,l=a.production,u=FBe({topLevelRule:s,ambiguityIndices:r,production:l,prefixPath:i});n(u)}function FBe(t){let e=Je(t.prefixPath,i=>Fu(i)).join(", "),r=t.production.idx===0?"":t.production.idx,n=`Ambiguous Alternatives Detected: <${t.ambiguityIndices.join(", ")}> in <${$Be(t.production)}${r}> inside <${t.topLevelRule.name}> Rule,
+<${e}> may appears as a prefix path in all these alternatives.
+`;return n=n+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
+For Further details.`,n}function $Be(t){if(t instanceof on)return"SUBRULE";if(t instanceof ln)return"OPTION";if(t instanceof Tn)return"OR";if(t instanceof Ln)return"AT_LEAST_ONE";if(t instanceof Rn)return"AT_LEAST_ONE_SEP";if(t instanceof wn)return"MANY_SEP";if(t instanceof Or)return"MANY";if(t instanceof kr)return"CONSUME";throw Error("non exhaustive match")}function zBe(t,e,r){let n=ya(e.configs.elements,a=>a.state.transitions),i=Qre(n.filter(a=>a instanceof Qg).map(a=>a.tokenType),a=>a.tokenTypeIdx);return{actualToken:r,possibleTokenTypes:i,tokenPath:t}}function GBe(t,e){return t.edges[e.tokenTypeIdx]}function VBe(t,e,r){let n=new t1,i=[];for(let s of t.elements){if(r.is(s.alt)===!1)continue;if(s.state.type===Jg){i.push(s);continue}let l=s.state.transitions.length;for(let u=0;u<l;u++){let h=s.state.transitions[u],f=UBe(h,e);f!==void 0&&n.add({state:f,alt:s.alt,stack:s.stack})}}let a;if(i.length===0&&n.size===1&&(a=n),a===void 0){a=new t1;for(let s of n.elements)uE(s,a)}if(i.length>0&&!YBe(a))for(let s of i)a.add(s);return a}function UBe(t,e){if(t instanceof Qg&&sx(e,t.tokenType))return t.target}function HBe(t,e){let r;for(let n of t.elements)if(e.is(n.alt)===!0){if(r===void 0)r=n.alt;else if(r!==n.alt)return}return r}function Toe(t){return{configs:t,edges:{},isAcceptState:!1,prediction:-1}}function woe(t,e,r,n){return n=koe(t,n),e.edges[r.tokenTypeIdx]=n,n}function koe(t,e){if(e===Tx)return e;let r=e.configs.key,n=t.states[r];return n!==void 0?n:(e.configs.finalize(),t.states[r]=e,e)}function WBe(t){let e=new t1,r=t.transitions.length;for(let n=0;n<r;n++){let a={state:t.transitions[n].target,alt:n,stack:[]};uE(a,e)}return e}function uE(t,e){let r=t.state;if(r.type===Jg){if(t.stack.length>0){let i=[...t.stack],s={state:i.pop(),alt:t.alt,stack:i};uE(s,e)}else e.add(t);return}r.epsilonOnlyTransitions||e.add(t);let n=r.transitions.length;for(let i=0;i<n;i++){let a=r.transitions[i],s=qBe(t,a);s!==void 0&&uE(s,e)}}function qBe(t,e){if(e instanceof wx)return{state:e.target,alt:t.alt,stack:t.stack};if(e instanceof Zg){let r=[...t.stack,e.followState];return{state:e.target,alt:t.alt,stack:r}}}function YBe(t){for(let e of t.elements)if(e.state.type===Jg)return!0;return!1}function XBe(t){for(let e of t.elements)if(e.state.type!==Jg)return!1;return!0}function jBe(t){if(XBe(t))return!0;let e=KBe(t.elements);return QBe(e)&&!ZBe(e)}function KBe(t){let e=new Map;for(let r of t){let n=JN(r,!1),i=e.get(n);i===void 0&&(i={},e.set(n,i)),i[r.alt]=!0}return e}function QBe(t){for(let e of Array.from(t.values()))if(Object.keys(e).length>1)return!0;return!1}function ZBe(t){for(let e of Array.from(t.values()))if(Object.keys(e).length===1)return!0;return!1}var cE,xoe,kx,Eoe=N(()=>{"use strict";cf();yoe();voe();BL();RL();Zre();Im();uT();$T();HT();GL();o(MBe,"createDFACache");cE=class{static{o(this,"PredicateSet")}constructor(){this.predicates=[]}is(e){return e>=this.predicates.length||this.predicates[e]}set(e,r){this.predicates[e]=r}toString(){let e="",r=this.predicates.length;for(let n=0;n<r;n++)e+=this.predicates[n]===!0?"1":"0";return e}},xoe=new cE,kx=class extends Gu{static{o(this,"LLStarLookaheadStrategy")}constructor(e){var r;super(),this.logging=(r=e?.logging)!==null&&r!==void 0?r:n=>console.log(n)}initialize(e){this.atn=doe(e.rules),this.dfas=IBe(this.atn)}validateAmbiguousAlternationAlternatives(){return[]}validateEmptyOrAlternatives(){return[]}buildLookaheadForAlternation(e){let{prodOccurrence:r,rule:n,hasPredicates:i,dynamicTokensEnabled:a}=e,s=this.dfas,l=this.logging,u=fp(n,"Alternation",r),f=this.atn.decisionMap[u].decision,d=Je(Gk({maxLookahead:1,occurrence:r,prodType:"Alternation",rule:n}),p=>Je(p,m=>m[0]));if(boe(d,!1)&&!a){let p=Xr(d,(m,g,y)=>(Ae(g,v=>{v&&(m[v.tokenTypeIdx]=y,Ae(v.categoryMatches,x=>{m[x]=y}))}),m),{});return i?function(m){var g;let y=this.LA(1),v=p[y.tokenTypeIdx];if(m!==void 0&&v!==void 0){let x=(g=m[v])===null||g===void 0?void 0:g.GATE;if(x!==void 0&&x.call(this)===!1)return}return v}:function(){let m=this.LA(1);return p[m.tokenTypeIdx]}}else return i?function(p){let m=new cE,g=p===void 0?0:p.length;for(let v=0;v<g;v++){let x=p?.[v].GATE;m.set(v,x===void 0||x.call(this))}let y=eM.call(this,s,f,m,l);return typeof y=="number"?y:void 0}:function(){let p=eM.call(this,s,f,xoe,l);return typeof p=="number"?p:void 0}}buildLookaheadForOptional(e){let{prodOccurrence:r,rule:n,prodType:i,dynamicTokensEnabled:a}=e,s=this.dfas,l=this.logging,u=fp(n,i,r),f=this.atn.decisionMap[u].decision,d=Je(Gk({maxLookahead:1,occurrence:r,prodType:i,rule:n}),p=>Je(p,m=>m[0]));if(boe(d)&&d[0][0]&&!a){let p=d[0],m=qr(p);if(m.length===1&&ur(m[0].categoryMatches)){let y=m[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===y}}else{let g=Xr(m,(y,v)=>(v!==void 0&&(y[v.tokenTypeIdx]=!0,Ae(v.categoryMatches,x=>{y[x]=!0})),y),{});return function(){let y=this.LA(1);return g[y.tokenTypeIdx]===!0}}}return function(){let p=eM.call(this,s,f,xoe,l);return typeof p=="object"?!1:p===0}}};o(boe,"isLL1Sequence");o(IBe,"initATNSimulator");o(eM,"adaptivePredict");o(OBe,"performLookahead");o(PBe,"computeLookaheadTarget");o(BBe,"reportLookaheadAmbiguity");o(FBe,"buildAmbiguityError");o($Be,"getProductionDslName");o(zBe,"buildAdaptivePredictError");o(GBe,"getExistingTargetState");o(VBe,"computeReachSet");o(UBe,"getReachableTarget");o(HBe,"getUniqueAlt");o(Toe,"newDFAState");o(woe,"addDFAEdge");o(koe,"addDFAState");o(WBe,"computeStartState");o(uE,"closure");o(qBe,"getEpsilonTarget");o(YBe,"hasConfigInRuleStopState");o(XBe,"allConfigsInRuleStopStates");o(jBe,"hasConflictTerminatingPrediction");o(KBe,"getConflictingAltSets");o(QBe,"hasConflictingAltSet");o(ZBe,"hasStateAssociatedWithOneAlt")});var Soe=N(()=>{"use strict";Eoe()});var Coe,tM,Aoe,hE,jr,Pr,fE,_oe,rM,Doe,Loe,Roe,Noe,nM,Moe,Ioe,Ooe,dE,r1,n1,iM,i1,Poe,aM,sM,oM,lM,cM,Boe,Foe,uM,$oe,hM,Ex,zoe,Goe,Voe,Uoe,Hoe,Woe,qoe,Yoe,pE,Xoe,joe,Koe,Qoe,Zoe,Joe,ele,tle,rle,nle,ile,mE,ale,sle,ole,lle,cle,ule,hle,fle,dle,ple,mle,gle,yle,fM,dM,vle,xle,ble,wle,Tle,kle,Ele,Sle,Cle,pM,Fe,mM=N(()=>{"use strict";(function(t){function e(r){return typeof r=="string"}o(e,"is"),t.is=e})(Coe||(Coe={}));(function(t){function e(r){return typeof r=="string"}o(e,"is"),t.is=e})(tM||(tM={}));(function(t){t.MIN_VALUE=-2147483648,t.MAX_VALUE=2147483647;function e(r){return typeof r=="number"&&t.MIN_VALUE<=r&&r<=t.MAX_VALUE}o(e,"is"),t.is=e})(Aoe||(Aoe={}));(function(t){t.MIN_VALUE=0,t.MAX_VALUE=2147483647;function e(r){return typeof r=="number"&&t.MIN_VALUE<=r&&r<=t.MAX_VALUE}o(e,"is"),t.is=e})(hE||(hE={}));(function(t){function e(n,i){return n===Number.MAX_VALUE&&(n=hE.MAX_VALUE),i===Number.MAX_VALUE&&(i=hE.MAX_VALUE),{line:n,character:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Fe.uinteger(i.line)&&Fe.uinteger(i.character)}o(r,"is"),t.is=r})(jr||(jr={}));(function(t){function e(n,i,a,s){if(Fe.uinteger(n)&&Fe.uinteger(i)&&Fe.uinteger(a)&&Fe.uinteger(s))return{start:jr.create(n,i),end:jr.create(a,s)};if(jr.is(n)&&jr.is(i))return{start:n,end:i};throw new Error(`Range#create called with invalid arguments[${n}, ${i}, ${a}, ${s}]`)}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&jr.is(i.start)&&jr.is(i.end)}o(r,"is"),t.is=r})(Pr||(Pr={}));(function(t){function e(n,i){return{uri:n,range:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Pr.is(i.range)&&(Fe.string(i.uri)||Fe.undefined(i.uri))}o(r,"is"),t.is=r})(fE||(fE={}));(function(t){function e(n,i,a,s){return{targetUri:n,targetRange:i,targetSelectionRange:a,originSelectionRange:s}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Pr.is(i.targetRange)&&Fe.string(i.targetUri)&&Pr.is(i.targetSelectionRange)&&(Pr.is(i.originSelectionRange)||Fe.undefined(i.originSelectionRange))}o(r,"is"),t.is=r})(_oe||(_oe={}));(function(t){function e(n,i,a,s){return{red:n,green:i,blue:a,alpha:s}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Fe.numberRange(i.red,0,1)&&Fe.numberRange(i.green,0,1)&&Fe.numberRange(i.blue,0,1)&&Fe.numberRange(i.alpha,0,1)}o(r,"is"),t.is=r})(rM||(rM={}));(function(t){function e(n,i){return{range:n,color:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Pr.is(i.range)&&rM.is(i.color)}o(r,"is"),t.is=r})(Doe||(Doe={}));(function(t){function e(n,i,a){return{label:n,textEdit:i,additionalTextEdits:a}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Fe.string(i.label)&&(Fe.undefined(i.textEdit)||n1.is(i))&&(Fe.undefined(i.additionalTextEdits)||Fe.typedArray(i.additionalTextEdits,n1.is))}o(r,"is"),t.is=r})(Loe||(Loe={}));(function(t){t.Comment="comment",t.Imports="imports",t.Region="region"})(Roe||(Roe={}));(function(t){function e(n,i,a,s,l,u){let h={startLine:n,endLine:i};return Fe.defined(a)&&(h.startCharacter=a),Fe.defined(s)&&(h.endCharacter=s),Fe.defined(l)&&(h.kind=l),Fe.defined(u)&&(h.collapsedText=u),h}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Fe.uinteger(i.startLine)&&Fe.uinteger(i.startLine)&&(Fe.undefined(i.startCharacter)||Fe.uinteger(i.startCharacter))&&(Fe.undefined(i.endCharacter)||Fe.uinteger(i.endCharacter))&&(Fe.undefined(i.kind)||Fe.string(i.kind))}o(r,"is"),t.is=r})(Noe||(Noe={}));(function(t){function e(n,i){return{location:n,message:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&fE.is(i.location)&&Fe.string(i.message)}o(r,"is"),t.is=r})(nM||(nM={}));(function(t){t.Error=1,t.Warning=2,t.Information=3,t.Hint=4})(Moe||(Moe={}));(function(t){t.Unnecessary=1,t.Deprecated=2})(Ioe||(Ioe={}));(function(t){function e(r){let n=r;return Fe.objectLiteral(n)&&Fe.string(n.href)}o(e,"is"),t.is=e})(Ooe||(Ooe={}));(function(t){function e(n,i,a,s,l,u){let h={range:n,message:i};return Fe.defined(a)&&(h.severity=a),Fe.defined(s)&&(h.code=s),Fe.defined(l)&&(h.source=l),Fe.defined(u)&&(h.relatedInformation=u),h}o(e,"create"),t.create=e;function r(n){var i;let a=n;return Fe.defined(a)&&Pr.is(a.range)&&Fe.string(a.message)&&(Fe.number(a.severity)||Fe.undefined(a.severity))&&(Fe.integer(a.code)||Fe.string(a.code)||Fe.undefined(a.code))&&(Fe.undefined(a.codeDescription)||Fe.string((i=a.codeDescription)===null||i===void 0?void 0:i.href))&&(Fe.string(a.source)||Fe.undefined(a.source))&&(Fe.undefined(a.relatedInformation)||Fe.typedArray(a.relatedInformation,nM.is))}o(r,"is"),t.is=r})(dE||(dE={}));(function(t){function e(n,i,...a){let s={title:n,command:i};return Fe.defined(a)&&a.length>0&&(s.arguments=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.string(i.title)&&Fe.string(i.command)}o(r,"is"),t.is=r})(r1||(r1={}));(function(t){function e(a,s){return{range:a,newText:s}}o(e,"replace"),t.replace=e;function r(a,s){return{range:{start:a,end:a},newText:s}}o(r,"insert"),t.insert=r;function n(a){return{range:a,newText:""}}o(n,"del"),t.del=n;function i(a){let s=a;return Fe.objectLiteral(s)&&Fe.string(s.newText)&&Pr.is(s.range)}o(i,"is"),t.is=i})(n1||(n1={}));(function(t){function e(n,i,a){let s={label:n};return i!==void 0&&(s.needsConfirmation=i),a!==void 0&&(s.description=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Fe.string(i.label)&&(Fe.boolean(i.needsConfirmation)||i.needsConfirmation===void 0)&&(Fe.string(i.description)||i.description===void 0)}o(r,"is"),t.is=r})(iM||(iM={}));(function(t){function e(r){let n=r;return Fe.string(n)}o(e,"is"),t.is=e})(i1||(i1={}));(function(t){function e(a,s,l){return{range:a,newText:s,annotationId:l}}o(e,"replace"),t.replace=e;function r(a,s,l){return{range:{start:a,end:a},newText:s,annotationId:l}}o(r,"insert"),t.insert=r;function n(a,s){return{range:a,newText:"",annotationId:s}}o(n,"del"),t.del=n;function i(a){let s=a;return n1.is(s)&&(iM.is(s.annotationId)||i1.is(s.annotationId))}o(i,"is"),t.is=i})(Poe||(Poe={}));(function(t){function e(n,i){return{textDocument:n,edits:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&uM.is(i.textDocument)&&Array.isArray(i.edits)}o(r,"is"),t.is=r})(aM||(aM={}));(function(t){function e(n,i,a){let s={kind:"create",uri:n};return i!==void 0&&(i.overwrite!==void 0||i.ignoreIfExists!==void 0)&&(s.options=i),a!==void 0&&(s.annotationId=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="create"&&Fe.string(i.uri)&&(i.options===void 0||(i.options.overwrite===void 0||Fe.boolean(i.options.overwrite))&&(i.options.ignoreIfExists===void 0||Fe.boolean(i.options.ignoreIfExists)))&&(i.annotationId===void 0||i1.is(i.annotationId))}o(r,"is"),t.is=r})(sM||(sM={}));(function(t){function e(n,i,a,s){let l={kind:"rename",oldUri:n,newUri:i};return a!==void 0&&(a.overwrite!==void 0||a.ignoreIfExists!==void 0)&&(l.options=a),s!==void 0&&(l.annotationId=s),l}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="rename"&&Fe.string(i.oldUri)&&Fe.string(i.newUri)&&(i.options===void 0||(i.options.overwrite===void 0||Fe.boolean(i.options.overwrite))&&(i.options.ignoreIfExists===void 0||Fe.boolean(i.options.ignoreIfExists)))&&(i.annotationId===void 0||i1.is(i.annotationId))}o(r,"is"),t.is=r})(oM||(oM={}));(function(t){function e(n,i,a){let s={kind:"delete",uri:n};return i!==void 0&&(i.recursive!==void 0||i.ignoreIfNotExists!==void 0)&&(s.options=i),a!==void 0&&(s.annotationId=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&i.kind==="delete"&&Fe.string(i.uri)&&(i.options===void 0||(i.options.recursive===void 0||Fe.boolean(i.options.recursive))&&(i.options.ignoreIfNotExists===void 0||Fe.boolean(i.options.ignoreIfNotExists)))&&(i.annotationId===void 0||i1.is(i.annotationId))}o(r,"is"),t.is=r})(lM||(lM={}));(function(t){function e(r){let n=r;return n&&(n.changes!==void 0||n.documentChanges!==void 0)&&(n.documentChanges===void 0||n.documentChanges.every(i=>Fe.string(i.kind)?sM.is(i)||oM.is(i)||lM.is(i):aM.is(i)))}o(e,"is"),t.is=e})(cM||(cM={}));(function(t){function e(n){return{uri:n}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.string(i.uri)}o(r,"is"),t.is=r})(Boe||(Boe={}));(function(t){function e(n,i){return{uri:n,version:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.string(i.uri)&&Fe.integer(i.version)}o(r,"is"),t.is=r})(Foe||(Foe={}));(function(t){function e(n,i){return{uri:n,version:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.string(i.uri)&&(i.version===null||Fe.integer(i.version))}o(r,"is"),t.is=r})(uM||(uM={}));(function(t){function e(n,i,a,s){return{uri:n,languageId:i,version:a,text:s}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.string(i.uri)&&Fe.string(i.languageId)&&Fe.integer(i.version)&&Fe.string(i.text)}o(r,"is"),t.is=r})($oe||($oe={}));(function(t){t.PlainText="plaintext",t.Markdown="markdown";function e(r){let n=r;return n===t.PlainText||n===t.Markdown}o(e,"is"),t.is=e})(hM||(hM={}));(function(t){function e(r){let n=r;return Fe.objectLiteral(r)&&hM.is(n.kind)&&Fe.string(n.value)}o(e,"is"),t.is=e})(Ex||(Ex={}));(function(t){t.Text=1,t.Method=2,t.Function=3,t.Constructor=4,t.Field=5,t.Variable=6,t.Class=7,t.Interface=8,t.Module=9,t.Property=10,t.Unit=11,t.Value=12,t.Enum=13,t.Keyword=14,t.Snippet=15,t.Color=16,t.File=17,t.Reference=18,t.Folder=19,t.EnumMember=20,t.Constant=21,t.Struct=22,t.Event=23,t.Operator=24,t.TypeParameter=25})(zoe||(zoe={}));(function(t){t.PlainText=1,t.Snippet=2})(Goe||(Goe={}));(function(t){t.Deprecated=1})(Voe||(Voe={}));(function(t){function e(n,i,a){return{newText:n,insert:i,replace:a}}o(e,"create"),t.create=e;function r(n){let i=n;return i&&Fe.string(i.newText)&&Pr.is(i.insert)&&Pr.is(i.replace)}o(r,"is"),t.is=r})(Uoe||(Uoe={}));(function(t){t.asIs=1,t.adjustIndentation=2})(Hoe||(Hoe={}));(function(t){function e(r){let n=r;return n&&(Fe.string(n.detail)||n.detail===void 0)&&(Fe.string(n.description)||n.description===void 0)}o(e,"is"),t.is=e})(Woe||(Woe={}));(function(t){function e(r){return{label:r}}o(e,"create"),t.create=e})(qoe||(qoe={}));(function(t){function e(r,n){return{items:r||[],isIncomplete:!!n}}o(e,"create"),t.create=e})(Yoe||(Yoe={}));(function(t){function e(n){return n.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}o(e,"fromPlainText"),t.fromPlainText=e;function r(n){let i=n;return Fe.string(i)||Fe.objectLiteral(i)&&Fe.string(i.language)&&Fe.string(i.value)}o(r,"is"),t.is=r})(pE||(pE={}));(function(t){function e(r){let n=r;return!!n&&Fe.objectLiteral(n)&&(Ex.is(n.contents)||pE.is(n.contents)||Fe.typedArray(n.contents,pE.is))&&(r.range===void 0||Pr.is(r.range))}o(e,"is"),t.is=e})(Xoe||(Xoe={}));(function(t){function e(r,n){return n?{label:r,documentation:n}:{label:r}}o(e,"create"),t.create=e})(joe||(joe={}));(function(t){function e(r,n,...i){let a={label:r};return Fe.defined(n)&&(a.documentation=n),Fe.defined(i)?a.parameters=i:a.parameters=[],a}o(e,"create"),t.create=e})(Koe||(Koe={}));(function(t){t.Text=1,t.Read=2,t.Write=3})(Qoe||(Qoe={}));(function(t){function e(r,n){let i={range:r};return Fe.number(n)&&(i.kind=n),i}o(e,"create"),t.create=e})(Zoe||(Zoe={}));(function(t){t.File=1,t.Module=2,t.Namespace=3,t.Package=4,t.Class=5,t.Method=6,t.Property=7,t.Field=8,t.Constructor=9,t.Enum=10,t.Interface=11,t.Function=12,t.Variable=13,t.Constant=14,t.String=15,t.Number=16,t.Boolean=17,t.Array=18,t.Object=19,t.Key=20,t.Null=21,t.EnumMember=22,t.Struct=23,t.Event=24,t.Operator=25,t.TypeParameter=26})(Joe||(Joe={}));(function(t){t.Deprecated=1})(ele||(ele={}));(function(t){function e(r,n,i,a,s){let l={name:r,kind:n,location:{uri:a,range:i}};return s&&(l.containerName=s),l}o(e,"create"),t.create=e})(tle||(tle={}));(function(t){function e(r,n,i,a){return a!==void 0?{name:r,kind:n,location:{uri:i,range:a}}:{name:r,kind:n,location:{uri:i}}}o(e,"create"),t.create=e})(rle||(rle={}));(function(t){function e(n,i,a,s,l,u){let h={name:n,detail:i,kind:a,range:s,selectionRange:l};return u!==void 0&&(h.children=u),h}o(e,"create"),t.create=e;function r(n){let i=n;return i&&Fe.string(i.name)&&Fe.number(i.kind)&&Pr.is(i.range)&&Pr.is(i.selectionRange)&&(i.detail===void 0||Fe.string(i.detail))&&(i.deprecated===void 0||Fe.boolean(i.deprecated))&&(i.children===void 0||Array.isArray(i.children))&&(i.tags===void 0||Array.isArray(i.tags))}o(r,"is"),t.is=r})(nle||(nle={}));(function(t){t.Empty="",t.QuickFix="quickfix",t.Refactor="refactor",t.RefactorExtract="refactor.extract",t.RefactorInline="refactor.inline",t.RefactorRewrite="refactor.rewrite",t.Source="source",t.SourceOrganizeImports="source.organizeImports",t.SourceFixAll="source.fixAll"})(ile||(ile={}));(function(t){t.Invoked=1,t.Automatic=2})(mE||(mE={}));(function(t){function e(n,i,a){let s={diagnostics:n};return i!=null&&(s.only=i),a!=null&&(s.triggerKind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.typedArray(i.diagnostics,dE.is)&&(i.only===void 0||Fe.typedArray(i.only,Fe.string))&&(i.triggerKind===void 0||i.triggerKind===mE.Invoked||i.triggerKind===mE.Automatic)}o(r,"is"),t.is=r})(ale||(ale={}));(function(t){function e(n,i,a){let s={title:n},l=!0;return typeof i=="string"?(l=!1,s.kind=i):r1.is(i)?s.command=i:s.edit=i,l&&a!==void 0&&(s.kind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return i&&Fe.string(i.title)&&(i.diagnostics===void 0||Fe.typedArray(i.diagnostics,dE.is))&&(i.kind===void 0||Fe.string(i.kind))&&(i.edit!==void 0||i.command!==void 0)&&(i.command===void 0||r1.is(i.command))&&(i.isPreferred===void 0||Fe.boolean(i.isPreferred))&&(i.edit===void 0||cM.is(i.edit))}o(r,"is"),t.is=r})(sle||(sle={}));(function(t){function e(n,i){let a={range:n};return Fe.defined(i)&&(a.data=i),a}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Pr.is(i.range)&&(Fe.undefined(i.command)||r1.is(i.command))}o(r,"is"),t.is=r})(ole||(ole={}));(function(t){function e(n,i){return{tabSize:n,insertSpaces:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Fe.uinteger(i.tabSize)&&Fe.boolean(i.insertSpaces)}o(r,"is"),t.is=r})(lle||(lle={}));(function(t){function e(n,i,a){return{range:n,target:i,data:a}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Pr.is(i.range)&&(Fe.undefined(i.target)||Fe.string(i.target))}o(r,"is"),t.is=r})(cle||(cle={}));(function(t){function e(n,i){return{range:n,parent:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&Pr.is(i.range)&&(i.parent===void 0||t.is(i.parent))}o(r,"is"),t.is=r})(ule||(ule={}));(function(t){t.namespace="namespace",t.type="type",t.class="class",t.enum="enum",t.interface="interface",t.struct="struct",t.typeParameter="typeParameter",t.parameter="parameter",t.variable="variable",t.property="property",t.enumMember="enumMember",t.event="event",t.function="function",t.method="method",t.macro="macro",t.keyword="keyword",t.modifier="modifier",t.comment="comment",t.string="string",t.number="number",t.regexp="regexp",t.operator="operator",t.decorator="decorator"})(hle||(hle={}));(function(t){t.declaration="declaration",t.definition="definition",t.readonly="readonly",t.static="static",t.deprecated="deprecated",t.abstract="abstract",t.async="async",t.modification="modification",t.documentation="documentation",t.defaultLibrary="defaultLibrary"})(fle||(fle={}));(function(t){function e(r){let n=r;return Fe.objectLiteral(n)&&(n.resultId===void 0||typeof n.resultId=="string")&&Array.isArray(n.data)&&(n.data.length===0||typeof n.data[0]=="number")}o(e,"is"),t.is=e})(dle||(dle={}));(function(t){function e(n,i){return{range:n,text:i}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Pr.is(i.range)&&Fe.string(i.text)}o(r,"is"),t.is=r})(ple||(ple={}));(function(t){function e(n,i,a){return{range:n,variableName:i,caseSensitiveLookup:a}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Pr.is(i.range)&&Fe.boolean(i.caseSensitiveLookup)&&(Fe.string(i.variableName)||i.variableName===void 0)}o(r,"is"),t.is=r})(mle||(mle={}));(function(t){function e(n,i){return{range:n,expression:i}}o(e,"create"),t.create=e;function r(n){let i=n;return i!=null&&Pr.is(i.range)&&(Fe.string(i.expression)||i.expression===void 0)}o(r,"is"),t.is=r})(gle||(gle={}));(function(t){function e(n,i){return{frameId:n,stoppedLocation:i}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.defined(i)&&Pr.is(n.stoppedLocation)}o(r,"is"),t.is=r})(yle||(yle={}));(function(t){t.Type=1,t.Parameter=2;function e(r){return r===1||r===2}o(e,"is"),t.is=e})(fM||(fM={}));(function(t){function e(n){return{value:n}}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&(i.tooltip===void 0||Fe.string(i.tooltip)||Ex.is(i.tooltip))&&(i.location===void 0||fE.is(i.location))&&(i.command===void 0||r1.is(i.command))}o(r,"is"),t.is=r})(dM||(dM={}));(function(t){function e(n,i,a){let s={position:n,label:i};return a!==void 0&&(s.kind=a),s}o(e,"create"),t.create=e;function r(n){let i=n;return Fe.objectLiteral(i)&&jr.is(i.position)&&(Fe.string(i.label)||Fe.typedArray(i.label,dM.is))&&(i.kind===void 0||fM.is(i.kind))&&i.textEdits===void 0||Fe.typedArray(i.textEdits,n1.is)&&(i.tooltip===void 0||Fe.string(i.tooltip)||Ex.is(i.tooltip))&&(i.paddingLeft===void 0||Fe.boolean(i.paddingLeft))&&(i.paddingRight===void 0||Fe.boolean(i.paddingRight))}o(r,"is"),t.is=r})(vle||(vle={}));(function(t){function e(r){return{kind:"snippet",value:r}}o(e,"createSnippet"),t.createSnippet=e})(xle||(xle={}));(function(t){function e(r,n,i,a){return{insertText:r,filterText:n,range:i,command:a}}o(e,"create"),t.create=e})(ble||(ble={}));(function(t){function e(r){return{items:r}}o(e,"create"),t.create=e})(wle||(wle={}));(function(t){t.Invoked=0,t.Automatic=1})(Tle||(Tle={}));(function(t){function e(r,n){return{range:r,text:n}}o(e,"create"),t.create=e})(kle||(kle={}));(function(t){function e(r,n){return{triggerKind:r,selectedCompletionInfo:n}}o(e,"create"),t.create=e})(Ele||(Ele={}));(function(t){function e(r){let n=r;return Fe.objectLiteral(n)&&tM.is(n.uri)&&Fe.string(n.name)}o(e,"is"),t.is=e})(Sle||(Sle={}));(function(t){function e(a,s,l,u){return new pM(a,s,l,u)}o(e,"create"),t.create=e;function r(a){let s=a;return!!(Fe.defined(s)&&Fe.string(s.uri)&&(Fe.undefined(s.languageId)||Fe.string(s.languageId))&&Fe.uinteger(s.lineCount)&&Fe.func(s.getText)&&Fe.func(s.positionAt)&&Fe.func(s.offsetAt))}o(r,"is"),t.is=r;function n(a,s){let l=a.getText(),u=i(s,(f,d)=>{let p=f.range.start.line-d.range.start.line;return p===0?f.range.start.character-d.range.start.character:p}),h=l.length;for(let f=u.length-1;f>=0;f--){let d=u[f],p=a.offsetAt(d.range.start),m=a.offsetAt(d.range.end);if(m<=h)l=l.substring(0,p)+d.newText+l.substring(m,l.length);else throw new Error("Overlapping edit");h=p}return l}o(n,"applyEdits"),t.applyEdits=n;function i(a,s){if(a.length<=1)return a;let l=a.length/2|0,u=a.slice(0,l),h=a.slice(l);i(u,s),i(h,s);let f=0,d=0,p=0;for(;f<u.length&&d<h.length;)s(u[f],h[d])<=0?a[p++]=u[f++]:a[p++]=h[d++];for(;f<u.length;)a[p++]=u[f++];for(;d<h.length;)a[p++]=h[d++];return a}o(i,"mergeSort")})(Cle||(Cle={}));pM=class{static{o(this,"FullTextDocument")}constructor(e,r,n,i){this._uri=e,this._languageId=r,this._version=n,this._content=i,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let r=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(r,n)}return this._content}update(e,r){this._content=e.text,this._version=r,this._lineOffsets=void 0}getLineOffsets(){if(this._lineOffsets===void 0){let e=[],r=this._content,n=!0;for(let i=0;i<r.length;i++){n&&(e.push(i),n=!1);let a=r.charAt(i);n=a==="\r"||a===`
+`,a==="\r"&&i+1<r.length&&r.charAt(i+1)===`
+`&&i++}n&&r.length>0&&e.push(r.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let r=this.getLineOffsets(),n=0,i=r.length;if(i===0)return jr.create(0,e);for(;n<i;){let s=Math.floor((n+i)/2);r[s]>e?i=s:n=s+1}let a=n-1;return jr.create(a,e-r[a])}offsetAt(e){let r=this.getLineOffsets();if(e.line>=r.length)return this._content.length;if(e.line<0)return 0;let n=r[e.line],i=e.line+1<r.length?r[e.line+1]:this._content.length;return Math.max(Math.min(n+e.character,i),n)}get lineCount(){return this.getLineOffsets().length}};(function(t){let e=Object.prototype.toString;function r(m){return typeof m<"u"}o(r,"defined"),t.defined=r;function n(m){return typeof m>"u"}o(n,"undefined"),t.undefined=n;function i(m){return m===!0||m===!1}o(i,"boolean"),t.boolean=i;function a(m){return e.call(m)==="[object String]"}o(a,"string"),t.string=a;function s(m){return e.call(m)==="[object Number]"}o(s,"number"),t.number=s;function l(m,g,y){return e.call(m)==="[object Number]"&&g<=m&&m<=y}o(l,"numberRange"),t.numberRange=l;function u(m){return e.call(m)==="[object Number]"&&-2147483648<=m&&m<=2147483647}o(u,"integer"),t.integer=u;function h(m){return e.call(m)==="[object Number]"&&0<=m&&m<=2147483647}o(h,"uinteger"),t.uinteger=h;function f(m){return e.call(m)==="[object Function]"}o(f,"func"),t.func=f;function d(m){return m!==null&&typeof m=="object"}o(d,"objectLiteral"),t.objectLiteral=d;function p(m,g){return Array.isArray(m)&&m.every(g)}o(p,"typedArray"),t.typedArray=p})(Fe||(Fe={}))});var Sx,Cx,pp,mp,gM,a1,gE=N(()=>{"use strict";mM();Nl();Sx=class{static{o(this,"CstNodeBuilder")}constructor(){this.nodeStack=[]}get current(){var e;return(e=this.nodeStack[this.nodeStack.length-1])!==null&&e!==void 0?e:this.rootNode}buildRootNode(e){return this.rootNode=new a1(e),this.rootNode.root=this.rootNode,this.nodeStack=[this.rootNode],this.rootNode}buildCompositeNode(e){let r=new mp;return r.grammarSource=e,r.root=this.rootNode,this.current.content.push(r),this.nodeStack.push(r),r}buildLeafNode(e,r){let n=new pp(e.startOffset,e.image.length,Gm(e),e.tokenType,!r);return n.grammarSource=r,n.root=this.rootNode,this.current.content.push(n),n}removeNode(e){let r=e.container;if(r){let n=r.content.indexOf(e);n>=0&&r.content.splice(n,1)}}addHiddenNodes(e){let r=[];for(let a of e){let s=new pp(a.startOffset,a.image.length,Gm(a),a.tokenType,!0);s.root=this.rootNode,r.push(s)}let n=this.current,i=!1;if(n.content.length>0){n.content.push(...r);return}for(;n.container;){let a=n.container.content.indexOf(n);if(a>0){n.container.content.splice(a,0,...r),i=!0;break}n=n.container}i||this.rootNode.content.unshift(...r)}construct(e){let r=this.current;typeof e.$type=="string"&&(this.current.astNode=e),e.$cstNode=r;let n=this.nodeStack.pop();n?.content.length===0&&this.removeNode(n)}},Cx=class{static{o(this,"AbstractCstNode")}get parent(){return this.container}get feature(){return this.grammarSource}get hidden(){return!1}get astNode(){var e,r;let n=typeof((e=this._astNode)===null||e===void 0?void 0:e.$type)=="string"?this._astNode:(r=this.container)===null||r===void 0?void 0:r.astNode;if(!n)throw new Error("This node has no associated AST element");return n}set astNode(e){this._astNode=e}get element(){return this.astNode}get text(){return this.root.fullText.substring(this.offset,this.end)}},pp=class extends Cx{static{o(this,"LeafCstNodeImpl")}get offset(){return this._offset}get length(){return this._length}get end(){return this._offset+this._length}get hidden(){return this._hidden}get tokenType(){return this._tokenType}get range(){return this._range}constructor(e,r,n,i,a=!1){super(),this._hidden=a,this._offset=e,this._tokenType=i,this._length=r,this._range=n}},mp=class extends Cx{static{o(this,"CompositeCstNodeImpl")}constructor(){super(...arguments),this.content=new gM(this)}get children(){return this.content}get offset(){var e,r;return(r=(e=this.firstNonHiddenNode)===null||e===void 0?void 0:e.offset)!==null&&r!==void 0?r:0}get length(){return this.end-this.offset}get end(){var e,r;return(r=(e=this.lastNonHiddenNode)===null||e===void 0?void 0:e.end)!==null&&r!==void 0?r:0}get range(){let e=this.firstNonHiddenNode,r=this.lastNonHiddenNode;if(e&&r){if(this._rangeCache===void 0){let{range:n}=e,{range:i}=r;this._rangeCache={start:n.start,end:i.end.line<n.start.line?n.start:i.end}}return this._rangeCache}else return{start:jr.create(0,0),end:jr.create(0,0)}}get firstNonHiddenNode(){for(let e of this.content)if(!e.hidden)return e;return this.content[0]}get lastNonHiddenNode(){for(let e=this.content.length-1;e>=0;e--){let r=this.content[e];if(!r.hidden)return r}return this.content[this.content.length-1]}},gM=class t extends Array{static{o(this,"CstNodeContainer")}constructor(e){super(),this.parent=e,Object.setPrototypeOf(this,t.prototype)}push(...e){return this.addParents(e),super.push(...e)}unshift(...e){return this.addParents(e),super.unshift(...e)}splice(e,r,...n){return this.addParents(n),super.splice(e,r,...n)}addParents(e){for(let r of e)r.container=this.parent}},a1=class extends mp{static{o(this,"RootCstNodeImpl")}get text(){return this._text.substring(this.offset,this.end)}get fullText(){return this._text}constructor(e){super(),this._text="",this._text=e??""}}});function yM(t){return t.$type===yE}var yE,Ale,_le,Ax,_x,vE,s1,Dx,JBe,vM,Lx=N(()=>{"use strict";cf();Soe();Rc();Ol();is();gE();yE=Symbol("Datatype");o(yM,"isDataTypeNode");Ale="\u200B",_le=o(t=>t.endsWith(Ale)?t:t+Ale,"withRuleSuffix"),Ax=class{static{o(this,"AbstractLangiumParser")}constructor(e){this._unorderedGroups=new Map,this.allRules=new Map,this.lexer=e.parser.Lexer;let r=this.lexer.definition,n=e.LanguageMetaData.mode==="production";this.wrapper=new vM(r,Object.assign(Object.assign({},e.parser.ParserConfig),{skipValidations:n,errorMessageProvider:e.parser.ParserErrorMessageProvider}))}alternatives(e,r){this.wrapper.wrapOr(e,r)}optional(e,r){this.wrapper.wrapOption(e,r)}many(e,r){this.wrapper.wrapMany(e,r)}atLeastOne(e,r){this.wrapper.wrapAtLeastOne(e,r)}getRule(e){return this.allRules.get(e)}isRecording(){return this.wrapper.IS_RECORDING}get unorderedGroups(){return this._unorderedGroups}getRuleStack(){return this.wrapper.RULE_STACK}finalize(){this.wrapper.wrapSelfAnalysis()}},_x=class extends Ax{static{o(this,"LangiumParser")}get current(){return this.stack[this.stack.length-1]}constructor(e){super(e),this.nodeBuilder=new Sx,this.stack=[],this.assignmentMap=new Map,this.linker=e.references.Linker,this.converter=e.parser.ValueConverter,this.astReflection=e.shared.AstReflection}rule(e,r){let n=this.computeRuleType(e),i=this.wrapper.DEFINE_RULE(_le(e.name),this.startImplementation(n,r).bind(this));return this.allRules.set(e.name,i),e.entry&&(this.mainRule=i),i}computeRuleType(e){if(!e.fragment){if(Z2(e))return yE;{let r=Rg(e);return r??e.name}}}parse(e,r={}){this.nodeBuilder.buildRootNode(e);let n=this.lexerResult=this.lexer.tokenize(e);this.wrapper.input=n.tokens;let i=r.rule?this.allRules.get(r.rule):this.mainRule;if(!i)throw new Error(r.rule?`No rule found with name '${r.rule}'`:"No main rule available.");let a=i.call(this.wrapper,{});return this.nodeBuilder.addHiddenNodes(n.hidden),this.unorderedGroups.clear(),this.lexerResult=void 0,{value:a,lexerErrors:n.errors,lexerReport:n.report,parserErrors:this.wrapper.errors}}startImplementation(e,r){return n=>{let i=!this.isRecording()&&e!==void 0;if(i){let s={$type:e};this.stack.push(s),e===yE&&(s.value="")}let a;try{a=r(n)}catch{a=void 0}return a===void 0&&i&&(a=this.construct()),a}}extractHiddenTokens(e){let r=this.lexerResult.hidden;if(!r.length)return[];let n=e.startOffset;for(let i=0;i<r.length;i++)if(r[i].startOffset>n)return r.splice(0,i);return r.splice(0,r.length)}consume(e,r,n){let i=this.wrapper.wrapConsume(e,r);if(!this.isRecording()&&this.isValidToken(i)){let a=this.extractHiddenTokens(i);this.nodeBuilder.addHiddenNodes(a);let s=this.nodeBuilder.buildLeafNode(i,n),{assignment:l,isCrossRef:u}=this.getAssignment(n),h=this.current;if(l){let f=Ho(n)?i.image:this.converter.convert(i.image,s);this.assign(l.operator,l.feature,f,s,u)}else if(yM(h)){let f=i.image;Ho(n)||(f=this.converter.convert(f,s).toString()),h.value+=f}}}isValidToken(e){return!e.isInsertedInRecovery&&!isNaN(e.startOffset)&&typeof e.endOffset=="number"&&!isNaN(e.endOffset)}subrule(e,r,n,i,a){let s;!this.isRecording()&&!n&&(s=this.nodeBuilder.buildCompositeNode(i));let l=this.wrapper.wrapSubrule(e,r,a);!this.isRecording()&&s&&s.length>0&&this.performSubruleAssignment(l,i,s)}performSubruleAssignment(e,r,n){let{assignment:i,isCrossRef:a}=this.getAssignment(r);if(i)this.assign(i.operator,i.feature,e,n,a);else if(!i){let s=this.current;if(yM(s))s.value+=e.toString();else if(typeof e=="object"&&e){let u=this.assignWithoutOverride(e,s);this.stack.pop(),this.stack.push(u)}}}action(e,r){if(!this.isRecording()){let n=this.current;if(r.feature&&r.operator){n=this.construct(),this.nodeBuilder.removeNode(n.$cstNode),this.nodeBuilder.buildCompositeNode(r).content.push(n.$cstNode);let a={$type:e};this.stack.push(a),this.assign(r.operator,r.feature,n,n.$cstNode,!1)}else n.$type=e}}construct(){if(this.isRecording())return;let e=this.current;return vk(e),this.nodeBuilder.construct(e),this.stack.pop(),yM(e)?this.converter.convert(e.value,e.$cstNode):(XR(this.astReflection,e),e)}getAssignment(e){if(!this.assignmentMap.has(e)){let r=tp(e,Ml);this.assignmentMap.set(e,{assignment:r,isCrossRef:r?ep(r.terminal):!1})}return this.assignmentMap.get(e)}assign(e,r,n,i,a){let s=this.current,l;switch(a&&typeof n=="string"?l=this.linker.buildReference(s,r,i,n):l=n,e){case"=":{s[r]=l;break}case"?=":{s[r]=!0;break}case"+=":Array.isArray(s[r])||(s[r]=[]),s[r].push(l)}}assignWithoutOverride(e,r){for(let[i,a]of Object.entries(r)){let s=e[i];s===void 0?e[i]=a:Array.isArray(s)&&Array.isArray(a)&&(a.push(...s),e[i]=a)}let n=e.$cstNode;return n&&(n.astNode=void 0,e.$cstNode=void 0),e}get definitionErrors(){return this.wrapper.definitionErrors}},vE=class{static{o(this,"AbstractParserErrorMessageProvider")}buildMismatchTokenMessage(e){return zu.buildMismatchTokenMessage(e)}buildNotAllInputParsedMessage(e){return zu.buildNotAllInputParsedMessage(e)}buildNoViableAltMessage(e){return zu.buildNoViableAltMessage(e)}buildEarlyExitMessage(e){return zu.buildEarlyExitMessage(e)}},s1=class extends vE{static{o(this,"LangiumParserErrorMessageProvider")}buildMismatchTokenMessage({expected:e,actual:r}){return`Expecting ${e.LABEL?"`"+e.LABEL+"`":e.name.endsWith(":KW")?`keyword '${e.name.substring(0,e.name.length-3)}'`:`token of type '${e.name}'`} but found \`${r.image}\`.`}buildNotAllInputParsedMessage({firstRedundant:e}){return`Expecting end of file but found \`${e.image}\`.`}},Dx=class extends Ax{static{o(this,"LangiumCompletionParser")}constructor(){super(...arguments),this.tokens=[],this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}action(){}construct(){}parse(e){this.resetState();let r=this.lexer.tokenize(e,{mode:"partial"});return this.tokens=r.tokens,this.wrapper.input=[...this.tokens],this.mainRule.call(this.wrapper,{}),this.unorderedGroups.clear(),{tokens:this.tokens,elementStack:[...this.lastElementStack],tokenIndex:this.nextTokenIndex}}rule(e,r){let n=this.wrapper.DEFINE_RULE(_le(e.name),this.startImplementation(r).bind(this));return this.allRules.set(e.name,n),e.entry&&(this.mainRule=n),n}resetState(){this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}startImplementation(e){return r=>{let n=this.keepStackSize();try{e(r)}finally{this.resetStackSize(n)}}}removeUnexpectedElements(){this.elementStack.splice(this.stackSize)}keepStackSize(){let e=this.elementStack.length;return this.stackSize=e,e}resetStackSize(e){this.removeUnexpectedElements(),this.stackSize=e}consume(e,r,n){this.wrapper.wrapConsume(e,r),this.isRecording()||(this.lastElementStack=[...this.elementStack,n],this.nextTokenIndex=this.currIdx+1)}subrule(e,r,n,i,a){this.before(i),this.wrapper.wrapSubrule(e,r,a),this.after(i)}before(e){this.isRecording()||this.elementStack.push(e)}after(e){if(!this.isRecording()){let r=this.elementStack.lastIndexOf(e);r>=0&&this.elementStack.splice(r)}}get currIdx(){return this.wrapper.currIdx}},JBe={recoveryEnabled:!0,nodeLocationTracking:"full",skipValidations:!0,errorMessageProvider:new s1},vM=class extends xx{static{o(this,"ChevrotainWrapper")}constructor(e,r){let n=r&&"maxLookahead"in r;super(e,Object.assign(Object.assign(Object.assign({},JBe),{lookaheadStrategy:n?new Gu({maxLookahead:r.maxLookahead}):new kx({logging:r.skipValidations?()=>{}:void 0})}),r))}get IS_RECORDING(){return this.RECORDING_PHASE}DEFINE_RULE(e,r){return this.RULE(e,r)}wrapSelfAnalysis(){this.performSelfAnalysis()}wrapConsume(e,r){return this.consume(e,r)}wrapSubrule(e,r,n){return this.subrule(e,r,{ARGS:[n]})}wrapOr(e,r){this.or(e,r)}wrapOption(e,r){this.option(e,r)}wrapMany(e,r){this.many(e,r)}wrapAtLeastOne(e,r){this.atLeastOne(e,r)}}});function Rx(t,e,r){return eFe({parser:e,tokens:r,ruleNames:new Map},t),e}function eFe(t,e){let r=K2(e,!1),n=en(e.rules).filter(Oa).filter(i=>r.has(i));for(let i of n){let a=Object.assign(Object.assign({},t),{consume:1,optional:1,subrule:1,many:1,or:1});t.parser.rule(i,gp(a,i.definition))}}function gp(t,e,r=!1){let n;if(Ho(e))n=oFe(t,e);else if(Mu(e))n=tFe(t,e);else if(Ml(e))n=gp(t,e.terminal);else if(ep(e))n=Dle(t,e);else if(Il(e))n=rFe(t,e);else if(mk(e))n=iFe(t,e);else if(yk(e))n=aFe(t,e);else if(sf(e))n=sFe(t,e);else if($R(e)){let i=t.consume++;n=o(()=>t.parser.consume(i,lo,e),"method")}else throw new Zd(e.$cstNode,`Unexpected element type: ${e.$type}`);return Lle(t,r?void 0:xE(e),n,e.cardinality)}function tFe(t,e){let r=J2(e);return()=>t.parser.action(r,e)}function rFe(t,e){let r=e.rule.ref;if(Oa(r)){let n=t.subrule++,i=r.fragment,a=e.arguments.length>0?nFe(r,e.arguments):()=>({});return s=>t.parser.subrule(n,Rle(t,r),i,e,a(s))}else if(so(r)){let n=t.consume++,i=xM(t,r.name);return()=>t.parser.consume(n,i,e)}else if(r)Lc(r);else throw new Zd(e.$cstNode,`Undefined rule: ${e.rule.$refText}`)}function nFe(t,e){let r=e.map(n=>Vu(n.value));return n=>{let i={};for(let a=0;a<r.length;a++){let s=t.parameters[a],l=r[a];i[s.name]=l(n)}return i}}function Vu(t){if(NR(t)){let e=Vu(t.left),r=Vu(t.right);return n=>e(n)||r(n)}else if(RR(t)){let e=Vu(t.left),r=Vu(t.right);return n=>e(n)&&r(n)}else if(MR(t)){let e=Vu(t.value);return r=>!e(r)}else if(IR(t)){let e=t.parameter.ref.name;return r=>r!==void 0&&r[e]===!0}else if(LR(t)){let e=!!t.true;return()=>e}Lc(t)}function iFe(t,e){if(e.elements.length===1)return gp(t,e.elements[0]);{let r=[];for(let i of e.elements){let a={ALT:gp(t,i,!0)},s=xE(i);s&&(a.GATE=Vu(s)),r.push(a)}let n=t.or++;return i=>t.parser.alternatives(n,r.map(a=>{let s={ALT:o(()=>a.ALT(i),"ALT")},l=a.GATE;return l&&(s.GATE=()=>l(i)),s}))}}function aFe(t,e){if(e.elements.length===1)return gp(t,e.elements[0]);let r=[];for(let l of e.elements){let u={ALT:gp(t,l,!0)},h=xE(l);h&&(u.GATE=Vu(h)),r.push(u)}let n=t.or++,i=o((l,u)=>{let h=u.getRuleStack().join("-");return`uGroup_${l}_${h}`},"idFunc"),a=o(l=>t.parser.alternatives(n,r.map((u,h)=>{let f={ALT:o(()=>!0,"ALT")},d=t.parser;f.ALT=()=>{if(u.ALT(l),!d.isRecording()){let m=i(n,d);d.unorderedGroups.get(m)||d.unorderedGroups.set(m,[]);let g=d.unorderedGroups.get(m);typeof g?.[h]>"u"&&(g[h]=!0)}};let p=u.GATE;return p?f.GATE=()=>p(l):f.GATE=()=>{let m=d.unorderedGroups.get(i(n,d));return!m?.[h]},f})),"alternatives"),s=Lle(t,xE(e),a,"*");return l=>{s(l),t.parser.isRecording()||t.parser.unorderedGroups.delete(i(n,t.parser))}}function sFe(t,e){let r=e.elements.map(n=>gp(t,n));return n=>r.forEach(i=>i(n))}function xE(t){if(sf(t))return t.guardCondition}function Dle(t,e,r=e.terminal){if(r)if(Il(r)&&Oa(r.rule.ref)){let n=r.rule.ref,i=t.subrule++;return a=>t.parser.subrule(i,Rle(t,n),!1,e,a)}else if(Il(r)&&so(r.rule.ref)){let n=t.consume++,i=xM(t,r.rule.ref.name);return()=>t.parser.consume(n,i,e)}else if(Ho(r)){let n=t.consume++,i=xM(t,r.value);return()=>t.parser.consume(n,i,e)}else throw new Error("Could not build cross reference parser");else{if(!e.type.ref)throw new Error("Could not resolve reference to type: "+e.type.$refText);let n=kk(e.type.ref),i=n?.terminal;if(!i)throw new Error("Could not find name assignment for type: "+J2(e.type.ref));return Dle(t,e,i)}}function oFe(t,e){let r=t.consume++,n=t.tokens[e.value];if(!n)throw new Error("Could not find token for keyword: "+e.value);return()=>t.parser.consume(r,n,e)}function Lle(t,e,r,n){let i=e&&Vu(e);if(!n)if(i){let a=t.or++;return s=>t.parser.alternatives(a,[{ALT:o(()=>r(s),"ALT"),GATE:o(()=>i(s),"GATE")},{ALT:lE(),GATE:o(()=>!i(s),"GATE")}])}else return r;if(n==="*"){let a=t.many++;return s=>t.parser.many(a,{DEF:o(()=>r(s),"DEF"),GATE:i?()=>i(s):void 0})}else if(n==="+"){let a=t.many++;if(i){let s=t.or++;return l=>t.parser.alternatives(s,[{ALT:o(()=>t.parser.atLeastOne(a,{DEF:o(()=>r(l),"DEF")}),"ALT"),GATE:o(()=>i(l),"GATE")},{ALT:lE(),GATE:o(()=>!i(l),"GATE")}])}else return s=>t.parser.atLeastOne(a,{DEF:o(()=>r(s),"DEF")})}else if(n==="?"){let a=t.optional++;return s=>t.parser.optional(a,{DEF:o(()=>r(s),"DEF"),GATE:i?()=>i(s):void 0})}else Lc(n)}function Rle(t,e){let r=lFe(t,e),n=t.parser.getRule(r);if(!n)throw new Error(`Rule "${r}" not found."`);return n}function lFe(t,e){if(Oa(e))return e.name;if(t.ruleNames.has(e))return t.ruleNames.get(e);{let r=e,n=r.$container,i=e.$type;for(;!Oa(n);)(sf(n)||mk(n)||yk(n))&&(i=n.elements.indexOf(r).toString()+":"+i),r=n,n=n.$container;return i=n.name+":"+i,t.ruleNames.set(e,i),i}}function xM(t,e){let r=t.tokens[e];if(!r)throw new Error(`Token "${e}" not found."`);return r}var bE=N(()=>{"use strict";cf();Rc();uk();Ps();Ol();o(Rx,"createParser");o(eFe,"buildRules");o(gp,"buildElement");o(tFe,"buildAction");o(rFe,"buildRuleCall");o(nFe,"buildRuleCallPredicate");o(Vu,"buildPredicate");o(iFe,"buildAlternatives");o(aFe,"buildUnorderedGroup");o(sFe,"buildGroup");o(xE,"getGuardCondition");o(Dle,"buildCrossReference");o(oFe,"buildKeyword");o(Lle,"wrap");o(Rle,"getRule");o(lFe,"getRuleName");o(xM,"getToken")});function bM(t){let e=t.Grammar,r=t.parser.Lexer,n=new Dx(t);return Rx(e,n,r.definition),n.finalize(),n}var wM=N(()=>{"use strict";Lx();bE();o(bM,"createCompletionParser")});function TM(t){let e=Nle(t);return e.finalize(),e}function Nle(t){let e=t.Grammar,r=t.parser.Lexer,n=new _x(t);return Rx(e,n,r.definition)}var kM=N(()=>{"use strict";Lx();bE();o(TM,"createLangiumParser");o(Nle,"prepareLangiumParser")});var Uu,wE=N(()=>{"use strict";cf();Rc();is();Ol();Lg();Ps();Uu=class{static{o(this,"DefaultTokenBuilder")}constructor(){this.diagnostics=[]}buildTokens(e,r){let n=en(K2(e,!1)),i=this.buildTerminalTokens(n),a=this.buildKeywordTokens(n,i,r);return i.forEach(s=>{let l=s.PATTERN;typeof l=="object"&&l&&"test"in l&&Dg(l)?a.unshift(s):a.push(s)}),a}flushLexingReport(e){return{diagnostics:this.popDiagnostics()}}popDiagnostics(){let e=[...this.diagnostics];return this.diagnostics=[],e}buildTerminalTokens(e){return e.filter(so).filter(r=>!r.fragment).map(r=>this.buildTerminalToken(r)).toArray()}buildTerminalToken(e){let r=Ng(e),n=this.requiresCustomPattern(r)?this.regexPatternFunction(r):r,i={name:e.name,PATTERN:n};return typeof n=="function"&&(i.LINE_BREAKS=!0),e.hidden&&(i.GROUP=Dg(r)?Xn.SKIPPED:"hidden"),i}requiresCustomPattern(e){return e.flags.includes("u")||e.flags.includes("s")?!0:!!(e.source.includes("?<=")||e.source.includes("?<!"))}regexPatternFunction(e){let r=new RegExp(e,e.flags+"y");return(n,i)=>(r.lastIndex=i,r.exec(n))}buildKeywordTokens(e,r,n){return e.filter(Oa).flatMap(i=>Nc(i).filter(Ho)).distinct(i=>i.value).toArray().sort((i,a)=>a.value.length-i.value.length).map(i=>this.buildKeywordToken(i,r,!!n?.caseInsensitive))}buildKeywordToken(e,r,n){let i=this.buildKeywordPattern(e,n),a={name:e.value,PATTERN:i,LONGER_ALT:this.findLongerAlt(e,r)};return typeof i=="function"&&(a.LINE_BREAKS=!0),a}buildKeywordPattern(e,r){return r?new RegExp(tN(e.value)):e.value}findLongerAlt(e,r){return r.reduce((n,i)=>{let a=i?.PATTERN;return a?.source&&rN("^"+a.source+"$",e.value)&&n.push(i),n},[])}}});var yp,Oc,EM=N(()=>{"use strict";Rc();Ol();yp=class{static{o(this,"DefaultValueConverter")}convert(e,r){let n=r.grammarSource;if(ep(n)&&(n=aN(n)),Il(n)){let i=n.rule.ref;if(!i)throw new Error("This cst node was not parsed by a rule.");return this.runConverter(i,e,r)}return e}runConverter(e,r,n){var i;switch(e.name.toUpperCase()){case"INT":return Oc.convertInt(r);case"STRING":return Oc.convertString(r);case"ID":return Oc.convertID(r)}switch((i=fN(e))===null||i===void 0?void 0:i.toLowerCase()){case"number":return Oc.convertNumber(r);case"boolean":return Oc.convertBoolean(r);case"bigint":return Oc.convertBigint(r);case"date":return Oc.convertDate(r);default:return r}}};(function(t){function e(h){let f="";for(let d=1;d<h.length-1;d++){let p=h.charAt(d);if(p==="\\"){let m=h.charAt(++d);f+=r(m)}else f+=p}return f}o(e,"convertString"),t.convertString=e;function r(h){switch(h){case"b":return"\b";case"f":return"\f";case"n":return`
+`;case"r":return"\r";case"t":return" ";case"v":return"\v";case"0":return"\0";default:return h}}o(r,"convertEscapeCharacter");function n(h){return h.charAt(0)==="^"?h.substring(1):h}o(n,"convertID"),t.convertID=n;function i(h){return parseInt(h)}o(i,"convertInt"),t.convertInt=i;function a(h){return BigInt(h)}o(a,"convertBigint"),t.convertBigint=a;function s(h){return new Date(h)}o(s,"convertDate"),t.convertDate=s;function l(h){return Number(h)}o(l,"convertNumber"),t.convertNumber=l;function u(h){return h.toLowerCase()==="true"}o(u,"convertBoolean"),t.convertBoolean=u})(Oc||(Oc={}))});var _M=Mi(AM=>{"use strict";Object.defineProperty(AM,"__esModule",{value:!0});var SM;function CM(){if(SM===void 0)throw new Error("No runtime abstraction layer installed");return SM}o(CM,"RAL");(function(t){function e(r){if(r===void 0)throw new Error("No runtime abstraction layer provided");SM=r}o(e,"install"),t.install=e})(CM||(CM={}));AM.default=CM});var Ole=Mi(Ba=>{"use strict";Object.defineProperty(Ba,"__esModule",{value:!0});Ba.stringArray=Ba.array=Ba.func=Ba.error=Ba.number=Ba.string=Ba.boolean=void 0;function cFe(t){return t===!0||t===!1}o(cFe,"boolean");Ba.boolean=cFe;function Mle(t){return typeof t=="string"||t instanceof String}o(Mle,"string");Ba.string=Mle;function uFe(t){return typeof t=="number"||t instanceof Number}o(uFe,"number");Ba.number=uFe;function hFe(t){return t instanceof Error}o(hFe,"error");Ba.error=hFe;function fFe(t){return typeof t=="function"}o(fFe,"func");Ba.func=fFe;function Ile(t){return Array.isArray(t)}o(Ile,"array");Ba.array=Ile;function dFe(t){return Ile(t)&&t.every(e=>Mle(e))}o(dFe,"stringArray");Ba.stringArray=dFe});var LM=Mi(o1=>{"use strict";Object.defineProperty(o1,"__esModule",{value:!0});o1.Emitter=o1.Event=void 0;var pFe=_M(),Ple;(function(t){let e={dispose(){}};t.None=function(){return e}})(Ple||(o1.Event=Ple={}));var DM=class{static{o(this,"CallbackList")}add(e,r=null,n){this._callbacks||(this._callbacks=[],this._contexts=[]),this._callbacks.push(e),this._contexts.push(r),Array.isArray(n)&&n.push({dispose:o(()=>this.remove(e,r),"dispose")})}remove(e,r=null){if(!this._callbacks)return;let n=!1;for(let i=0,a=this._callbacks.length;i<a;i++)if(this._callbacks[i]===e)if(this._contexts[i]===r){this._callbacks.splice(i,1),this._contexts.splice(i,1);return}else n=!0;if(n)throw new Error("When adding a listener with a context, you should remove it with the same context")}invoke(...e){if(!this._callbacks)return[];let r=[],n=this._callbacks.slice(0),i=this._contexts.slice(0);for(let a=0,s=n.length;a<s;a++)try{r.push(n[a].apply(i[a],e))}catch(l){(0,pFe.default)().console.error(l)}return r}isEmpty(){return!this._callbacks||this._callbacks.length===0}dispose(){this._callbacks=void 0,this._contexts=void 0}},TE=class t{static{o(this,"Emitter")}constructor(e){this._options=e}get event(){return this._event||(this._event=(e,r,n)=>{this._callbacks||(this._callbacks=new DM),this._options&&this._options.onFirstListenerAdd&&this._callbacks.isEmpty()&&this._options.onFirstListenerAdd(this),this._callbacks.add(e,r);let i={dispose:o(()=>{this._callbacks&&(this._callbacks.remove(e,r),i.dispose=t._noop,this._options&&this._options.onLastListenerRemove&&this._callbacks.isEmpty()&&this._options.onLastListenerRemove(this))},"dispose")};return Array.isArray(n)&&n.push(i),i}),this._event}fire(e){this._callbacks&&this._callbacks.invoke.call(this._callbacks,e)}dispose(){this._callbacks&&(this._callbacks.dispose(),this._callbacks=void 0)}};o1.Emitter=TE;TE._noop=function(){}});var Ble=Mi(l1=>{"use strict";Object.defineProperty(l1,"__esModule",{value:!0});l1.CancellationTokenSource=l1.CancellationToken=void 0;var mFe=_M(),gFe=Ole(),RM=LM(),kE;(function(t){t.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:RM.Event.None}),t.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:RM.Event.None});function e(r){let n=r;return n&&(n===t.None||n===t.Cancelled||gFe.boolean(n.isCancellationRequested)&&!!n.onCancellationRequested)}o(e,"is"),t.is=e})(kE||(l1.CancellationToken=kE={}));var yFe=Object.freeze(function(t,e){let r=(0,mFe.default)().timer.setTimeout(t.bind(e),0);return{dispose(){r.dispose()}}}),EE=class{static{o(this,"MutableToken")}constructor(){this._isCancelled=!1}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?yFe:(this._emitter||(this._emitter=new RM.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=void 0)}},NM=class{static{o(this,"CancellationTokenSource")}get token(){return this._token||(this._token=new EE),this._token}cancel(){this._token?this._token.cancel():this._token=kE.Cancelled}dispose(){this._token?this._token instanceof EE&&this._token.dispose():this._token=kE.None}};l1.CancellationTokenSource=NM});var yr={};var qo=N(()=>{"use strict";Sr(yr,Sa(Ble(),1))});function MM(){return new Promise(t=>{typeof setImmediate>"u"?setTimeout(t,0):setImmediate(t)})}function CE(){return SE=performance.now(),new yr.CancellationTokenSource}function $le(t){Fle=t}function Bc(t){return t===Pc}async function xi(t){if(t===yr.CancellationToken.None)return;let e=performance.now();if(e-SE>=Fle&&(SE=e,await MM(),SE=performance.now()),t.isCancellationRequested)throw Pc}var SE,Fle,Pc,cs,Yo=N(()=>{"use strict";qo();o(MM,"delayNextTick");SE=0,Fle=10;o(CE,"startCancelableOperation");o($le,"setInterruptionPeriod");Pc=Symbol("OperationCancelled");o(Bc,"isOperationCancelled");o(xi,"interruptAndCheck");cs=class{static{o(this,"Deferred")}constructor(){this.promise=new Promise((e,r)=>{this.resolve=n=>(e(n),this),this.reject=n=>(r(n),this)})}}});function IM(t,e){if(t.length<=1)return t;let r=t.length/2|0,n=t.slice(0,r),i=t.slice(r);IM(n,e),IM(i,e);let a=0,s=0,l=0;for(;a<n.length&&s<i.length;)e(n[a],i[s])<=0?t[l++]=n[a++]:t[l++]=i[s++];for(;a<n.length;)t[l++]=n[a++];for(;s<i.length;)t[l++]=i[s++];return t}function zle(t,e,r=0){let n=e?[r]:[];for(let i=0;i<t.length;i++){let a=t.charCodeAt(i);Gle(a)&&(a===13&&i+1<t.length&&t.charCodeAt(i+1)===10&&i++,n.push(r+i+1))}return n}function Gle(t){return t===13||t===10}function Vle(t){let e=t.start,r=t.end;return e.line>r.line||e.line===r.line&&e.character>r.character?{start:r,end:e}:t}function vFe(t){let e=Vle(t.range);return e!==t.range?{newText:t.newText,range:e}:t}var AE,c1,Ule=N(()=>{"use strict";AE=class t{static{o(this,"FullTextDocument")}constructor(e,r,n,i){this._uri=e,this._languageId=r,this._version=n,this._content=i,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let r=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(r,n)}return this._content}update(e,r){for(let n of e)if(t.isIncremental(n)){let i=Vle(n.range),a=this.offsetAt(i.start),s=this.offsetAt(i.end);this._content=this._content.substring(0,a)+n.text+this._content.substring(s,this._content.length);let l=Math.max(i.start.line,0),u=Math.max(i.end.line,0),h=this._lineOffsets,f=zle(n.text,!1,a);if(u-l===f.length)for(let p=0,m=f.length;p<m;p++)h[p+l+1]=f[p];else f.length<1e4?h.splice(l+1,u-l,...f):this._lineOffsets=h=h.slice(0,l+1).concat(f,h.slice(u+1));let d=n.text.length-(s-a);if(d!==0)for(let p=l+1+f.length,m=h.length;p<m;p++)h[p]=h[p]+d}else if(t.isFull(n))this._content=n.text,this._lineOffsets=void 0;else throw new Error("Unknown change event received");this._version=r}getLineOffsets(){return this._lineOffsets===void 0&&(this._lineOffsets=zle(this._content,!0)),this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let r=this.getLineOffsets(),n=0,i=r.length;if(i===0)return{line:0,character:e};for(;n<i;){let s=Math.floor((n+i)/2);r[s]>e?i=s:n=s+1}let a=n-1;return e=this.ensureBeforeEOL(e,r[a]),{line:a,character:e-r[a]}}offsetAt(e){let r=this.getLineOffsets();if(e.line>=r.length)return this._content.length;if(e.line<0)return 0;let n=r[e.line];if(e.character<=0)return n;let i=e.line+1<r.length?r[e.line+1]:this._content.length,a=Math.min(n+e.character,i);return this.ensureBeforeEOL(a,n)}ensureBeforeEOL(e,r){for(;e>r&&Gle(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){let r=e;return r!=null&&typeof r.text=="string"&&r.range!==void 0&&(r.rangeLength===void 0||typeof r.rangeLength=="number")}static isFull(e){let r=e;return r!=null&&typeof r.text=="string"&&r.range===void 0&&r.rangeLength===void 0}};(function(t){function e(i,a,s,l){return new AE(i,a,s,l)}o(e,"create"),t.create=e;function r(i,a,s){if(i instanceof AE)return i.update(a,s),i;throw new Error("TextDocument.update: document must be created by TextDocument.create")}o(r,"update"),t.update=r;function n(i,a){let s=i.getText(),l=IM(a.map(vFe),(f,d)=>{let p=f.range.start.line-d.range.start.line;return p===0?f.range.start.character-d.range.start.character:p}),u=0,h=[];for(let f of l){let d=i.offsetAt(f.range.start);if(d<u)throw new Error("Overlapping edit");d>u&&h.push(s.substring(u,d)),f.newText.length&&h.push(f.newText),u=i.offsetAt(f.range.end)}return h.push(s.substr(u)),h.join("")}o(n,"applyEdits"),t.applyEdits=n})(c1||(c1={}));o(IM,"mergeSort");o(zle,"computeLineOffsets");o(Gle,"isEOL");o(Vle,"getWellformedRange");o(vFe,"getWellformedEdit")});var Hle,us,u1,OM=N(()=>{"use strict";(()=>{"use strict";var t={470:i=>{function a(u){if(typeof u!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(u))}o(a,"e");function s(u,h){for(var f,d="",p=0,m=-1,g=0,y=0;y<=u.length;++y){if(y<u.length)f=u.charCodeAt(y);else{if(f===47)break;f=47}if(f===47){if(!(m===y-1||g===1))if(m!==y-1&&g===2){if(d.length<2||p!==2||d.charCodeAt(d.length-1)!==46||d.charCodeAt(d.length-2)!==46){if(d.length>2){var v=d.lastIndexOf("/");if(v!==d.length-1){v===-1?(d="",p=0):p=(d=d.slice(0,v)).length-1-d.lastIndexOf("/"),m=y,g=0;continue}}else if(d.length===2||d.length===1){d="",p=0,m=y,g=0;continue}}h&&(d.length>0?d+="/..":d="..",p=2)}else d.length>0?d+="/"+u.slice(m+1,y):d=u.slice(m+1,y),p=y-m-1;m=y,g=0}else f===46&&g!==-1?++g:g=-1}return d}o(s,"r");var l={resolve:o(function(){for(var u,h="",f=!1,d=arguments.length-1;d>=-1&&!f;d--){var p;d>=0?p=arguments[d]:(u===void 0&&(u=process.cwd()),p=u),a(p),p.length!==0&&(h=p+"/"+h,f=p.charCodeAt(0)===47)}return h=s(h,!f),f?h.length>0?"/"+h:"/":h.length>0?h:"."},"resolve"),normalize:o(function(u){if(a(u),u.length===0)return".";var h=u.charCodeAt(0)===47,f=u.charCodeAt(u.length-1)===47;return(u=s(u,!h)).length!==0||h||(u="."),u.length>0&&f&&(u+="/"),h?"/"+u:u},"normalize"),isAbsolute:o(function(u){return a(u),u.length>0&&u.charCodeAt(0)===47},"isAbsolute"),join:o(function(){if(arguments.length===0)return".";for(var u,h=0;h<arguments.length;++h){var f=arguments[h];a(f),f.length>0&&(u===void 0?u=f:u+="/"+f)}return u===void 0?".":l.normalize(u)},"join"),relative:o(function(u,h){if(a(u),a(h),u===h||(u=l.resolve(u))===(h=l.resolve(h)))return"";for(var f=1;f<u.length&&u.charCodeAt(f)===47;++f);for(var d=u.length,p=d-f,m=1;m<h.length&&h.charCodeAt(m)===47;++m);for(var g=h.length-m,y=p<g?p:g,v=-1,x=0;x<=y;++x){if(x===y){if(g>y){if(h.charCodeAt(m+x)===47)return h.slice(m+x+1);if(x===0)return h.slice(m+x)}else p>y&&(u.charCodeAt(f+x)===47?v=x:x===0&&(v=0));break}var b=u.charCodeAt(f+x);if(b!==h.charCodeAt(m+x))break;b===47&&(v=x)}var w="";for(x=f+v+1;x<=d;++x)x!==d&&u.charCodeAt(x)!==47||(w.length===0?w+="..":w+="/..");return w.length>0?w+h.slice(m+v):(m+=v,h.charCodeAt(m)===47&&++m,h.slice(m))},"relative"),_makeLong:o(function(u){return u},"_makeLong"),dirname:o(function(u){if(a(u),u.length===0)return".";for(var h=u.charCodeAt(0),f=h===47,d=-1,p=!0,m=u.length-1;m>=1;--m)if((h=u.charCodeAt(m))===47){if(!p){d=m;break}}else p=!1;return d===-1?f?"/":".":f&&d===1?"//":u.slice(0,d)},"dirname"),basename:o(function(u,h){if(h!==void 0&&typeof h!="string")throw new TypeError('"ext" argument must be a string');a(u);var f,d=0,p=-1,m=!0;if(h!==void 0&&h.length>0&&h.length<=u.length){if(h.length===u.length&&h===u)return"";var g=h.length-1,y=-1;for(f=u.length-1;f>=0;--f){var v=u.charCodeAt(f);if(v===47){if(!m){d=f+1;break}}else y===-1&&(m=!1,y=f+1),g>=0&&(v===h.charCodeAt(g)?--g==-1&&(p=f):(g=-1,p=y))}return d===p?p=y:p===-1&&(p=u.length),u.slice(d,p)}for(f=u.length-1;f>=0;--f)if(u.charCodeAt(f)===47){if(!m){d=f+1;break}}else p===-1&&(m=!1,p=f+1);return p===-1?"":u.slice(d,p)},"basename"),extname:o(function(u){a(u);for(var h=-1,f=0,d=-1,p=!0,m=0,g=u.length-1;g>=0;--g){var y=u.charCodeAt(g);if(y!==47)d===-1&&(p=!1,d=g+1),y===46?h===-1?h=g:m!==1&&(m=1):h!==-1&&(m=-1);else if(!p){f=g+1;break}}return h===-1||d===-1||m===0||m===1&&h===d-1&&h===f+1?"":u.slice(h,d)},"extname"),format:o(function(u){if(u===null||typeof u!="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof u);return function(h,f){var d=f.dir||f.root,p=f.base||(f.name||"")+(f.ext||"");return d?d===f.root?d+p:d+"/"+p:p}(0,u)},"format"),parse:o(function(u){a(u);var h={root:"",dir:"",base:"",ext:"",name:""};if(u.length===0)return h;var f,d=u.charCodeAt(0),p=d===47;p?(h.root="/",f=1):f=0;for(var m=-1,g=0,y=-1,v=!0,x=u.length-1,b=0;x>=f;--x)if((d=u.charCodeAt(x))!==47)y===-1&&(v=!1,y=x+1),d===46?m===-1?m=x:b!==1&&(b=1):m!==-1&&(b=-1);else if(!v){g=x+1;break}return m===-1||y===-1||b===0||b===1&&m===y-1&&m===g+1?y!==-1&&(h.base=h.name=g===0&&p?u.slice(1,y):u.slice(g,y)):(g===0&&p?(h.name=u.slice(1,m),h.base=u.slice(1,y)):(h.name=u.slice(g,m),h.base=u.slice(g,y)),h.ext=u.slice(m,y)),g>0?h.dir=u.slice(0,g-1):p&&(h.dir="/"),h},"parse"),sep:"/",delimiter:":",win32:null,posix:null};l.posix=l,i.exports=l}},e={};function r(i){var a=e[i];if(a!==void 0)return a.exports;var s=e[i]={exports:{}};return t[i](s,s.exports,r),s.exports}o(r,"r"),r.d=(i,a)=>{for(var s in a)r.o(a,s)&&!r.o(i,s)&&Object.defineProperty(i,s,{enumerable:!0,get:a[s]})},r.o=(i,a)=>Object.prototype.hasOwnProperty.call(i,a),r.r=i=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var n={};(()=>{let i;r.r(n),r.d(n,{URI:o(()=>p,"URI"),Utils:o(()=>I,"Utils")}),typeof process=="object"?i=process.platform==="win32":typeof navigator=="object"&&(i=navigator.userAgent.indexOf("Windows")>=0);let a=/^\w[\w\d+.-]*$/,s=/^\//,l=/^\/\//;function u(D,k){if(!D.scheme&&k)throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${D.authority}", path: "${D.path}", query: "${D.query}", fragment: "${D.fragment}"}`);if(D.scheme&&!a.test(D.scheme))throw new Error("[UriError]: Scheme contains illegal characters.");if(D.path){if(D.authority){if(!s.test(D.path))throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character')}else if(l.test(D.path))throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")')}}o(u,"s");let h="",f="/",d=/^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;class p{static{o(this,"f")}static isUri(k){return k instanceof p||!!k&&typeof k.authority=="string"&&typeof k.fragment=="string"&&typeof k.path=="string"&&typeof k.query=="string"&&typeof k.scheme=="string"&&typeof k.fsPath=="string"&&typeof k.with=="function"&&typeof k.toString=="function"}scheme;authority;path;query;fragment;constructor(k,L,R,O,M,B=!1){typeof k=="object"?(this.scheme=k.scheme||h,this.authority=k.authority||h,this.path=k.path||h,this.query=k.query||h,this.fragment=k.fragment||h):(this.scheme=function(F,P){return F||P?F:"file"}(k,B),this.authority=L||h,this.path=function(F,P){switch(F){case"https":case"http":case"file":P?P[0]!==f&&(P=f+P):P=f}return P}(this.scheme,R||h),this.query=O||h,this.fragment=M||h,u(this,B))}get fsPath(){return b(this,!1)}with(k){if(!k)return this;let{scheme:L,authority:R,path:O,query:M,fragment:B}=k;return L===void 0?L=this.scheme:L===null&&(L=h),R===void 0?R=this.authority:R===null&&(R=h),O===void 0?O=this.path:O===null&&(O=h),M===void 0?M=this.query:M===null&&(M=h),B===void 0?B=this.fragment:B===null&&(B=h),L===this.scheme&&R===this.authority&&O===this.path&&M===this.query&&B===this.fragment?this:new g(L,R,O,M,B)}static parse(k,L=!1){let R=d.exec(k);return R?new g(R[2]||h,E(R[4]||h),E(R[5]||h),E(R[7]||h),E(R[9]||h),L):new g(h,h,h,h,h)}static file(k){let L=h;if(i&&(k=k.replace(/\\/g,f)),k[0]===f&&k[1]===f){let R=k.indexOf(f,2);R===-1?(L=k.substring(2),k=f):(L=k.substring(2,R),k=k.substring(R)||f)}return new g("file",L,k,h,h)}static from(k){let L=new g(k.scheme,k.authority,k.path,k.query,k.fragment);return u(L,!0),L}toString(k=!1){return w(this,k)}toJSON(){return this}static revive(k){if(k){if(k instanceof p)return k;{let L=new g(k);return L._formatted=k.external,L._fsPath=k._sep===m?k.fsPath:null,L}}return k}}let m=i?1:void 0;class g extends p{static{o(this,"l")}_formatted=null;_fsPath=null;get fsPath(){return this._fsPath||(this._fsPath=b(this,!1)),this._fsPath}toString(k=!1){return k?w(this,!0):(this._formatted||(this._formatted=w(this,!1)),this._formatted)}toJSON(){let k={$mid:1};return this._fsPath&&(k.fsPath=this._fsPath,k._sep=m),this._formatted&&(k.external=this._formatted),this.path&&(k.path=this.path),this.scheme&&(k.scheme=this.scheme),this.authority&&(k.authority=this.authority),this.query&&(k.query=this.query),this.fragment&&(k.fragment=this.fragment),k}}let y={58:"%3A",47:"%2F",63:"%3F",35:"%23",91:"%5B",93:"%5D",64:"%40",33:"%21",36:"%24",38:"%26",39:"%27",40:"%28",41:"%29",42:"%2A",43:"%2B",44:"%2C",59:"%3B",61:"%3D",32:"%20"};function v(D,k,L){let R,O=-1;for(let M=0;M<D.length;M++){let B=D.charCodeAt(M);if(B>=97&&B<=122||B>=65&&B<=90||B>=48&&B<=57||B===45||B===46||B===95||B===126||k&&B===47||L&&B===91||L&&B===93||L&&B===58)O!==-1&&(R+=encodeURIComponent(D.substring(O,M)),O=-1),R!==void 0&&(R+=D.charAt(M));else{R===void 0&&(R=D.substr(0,M));let F=y[B];F!==void 0?(O!==-1&&(R+=encodeURIComponent(D.substring(O,M)),O=-1),R+=F):O===-1&&(O=M)}}return O!==-1&&(R+=encodeURIComponent(D.substring(O))),R!==void 0?R:D}o(v,"d");function x(D){let k;for(let L=0;L<D.length;L++){let R=D.charCodeAt(L);R===35||R===63?(k===void 0&&(k=D.substr(0,L)),k+=y[R]):k!==void 0&&(k+=D[L])}return k!==void 0?k:D}o(x,"p");function b(D,k){let L;return L=D.authority&&D.path.length>1&&D.scheme==="file"?`//${D.authority}${D.path}`:D.path.charCodeAt(0)===47&&(D.path.charCodeAt(1)>=65&&D.path.charCodeAt(1)<=90||D.path.charCodeAt(1)>=97&&D.path.charCodeAt(1)<=122)&&D.path.charCodeAt(2)===58?k?D.path.substr(1):D.path[1].toLowerCase()+D.path.substr(2):D.path,i&&(L=L.replace(/\//g,"\\")),L}o(b,"m");function w(D,k){let L=k?x:v,R="",{scheme:O,authority:M,path:B,query:F,fragment:P}=D;if(O&&(R+=O,R+=":"),(M||O==="file")&&(R+=f,R+=f),M){let z=M.indexOf("@");if(z!==-1){let $=M.substr(0,z);M=M.substr(z+1),z=$.lastIndexOf(":"),z===-1?R+=L($,!1,!1):(R+=L($.substr(0,z),!1,!1),R+=":",R+=L($.substr(z+1),!1,!0)),R+="@"}M=M.toLowerCase(),z=M.lastIndexOf(":"),z===-1?R+=L(M,!1,!0):(R+=L(M.substr(0,z),!1,!0),R+=M.substr(z))}if(B){if(B.length>=3&&B.charCodeAt(0)===47&&B.charCodeAt(2)===58){let z=B.charCodeAt(1);z>=65&&z<=90&&(B=`/${String.fromCharCode(z+32)}:${B.substr(3)}`)}else if(B.length>=2&&B.charCodeAt(1)===58){let z=B.charCodeAt(0);z>=65&&z<=90&&(B=`${String.fromCharCode(z+32)}:${B.substr(2)}`)}R+=L(B,!0,!1)}return F&&(R+="?",R+=L(F,!1,!1)),P&&(R+="#",R+=k?P:v(P,!1,!1)),R}o(w,"y");function C(D){try{return decodeURIComponent(D)}catch{return D.length>3?D.substr(0,3)+C(D.substr(3)):D}}o(C,"v");let T=/(%[0-9A-Za-z][0-9A-Za-z])+/g;function E(D){return D.match(T)?D.replace(T,k=>C(k)):D}o(E,"C");var A=r(470);let S=A.posix||A,_="/";var I;(function(D){D.joinPath=function(k,...L){return k.with({path:S.join(k.path,...L)})},D.resolvePath=function(k,...L){let R=k.path,O=!1;R[0]!==_&&(R=_+R,O=!0);let M=S.resolve(R,...L);return O&&M[0]===_&&!k.authority&&(M=M.substring(1)),k.with({path:M})},D.dirname=function(k){if(k.path.length===0||k.path===_)return k;let L=S.dirname(k.path);return L.length===1&&L.charCodeAt(0)===46&&(L=""),k.with({path:L})},D.basename=function(k){return S.basename(k.path)},D.extname=function(k){return S.extname(k.path)}})(I||(I={}))})(),Hle=n})();({URI:us,Utils:u1}=Hle)});var hs,Fc=N(()=>{"use strict";OM();(function(t){t.basename=u1.basename,t.dirname=u1.dirname,t.extname=u1.extname,t.joinPath=u1.joinPath,t.resolvePath=u1.resolvePath;function e(i,a){return i?.toString()===a?.toString()}o(e,"equals"),t.equals=e;function r(i,a){let s=typeof i=="string"?i:i.path,l=typeof a=="string"?a:a.path,u=s.split("/").filter(m=>m.length>0),h=l.split("/").filter(m=>m.length>0),f=0;for(;f<u.length&&u[f]===h[f];f++);let d="../".repeat(u.length-f),p=h.slice(f).join("/");return d+p}o(r,"relative"),t.relative=r;function n(i){return us.parse(i.toString()).toString()}o(n,"normalize"),t.normalize=n})(hs||(hs={}))});var kn,Nx,Mx,h1=N(()=>{"use strict";Ule();h1();qo();Ps();Fc();(function(t){t[t.Changed=0]="Changed",t[t.Parsed=1]="Parsed",t[t.IndexedContent=2]="IndexedContent",t[t.ComputedScopes=3]="ComputedScopes",t[t.Linked=4]="Linked",t[t.IndexedReferences=5]="IndexedReferences",t[t.Validated=6]="Validated"})(kn||(kn={}));Nx=class{static{o(this,"DefaultLangiumDocumentFactory")}constructor(e){this.serviceRegistry=e.ServiceRegistry,this.textDocuments=e.workspace.TextDocuments,this.fileSystemProvider=e.workspace.FileSystemProvider}async fromUri(e,r=yr.CancellationToken.None){let n=await this.fileSystemProvider.readFile(e);return this.createAsync(e,n,r)}fromTextDocument(e,r,n){return r=r??us.parse(e.uri),yr.CancellationToken.is(n)?this.createAsync(r,e,n):this.create(r,e,n)}fromString(e,r,n){return yr.CancellationToken.is(n)?this.createAsync(r,e,n):this.create(r,e,n)}fromModel(e,r){return this.create(r,{$model:e})}create(e,r,n){if(typeof r=="string"){let i=this.parse(e,r,n);return this.createLangiumDocument(i,e,void 0,r)}else if("$model"in r){let i={value:r.$model,parserErrors:[],lexerErrors:[]};return this.createLangiumDocument(i,e)}else{let i=this.parse(e,r.getText(),n);return this.createLangiumDocument(i,e,r)}}async createAsync(e,r,n){if(typeof r=="string"){let i=await this.parseAsync(e,r,n);return this.createLangiumDocument(i,e,void 0,r)}else{let i=await this.parseAsync(e,r.getText(),n);return this.createLangiumDocument(i,e,r)}}createLangiumDocument(e,r,n,i){let a;if(n)a={parseResult:e,uri:r,state:kn.Parsed,references:[],textDocument:n};else{let s=this.createTextDocumentGetter(r,i);a={parseResult:e,uri:r,state:kn.Parsed,references:[],get textDocument(){return s()}}}return e.value.$document=a,a}async update(e,r){var n,i;let a=(n=e.parseResult.value.$cstNode)===null||n===void 0?void 0:n.root.fullText,s=(i=this.textDocuments)===null||i===void 0?void 0:i.get(e.uri.toString()),l=s?s.getText():await this.fileSystemProvider.readFile(e.uri);if(s)Object.defineProperty(e,"textDocument",{value:s});else{let u=this.createTextDocumentGetter(e.uri,l);Object.defineProperty(e,"textDocument",{get:u})}return a!==l&&(e.parseResult=await this.parseAsync(e.uri,l,r),e.parseResult.value.$document=e),e.state=kn.Parsed,e}parse(e,r,n){return this.serviceRegistry.getServices(e).parser.LangiumParser.parse(r,n)}parseAsync(e,r,n){return this.serviceRegistry.getServices(e).parser.AsyncParser.parse(r,n)}createTextDocumentGetter(e,r){let n=this.serviceRegistry,i;return()=>i??(i=c1.create(e.toString(),n.getServices(e).LanguageMetaData.languageId,0,r??""))}},Mx=class{static{o(this,"DefaultLangiumDocuments")}constructor(e){this.documentMap=new Map,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.serviceRegistry=e.ServiceRegistry}get all(){return en(this.documentMap.values())}addDocument(e){let r=e.uri.toString();if(this.documentMap.has(r))throw new Error(`A document with the URI '${r}' is already present.`);this.documentMap.set(r,e)}getDocument(e){let r=e.toString();return this.documentMap.get(r)}async getOrCreateDocument(e,r){let n=this.getDocument(e);return n||(n=await this.langiumDocumentFactory.fromUri(e,r),this.addDocument(n),n)}createDocument(e,r,n){if(n)return this.langiumDocumentFactory.fromString(r,e,n).then(i=>(this.addDocument(i),i));{let i=this.langiumDocumentFactory.fromString(r,e);return this.addDocument(i),i}}hasDocument(e){return this.documentMap.has(e.toString())}invalidateDocument(e){let r=e.toString(),n=this.documentMap.get(r);return n&&(this.serviceRegistry.getServices(e).references.Linker.unlink(n),n.state=kn.Changed,n.precomputedScopes=void 0,n.diagnostics=void 0),n}deleteDocument(e){let r=e.toString(),n=this.documentMap.get(r);return n&&(n.state=kn.Changed,this.documentMap.delete(r)),n}}});var PM,Ix,BM=N(()=>{"use strict";qo();Rl();is();Yo();h1();PM=Symbol("ref_resolving"),Ix=class{static{o(this,"DefaultLinker")}constructor(e){this.reflection=e.shared.AstReflection,this.langiumDocuments=()=>e.shared.workspace.LangiumDocuments,this.scopeProvider=e.references.ScopeProvider,this.astNodeLocator=e.workspace.AstNodeLocator}async link(e,r=yr.CancellationToken.None){for(let n of Wo(e.parseResult.value))await xi(r),Ag(n).forEach(i=>this.doLink(i,e))}doLink(e,r){var n;let i=e.reference;if(i._ref===void 0){i._ref=PM;try{let a=this.getCandidate(e);if(jd(a))i._ref=a;else if(i._nodeDescription=a,this.langiumDocuments().hasDocument(a.documentUri)){let s=this.loadAstNode(a);i._ref=s??this.createLinkingError(e,a)}else i._ref=void 0}catch(a){console.error(`An error occurred while resolving reference to '${i.$refText}':`,a);let s=(n=a.message)!==null&&n!==void 0?n:String(a);i._ref=Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${i.$refText}': ${s}`})}r.references.push(i)}}unlink(e){for(let r of e.references)delete r._ref,delete r._nodeDescription;e.references=[]}getCandidate(e){let n=this.scopeProvider.getScope(e).getElement(e.reference.$refText);return n??this.createLinkingError(e)}buildReference(e,r,n,i){let a=this,s={$refNode:n,$refText:i,get ref(){var l;if(ii(this._ref))return this._ref;if(kR(this._nodeDescription)){let u=a.loadAstNode(this._nodeDescription);this._ref=u??a.createLinkingError({reference:s,container:e,property:r},this._nodeDescription)}else if(this._ref===void 0){this._ref=PM;let u=H2(e).$document,h=a.getLinkedNode({reference:s,container:e,property:r});if(h.error&&u&&u.state<kn.ComputedScopes)return this._ref=void 0;this._ref=(l=h.node)!==null&&l!==void 0?l:h.error,this._nodeDescription=h.descr,u?.references.push(this)}else if(this._ref===PM)throw new Error(`Cyclic reference resolution detected: ${a.astNodeLocator.getAstNodePath(e)}/${r} (symbol '${i}')`);return ii(this._ref)?this._ref:void 0},get $nodeDescription(){return this._nodeDescription},get error(){return jd(this._ref)?this._ref:void 0}};return s}getLinkedNode(e){var r;try{let n=this.getCandidate(e);if(jd(n))return{error:n};let i=this.loadAstNode(n);return i?{node:i,descr:n}:{descr:n,error:this.createLinkingError(e,n)}}catch(n){console.error(`An error occurred while resolving reference to '${e.reference.$refText}':`,n);let i=(r=n.message)!==null&&r!==void 0?r:String(n);return{error:Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${e.reference.$refText}': ${i}`})}}}loadAstNode(e){if(e.node)return e.node;let r=this.langiumDocuments().getDocument(e.documentUri);if(r)return this.astNodeLocator.getAstNode(r.parseResult.value,e.path)}createLinkingError(e,r){let n=H2(e.container).$document;n&&n.state<kn.ComputedScopes&&console.warn(`Attempted reference resolution before document reached ComputedScopes state (${n.uri}).`);let i=this.reflection.getReferenceType(e);return Object.assign(Object.assign({},e),{message:`Could not resolve reference to ${i} named '${e.reference.$refText}'.`,targetDescription:r})}}});function Wle(t){return typeof t.name=="string"}var Ox,FM=N(()=>{"use strict";Ol();o(Wle,"isNamed");Ox=class{static{o(this,"DefaultNameProvider")}getName(e){if(Wle(e))return e.name}getNameNode(e){return Q2(e.$cstNode,"name")}}});var Px,$M=N(()=>{"use strict";Ol();Rl();is();Nl();Ps();Fc();Px=class{static{o(this,"DefaultReferences")}constructor(e){this.nameProvider=e.references.NameProvider,this.index=e.shared.workspace.IndexManager,this.nodeLocator=e.workspace.AstNodeLocator}findDeclaration(e){if(e){let r=hN(e),n=e.astNode;if(r&&n){let i=n[r.feature];if(va(i))return i.ref;if(Array.isArray(i)){for(let a of i)if(va(a)&&a.$refNode&&a.$refNode.offset<=e.offset&&a.$refNode.end>=e.end)return a.ref}}if(n){let i=this.nameProvider.getNameNode(n);if(i&&(i===e||SR(e,i)))return n}}}findDeclarationNode(e){let r=this.findDeclaration(e);if(r?.$cstNode){let n=this.nameProvider.getNameNode(r);return n??r.$cstNode}}findReferences(e,r){let n=[];if(r.includeDeclaration){let a=this.getReferenceToSelf(e);a&&n.push(a)}let i=this.index.findAllReferences(e,this.nodeLocator.getAstNodePath(e));return r.documentUri&&(i=i.filter(a=>hs.equals(a.sourceUri,r.documentUri))),n.push(...i),en(n)}getReferenceToSelf(e){let r=this.nameProvider.getNameNode(e);if(r){let n=Pa(e),i=this.nodeLocator.getAstNodePath(e);return{sourceUri:n.uri,sourcePath:i,targetUri:n.uri,targetPath:i,segment:Qd(r),local:!0}}}}});var Bl,vp,f1=N(()=>{"use strict";Ps();Bl=class{static{o(this,"MultiMap")}constructor(e){if(this.map=new Map,e)for(let[r,n]of e)this.add(r,n)}get size(){return zm.sum(en(this.map.values()).map(e=>e.length))}clear(){this.map.clear()}delete(e,r){if(r===void 0)return this.map.delete(e);{let n=this.map.get(e);if(n){let i=n.indexOf(r);if(i>=0)return n.length===1?this.map.delete(e):n.splice(i,1),!0}return!1}}get(e){var r;return(r=this.map.get(e))!==null&&r!==void 0?r:[]}has(e,r){if(r===void 0)return this.map.has(e);{let n=this.map.get(e);return n?n.indexOf(r)>=0:!1}}add(e,r){return this.map.has(e)?this.map.get(e).push(r):this.map.set(e,[r]),this}addAll(e,r){return this.map.has(e)?this.map.get(e).push(...r):this.map.set(e,Array.from(r)),this}forEach(e){this.map.forEach((r,n)=>r.forEach(i=>e(i,n,this)))}[Symbol.iterator](){return this.entries().iterator()}entries(){return en(this.map.entries()).flatMap(([e,r])=>r.map(n=>[e,n]))}keys(){return en(this.map.keys())}values(){return en(this.map.values()).flat()}entriesGroupedByKey(){return en(this.map.entries())}},vp=class{static{o(this,"BiMap")}get size(){return this.map.size}constructor(e){if(this.map=new Map,this.inverse=new Map,e)for(let[r,n]of e)this.set(r,n)}clear(){this.map.clear(),this.inverse.clear()}set(e,r){return this.map.set(e,r),this.inverse.set(r,e),this}get(e){return this.map.get(e)}getKey(e){return this.inverse.get(e)}delete(e){let r=this.map.get(e);return r!==void 0?(this.map.delete(e),this.inverse.delete(r),!0):!1}}});var Bx,zM=N(()=>{"use strict";qo();is();f1();Yo();Bx=class{static{o(this,"DefaultScopeComputation")}constructor(e){this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider}async computeExports(e,r=yr.CancellationToken.None){return this.computeExportsForNode(e.parseResult.value,e,void 0,r)}async computeExportsForNode(e,r,n=W2,i=yr.CancellationToken.None){let a=[];this.exportNode(e,a,r);for(let s of n(e))await xi(i),this.exportNode(s,a,r);return a}exportNode(e,r,n){let i=this.nameProvider.getName(e);i&&r.push(this.descriptions.createDescription(e,i,n))}async computeLocalScopes(e,r=yr.CancellationToken.None){let n=e.parseResult.value,i=new Bl;for(let a of Nc(n))await xi(r),this.processNode(a,e,i);return i}processNode(e,r,n){let i=e.$container;if(i){let a=this.nameProvider.getName(e);a&&n.add(i,this.descriptions.createDescription(e,a,r))}}}});var d1,Fx,xFe,GM=N(()=>{"use strict";Ps();d1=class{static{o(this,"StreamScope")}constructor(e,r,n){var i;this.elements=e,this.outerScope=r,this.caseInsensitive=(i=n?.caseInsensitive)!==null&&i!==void 0?i:!1}getAllElements(){return this.outerScope?this.elements.concat(this.outerScope.getAllElements()):this.elements}getElement(e){let r=this.caseInsensitive?this.elements.find(n=>n.name.toLowerCase()===e.toLowerCase()):this.elements.find(n=>n.name===e);if(r)return r;if(this.outerScope)return this.outerScope.getElement(e)}},Fx=class{static{o(this,"MapScope")}constructor(e,r,n){var i;this.elements=new Map,this.caseInsensitive=(i=n?.caseInsensitive)!==null&&i!==void 0?i:!1;for(let a of e){let s=this.caseInsensitive?a.name.toLowerCase():a.name;this.elements.set(s,a)}this.outerScope=r}getElement(e){let r=this.caseInsensitive?e.toLowerCase():e,n=this.elements.get(r);if(n)return n;if(this.outerScope)return this.outerScope.getElement(e)}getAllElements(){let e=en(this.elements.values());return this.outerScope&&(e=e.concat(this.outerScope.getAllElements())),e}},xFe={getElement(){},getAllElements(){return I2}}});var p1,$x,xp,_E,m1,DE=N(()=>{"use strict";p1=class{static{o(this,"DisposableCache")}constructor(){this.toDispose=[],this.isDisposed=!1}onDispose(e){this.toDispose.push(e)}dispose(){this.throwIfDisposed(),this.clear(),this.isDisposed=!0,this.toDispose.forEach(e=>e.dispose())}throwIfDisposed(){if(this.isDisposed)throw new Error("This cache has already been disposed")}},$x=class extends p1{static{o(this,"SimpleCache")}constructor(){super(...arguments),this.cache=new Map}has(e){return this.throwIfDisposed(),this.cache.has(e)}set(e,r){this.throwIfDisposed(),this.cache.set(e,r)}get(e,r){if(this.throwIfDisposed(),this.cache.has(e))return this.cache.get(e);if(r){let n=r();return this.cache.set(e,n),n}else return}delete(e){return this.throwIfDisposed(),this.cache.delete(e)}clear(){this.throwIfDisposed(),this.cache.clear()}},xp=class extends p1{static{o(this,"ContextCache")}constructor(e){super(),this.cache=new Map,this.converter=e??(r=>r)}has(e,r){return this.throwIfDisposed(),this.cacheForContext(e).has(r)}set(e,r,n){this.throwIfDisposed(),this.cacheForContext(e).set(r,n)}get(e,r,n){this.throwIfDisposed();let i=this.cacheForContext(e);if(i.has(r))return i.get(r);if(n){let a=n();return i.set(r,a),a}else return}delete(e,r){return this.throwIfDisposed(),this.cacheForContext(e).delete(r)}clear(e){if(this.throwIfDisposed(),e){let r=this.converter(e);this.cache.delete(r)}else this.cache.clear()}cacheForContext(e){let r=this.converter(e),n=this.cache.get(r);return n||(n=new Map,this.cache.set(r,n)),n}},_E=class extends xp{static{o(this,"DocumentCache")}constructor(e,r){super(n=>n.toString()),r?(this.toDispose.push(e.workspace.DocumentBuilder.onDocumentPhase(r,n=>{this.clear(n.uri.toString())})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{for(let a of i)this.clear(a)}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{let a=n.concat(i);for(let s of a)this.clear(s)}))}},m1=class extends $x{static{o(this,"WorkspaceCache")}constructor(e,r){super(),r?(this.toDispose.push(e.workspace.DocumentBuilder.onBuildPhase(r,()=>{this.clear()})),this.toDispose.push(e.workspace.DocumentBuilder.onUpdate((n,i)=>{i.length>0&&this.clear()}))):this.toDispose.push(e.workspace.DocumentBuilder.onUpdate(()=>{this.clear()}))}}});var zx,VM=N(()=>{"use strict";GM();is();Ps();DE();zx=class{static{o(this,"DefaultScopeProvider")}constructor(e){this.reflection=e.shared.AstReflection,this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider,this.indexManager=e.shared.workspace.IndexManager,this.globalScopeCache=new m1(e.shared)}getScope(e){let r=[],n=this.reflection.getReferenceType(e),i=Pa(e.container).precomputedScopes;if(i){let s=e.container;do{let l=i.get(s);l.length>0&&r.push(en(l).filter(u=>this.reflection.isSubtype(u.type,n))),s=s.$container}while(s)}let a=this.getGlobalScope(n,e);for(let s=r.length-1;s>=0;s--)a=this.createScope(r[s],a);return a}createScope(e,r,n){return new d1(en(e),r,n)}createScopeForNodes(e,r,n){let i=en(e).map(a=>{let s=this.nameProvider.getName(a);if(s)return this.descriptions.createDescription(a,s)}).nonNullable();return new d1(i,r,n)}getGlobalScope(e,r){return this.globalScopeCache.get(e,()=>new Fx(this.indexManager.allElements(e)))}}});function UM(t){return typeof t.$comment=="string"}function qle(t){return typeof t=="object"&&!!t&&("$ref"in t||"$error"in t)}var Gx,LE=N(()=>{"use strict";OM();Rl();is();Ol();o(UM,"isAstNodeWithComment");o(qle,"isIntermediateReference");Gx=class{static{o(this,"DefaultJsonSerializer")}constructor(e){this.ignoreProperties=new Set(["$container","$containerProperty","$containerIndex","$document","$cstNode"]),this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider,this.commentProvider=e.documentation.CommentProvider}serialize(e,r){let n=r??{},i=r?.replacer,a=o((l,u)=>this.replacer(l,u,n),"defaultReplacer"),s=i?(l,u)=>i(l,u,a):a;try{return this.currentDocument=Pa(e),JSON.stringify(e,s,r?.space)}finally{this.currentDocument=void 0}}deserialize(e,r){let n=r??{},i=JSON.parse(e);return this.linkNode(i,i,n),i}replacer(e,r,{refText:n,sourceText:i,textRegions:a,comments:s,uriConverter:l}){var u,h,f,d;if(!this.ignoreProperties.has(e))if(va(r)){let p=r.ref,m=n?r.$refText:void 0;if(p){let g=Pa(p),y="";this.currentDocument&&this.currentDocument!==g&&(l?y=l(g.uri,r):y=g.uri.toString());let v=this.astNodeLocator.getAstNodePath(p);return{$ref:`${y}#${v}`,$refText:m}}else return{$error:(h=(u=r.error)===null||u===void 0?void 0:u.message)!==null&&h!==void 0?h:"Could not resolve reference",$refText:m}}else if(ii(r)){let p;if(a&&(p=this.addAstNodeRegionWithAssignmentsTo(Object.assign({},r)),(!e||r.$document)&&p?.$textRegion&&(p.$textRegion.documentURI=(f=this.currentDocument)===null||f===void 0?void 0:f.uri.toString())),i&&!e&&(p??(p=Object.assign({},r)),p.$sourceText=(d=r.$cstNode)===null||d===void 0?void 0:d.text),s){p??(p=Object.assign({},r));let m=this.commentProvider.getComment(r);m&&(p.$comment=m.replace(/\r/g,""))}return p??r}else return r}addAstNodeRegionWithAssignmentsTo(e){let r=o(n=>({offset:n.offset,end:n.end,length:n.length,range:n.range}),"createDocumentSegment");if(e.$cstNode){let n=e.$textRegion=r(e.$cstNode),i=n.assignments={};return Object.keys(e).filter(a=>!a.startsWith("$")).forEach(a=>{let s=oN(e.$cstNode,a).map(r);s.length!==0&&(i[a]=s)}),e}}linkNode(e,r,n,i,a,s){for(let[u,h]of Object.entries(e))if(Array.isArray(h))for(let f=0;f<h.length;f++){let d=h[f];qle(d)?h[f]=this.reviveReference(e,u,r,d,n):ii(d)&&this.linkNode(d,r,n,e,u,f)}else qle(h)?e[u]=this.reviveReference(e,u,r,h,n):ii(h)&&this.linkNode(h,r,n,e,u);let l=e;l.$container=i,l.$containerProperty=a,l.$containerIndex=s}reviveReference(e,r,n,i,a){let s=i.$refText,l=i.$error;if(i.$ref){let u=this.getRefNode(n,i.$ref,a.uriConverter);if(ii(u))return s||(s=this.nameProvider.getName(u)),{$refText:s??"",ref:u};l=u}if(l){let u={$refText:s??""};return u.error={container:e,property:r,message:l,reference:u},u}else return}getRefNode(e,r,n){try{let i=r.indexOf("#");if(i===0){let u=this.astNodeLocator.getAstNode(e,r.substring(1));return u||"Could not resolve path: "+r}if(i<0){let u=n?n(r):us.parse(r),h=this.langiumDocuments.getDocument(u);return h?h.parseResult.value:"Could not find document for URI: "+r}let a=n?n(r.substring(0,i)):us.parse(r.substring(0,i)),s=this.langiumDocuments.getDocument(a);if(!s)return"Could not find document for URI: "+r;if(i===r.length-1)return s.parseResult.value;let l=this.astNodeLocator.getAstNode(s.parseResult.value,r.substring(i+1));return l||"Could not resolve URI: "+r}catch(i){return String(i)}}}});var Vx,HM=N(()=>{"use strict";Fc();Vx=class{static{o(this,"DefaultServiceRegistry")}get map(){return this.fileExtensionMap}constructor(e){this.languageIdMap=new Map,this.fileExtensionMap=new Map,this.textDocuments=e?.workspace.TextDocuments}register(e){let r=e.LanguageMetaData;for(let n of r.fileExtensions)this.fileExtensionMap.has(n)&&console.warn(`The file extension ${n} is used by multiple languages. It is now assigned to '${r.languageId}'.`),this.fileExtensionMap.set(n,e);this.languageIdMap.set(r.languageId,e),this.languageIdMap.size===1?this.singleton=e:this.singleton=void 0}getServices(e){var r,n;if(this.singleton!==void 0)return this.singleton;if(this.languageIdMap.size===0)throw new Error("The service registry is empty. Use `register` to register the services of a language.");let i=(n=(r=this.textDocuments)===null||r===void 0?void 0:r.get(e))===null||n===void 0?void 0:n.languageId;if(i!==void 0){let l=this.languageIdMap.get(i);if(l)return l}let a=hs.extname(e),s=this.fileExtensionMap.get(a);if(!s)throw i?new Error(`The service registry contains no services for the extension '${a}' for language '${i}'.`):new Error(`The service registry contains no services for the extension '${a}'.`);return s}hasServices(e){try{return this.getServices(e),!0}catch{return!1}}get all(){return Array.from(this.languageIdMap.values())}}});function bp(t){return{code:t}}var g1,Ux,Hx=N(()=>{"use strict";Xo();f1();Yo();Ps();o(bp,"diagnosticData");(function(t){t.all=["fast","slow","built-in"]})(g1||(g1={}));Ux=class{static{o(this,"ValidationRegistry")}constructor(e){this.entries=new Bl,this.entriesBefore=[],this.entriesAfter=[],this.reflection=e.shared.AstReflection}register(e,r=this,n="fast"){if(n==="built-in")throw new Error("The 'built-in' category is reserved for lexer, parser, and linker errors.");for(let[i,a]of Object.entries(e)){let s=a;if(Array.isArray(s))for(let l of s){let u={check:this.wrapValidationException(l,r),category:n};this.addEntry(i,u)}else if(typeof s=="function"){let l={check:this.wrapValidationException(s,r),category:n};this.addEntry(i,l)}else Lc(s)}}wrapValidationException(e,r){return async(n,i,a)=>{await this.handleException(()=>e.call(r,n,i,a),"An error occurred during validation",i,n)}}async handleException(e,r,n,i){try{await e()}catch(a){if(Bc(a))throw a;console.error(`${r}:`,a),a instanceof Error&&a.stack&&console.error(a.stack);let s=a instanceof Error?a.message:String(a);n("error",`${r}: ${s}`,{node:i})}}addEntry(e,r){if(e==="AstNode"){this.entries.add("AstNode",r);return}for(let n of this.reflection.getAllSubTypes(e))this.entries.add(n,r)}getChecks(e,r){let n=en(this.entries.get(e)).concat(this.entries.get("AstNode"));return r&&(n=n.filter(i=>r.includes(i.category))),n.map(i=>i.check)}registerBeforeDocument(e,r=this){this.entriesBefore.push(this.wrapPreparationException(e,"An error occurred during set-up of the validation",r))}registerAfterDocument(e,r=this){this.entriesAfter.push(this.wrapPreparationException(e,"An error occurred during tear-down of the validation",r))}wrapPreparationException(e,r,n){return async(i,a,s,l)=>{await this.handleException(()=>e.call(n,i,a,s,l),r,a,i)}}get checksBefore(){return this.entriesBefore}get checksAfter(){return this.entriesAfter}}});function Yle(t){if(t.range)return t.range;let e;return typeof t.property=="string"?e=Q2(t.node.$cstNode,t.property,t.index):typeof t.keyword=="string"&&(e=cN(t.node.$cstNode,t.keyword,t.index)),e??(e=t.node.$cstNode),e?e.range:{start:{line:0,character:0},end:{line:0,character:0}}}function RE(t){switch(t){case"error":return 1;case"warning":return 2;case"info":return 3;case"hint":return 4;default:throw new Error("Invalid diagnostic severity: "+t)}}function Xle(t){switch(t){case"error":return bp(jo.LexingError);case"warning":return bp(jo.LexingWarning);case"info":return bp(jo.LexingInfo);case"hint":return bp(jo.LexingHint);default:throw new Error("Invalid diagnostic severity: "+t)}}var Wx,jo,WM=N(()=>{"use strict";qo();Ol();is();Nl();Yo();Hx();Wx=class{static{o(this,"DefaultDocumentValidator")}constructor(e){this.validationRegistry=e.validation.ValidationRegistry,this.metadata=e.LanguageMetaData}async validateDocument(e,r={},n=yr.CancellationToken.None){let i=e.parseResult,a=[];if(await xi(n),(!r.categories||r.categories.includes("built-in"))&&(this.processLexingErrors(i,a,r),r.stopAfterLexingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===jo.LexingError})||(this.processParsingErrors(i,a,r),r.stopAfterParsingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===jo.ParsingError}))||(this.processLinkingErrors(e,a,r),r.stopAfterLinkingErrors&&a.some(s=>{var l;return((l=s.data)===null||l===void 0?void 0:l.code)===jo.LinkingError}))))return a;try{a.push(...await this.validateAst(i.value,r,n))}catch(s){if(Bc(s))throw s;console.error("An error occurred during validation:",s)}return await xi(n),a}processLexingErrors(e,r,n){var i,a,s;let l=[...e.lexerErrors,...(a=(i=e.lexerReport)===null||i===void 0?void 0:i.diagnostics)!==null&&a!==void 0?a:[]];for(let u of l){let h=(s=u.severity)!==null&&s!==void 0?s:"error",f={severity:RE(h),range:{start:{line:u.line-1,character:u.column-1},end:{line:u.line-1,character:u.column+u.length-1}},message:u.message,data:Xle(h),source:this.getSource()};r.push(f)}}processParsingErrors(e,r,n){for(let i of e.parserErrors){let a;if(isNaN(i.token.startOffset)){if("previousToken"in i){let s=i.previousToken;if(isNaN(s.startOffset)){let l={line:0,character:0};a={start:l,end:l}}else{let l={line:s.endLine-1,character:s.endColumn};a={start:l,end:l}}}}else a=Gm(i.token);if(a){let s={severity:RE("error"),range:a,message:i.message,data:bp(jo.ParsingError),source:this.getSource()};r.push(s)}}}processLinkingErrors(e,r,n){for(let i of e.references){let a=i.error;if(a){let s={node:a.container,property:a.property,index:a.index,data:{code:jo.LinkingError,containerType:a.container.$type,property:a.property,refText:a.reference.$refText}};r.push(this.toDiagnostic("error",a.message,s))}}}async validateAst(e,r,n=yr.CancellationToken.None){let i=[],a=o((s,l,u)=>{i.push(this.toDiagnostic(s,l,u))},"acceptor");return await this.validateAstBefore(e,r,a,n),await this.validateAstNodes(e,r,a,n),await this.validateAstAfter(e,r,a,n),i}async validateAstBefore(e,r,n,i=yr.CancellationToken.None){var a;let s=this.validationRegistry.checksBefore;for(let l of s)await xi(i),await l(e,n,(a=r.categories)!==null&&a!==void 0?a:[],i)}async validateAstNodes(e,r,n,i=yr.CancellationToken.None){await Promise.all(Wo(e).map(async a=>{await xi(i);let s=this.validationRegistry.getChecks(a.$type,r.categories);for(let l of s)await l(a,n,i)}))}async validateAstAfter(e,r,n,i=yr.CancellationToken.None){var a;let s=this.validationRegistry.checksAfter;for(let l of s)await xi(i),await l(e,n,(a=r.categories)!==null&&a!==void 0?a:[],i)}toDiagnostic(e,r,n){return{message:r,range:Yle(n),severity:RE(e),code:n.code,codeDescription:n.codeDescription,tags:n.tags,relatedInformation:n.relatedInformation,data:n.data,source:this.getSource()}}getSource(){return this.metadata.languageId}};o(Yle,"getDiagnosticRange");o(RE,"toDiagnosticSeverity");o(Xle,"toDiagnosticData");(function(t){t.LexingError="lexing-error",t.LexingWarning="lexing-warning",t.LexingInfo="lexing-info",t.LexingHint="lexing-hint",t.ParsingError="parsing-error",t.LinkingError="linking-error"})(jo||(jo={}))});var qx,Yx,qM=N(()=>{"use strict";qo();Rl();is();Nl();Yo();Fc();qx=class{static{o(this,"DefaultAstNodeDescriptionProvider")}constructor(e){this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider}createDescription(e,r,n){let i=n??Pa(e);r??(r=this.nameProvider.getName(e));let a=this.astNodeLocator.getAstNodePath(e);if(!r)throw new Error(`Node at path ${a} has no name.`);let s,l=o(()=>{var u;return s??(s=Qd((u=this.nameProvider.getNameNode(e))!==null&&u!==void 0?u:e.$cstNode))},"nameSegmentGetter");return{node:e,name:r,get nameSegment(){return l()},selectionSegment:Qd(e.$cstNode),type:e.$type,documentUri:i.uri,path:a}}},Yx=class{static{o(this,"DefaultReferenceDescriptionProvider")}constructor(e){this.nodeLocator=e.workspace.AstNodeLocator}async createDescriptions(e,r=yr.CancellationToken.None){let n=[],i=e.parseResult.value;for(let a of Wo(i))await xi(r),Ag(a).filter(s=>!jd(s)).forEach(s=>{let l=this.createDescription(s);l&&n.push(l)});return n}createDescription(e){let r=e.reference.$nodeDescription,n=e.reference.$refNode;if(!r||!n)return;let i=Pa(e.container).uri;return{sourceUri:i,sourcePath:this.nodeLocator.getAstNodePath(e.container),targetUri:r.documentUri,targetPath:r.path,segment:Qd(n),local:hs.equals(r.documentUri,i)}}}});var Xx,YM=N(()=>{"use strict";Xx=class{static{o(this,"DefaultAstNodeLocator")}constructor(){this.segmentSeparator="/",this.indexSeparator="@"}getAstNodePath(e){if(e.$container){let r=this.getAstNodePath(e.$container),n=this.getPathSegment(e);return r+this.segmentSeparator+n}return""}getPathSegment({$containerProperty:e,$containerIndex:r}){if(!e)throw new Error("Missing '$containerProperty' in AST node.");return r!==void 0?e+this.indexSeparator+r:e}getAstNode(e,r){return r.split(this.segmentSeparator).reduce((i,a)=>{if(!i||a.length===0)return i;let s=a.indexOf(this.indexSeparator);if(s>0){let l=a.substring(0,s),u=parseInt(a.substring(s+1)),h=i[l];return h?.[u]}return i[a]},e)}}});var Kn={};var NE=N(()=>{"use strict";Sr(Kn,Sa(LM(),1))});var jx,XM=N(()=>{"use strict";NE();Yo();jx=class{static{o(this,"DefaultConfigurationProvider")}constructor(e){this._ready=new cs,this.settings={},this.workspaceConfig=!1,this.onConfigurationSectionUpdateEmitter=new Kn.Emitter,this.serviceRegistry=e.ServiceRegistry}get ready(){return this._ready.promise}initialize(e){var r,n;this.workspaceConfig=(n=(r=e.capabilities.workspace)===null||r===void 0?void 0:r.configuration)!==null&&n!==void 0?n:!1}async initialized(e){if(this.workspaceConfig){if(e.register){let r=this.serviceRegistry.all;e.register({section:r.map(n=>this.toSectionName(n.LanguageMetaData.languageId))})}if(e.fetchConfiguration){let r=this.serviceRegistry.all.map(i=>({section:this.toSectionName(i.LanguageMetaData.languageId)})),n=await e.fetchConfiguration(r);r.forEach((i,a)=>{this.updateSectionConfiguration(i.section,n[a])})}}this._ready.resolve()}updateConfiguration(e){e.settings&&Object.keys(e.settings).forEach(r=>{let n=e.settings[r];this.updateSectionConfiguration(r,n),this.onConfigurationSectionUpdateEmitter.fire({section:r,configuration:n})})}updateSectionConfiguration(e,r){this.settings[e]=r}async getConfiguration(e,r){await this.ready;let n=this.toSectionName(e);if(this.settings[n])return this.settings[n][r]}toSectionName(e){return`${e}`}get onConfigurationSectionUpdate(){return this.onConfigurationSectionUpdateEmitter.event}}});var ff,jM=N(()=>{"use strict";(function(t){function e(r){return{dispose:o(async()=>await r(),"dispose")}}o(e,"create"),t.create=e})(ff||(ff={}))});var Kx,KM=N(()=>{"use strict";qo();jM();f1();Yo();Ps();Hx();h1();Kx=class{static{o(this,"DefaultDocumentBuilder")}constructor(e){this.updateBuildOptions={validation:{categories:["built-in","fast"]}},this.updateListeners=[],this.buildPhaseListeners=new Bl,this.documentPhaseListeners=new Bl,this.buildState=new Map,this.documentBuildWaiters=new Map,this.currentState=kn.Changed,this.langiumDocuments=e.workspace.LangiumDocuments,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.textDocuments=e.workspace.TextDocuments,this.indexManager=e.workspace.IndexManager,this.serviceRegistry=e.ServiceRegistry}async build(e,r={},n=yr.CancellationToken.None){var i,a;for(let s of e){let l=s.uri.toString();if(s.state===kn.Validated){if(typeof r.validation=="boolean"&&r.validation)s.state=kn.IndexedReferences,s.diagnostics=void 0,this.buildState.delete(l);else if(typeof r.validation=="object"){let u=this.buildState.get(l),h=(i=u?.result)===null||i===void 0?void 0:i.validationChecks;if(h){let d=((a=r.validation.categories)!==null&&a!==void 0?a:g1.all).filter(p=>!h.includes(p));d.length>0&&(this.buildState.set(l,{completed:!1,options:{validation:Object.assign(Object.assign({},r.validation),{categories:d})},result:u.result}),s.state=kn.IndexedReferences)}}}else this.buildState.delete(l)}this.currentState=kn.Changed,await this.emitUpdate(e.map(s=>s.uri),[]),await this.buildDocuments(e,r,n)}async update(e,r,n=yr.CancellationToken.None){this.currentState=kn.Changed;for(let s of r)this.langiumDocuments.deleteDocument(s),this.buildState.delete(s.toString()),this.indexManager.remove(s);for(let s of e){if(!this.langiumDocuments.invalidateDocument(s)){let u=this.langiumDocumentFactory.fromModel({$type:"INVALID"},s);u.state=kn.Changed,this.langiumDocuments.addDocument(u)}this.buildState.delete(s.toString())}let i=en(e).concat(r).map(s=>s.toString()).toSet();this.langiumDocuments.all.filter(s=>!i.has(s.uri.toString())&&this.shouldRelink(s,i)).forEach(s=>{this.serviceRegistry.getServices(s.uri).references.Linker.unlink(s),s.state=Math.min(s.state,kn.ComputedScopes),s.diagnostics=void 0}),await this.emitUpdate(e,r),await xi(n);let a=this.sortDocuments(this.langiumDocuments.all.filter(s=>{var l;return s.state<kn.Linked||!(!((l=this.buildState.get(s.uri.toString()))===null||l===void 0)&&l.completed)}).toArray());await this.buildDocuments(a,this.updateBuildOptions,n)}async emitUpdate(e,r){await Promise.all(this.updateListeners.map(n=>n(e,r)))}sortDocuments(e){let r=0,n=e.length-1;for(;r<n;){for(;r<e.length&&this.hasTextDocument(e[r]);)r++;for(;n>=0&&!this.hasTextDocument(e[n]);)n--;r<n&&([e[r],e[n]]=[e[n],e[r]])}return e}hasTextDocument(e){var r;return!!(!((r=this.textDocuments)===null||r===void 0)&&r.get(e.uri))}shouldRelink(e,r){return e.references.some(n=>n.error!==void 0)?!0:this.indexManager.isAffected(e,r)}onUpdate(e){return this.updateListeners.push(e),ff.create(()=>{let r=this.updateListeners.indexOf(e);r>=0&&this.updateListeners.splice(r,1)})}async buildDocuments(e,r,n){this.prepareBuild(e,r),await this.runCancelable(e,kn.Parsed,n,a=>this.langiumDocumentFactory.update(a,n)),await this.runCancelable(e,kn.IndexedContent,n,a=>this.indexManager.updateContent(a,n)),await this.runCancelable(e,kn.ComputedScopes,n,async a=>{let s=this.serviceRegistry.getServices(a.uri).references.ScopeComputation;a.precomputedScopes=await s.computeLocalScopes(a,n)}),await this.runCancelable(e,kn.Linked,n,a=>this.serviceRegistry.getServices(a.uri).references.Linker.link(a,n)),await this.runCancelable(e,kn.IndexedReferences,n,a=>this.indexManager.updateReferences(a,n));let i=e.filter(a=>this.shouldValidate(a));await this.runCancelable(i,kn.Validated,n,a=>this.validate(a,n));for(let a of e){let s=this.buildState.get(a.uri.toString());s&&(s.completed=!0)}}prepareBuild(e,r){for(let n of e){let i=n.uri.toString(),a=this.buildState.get(i);(!a||a.completed)&&this.buildState.set(i,{completed:!1,options:r,result:a?.result})}}async runCancelable(e,r,n,i){let a=e.filter(l=>l.state<r);for(let l of a)await xi(n),await i(l),l.state=r,await this.notifyDocumentPhase(l,r,n);let s=e.filter(l=>l.state===r);await this.notifyBuildPhase(s,r,n),this.currentState=r}onBuildPhase(e,r){return this.buildPhaseListeners.add(e,r),ff.create(()=>{this.buildPhaseListeners.delete(e,r)})}onDocumentPhase(e,r){return this.documentPhaseListeners.add(e,r),ff.create(()=>{this.documentPhaseListeners.delete(e,r)})}waitUntil(e,r,n){let i;if(r&&"path"in r?i=r:n=r,n??(n=yr.CancellationToken.None),i){let a=this.langiumDocuments.getDocument(i);if(a&&a.state>e)return Promise.resolve(i)}return this.currentState>=e?Promise.resolve(void 0):n.isCancellationRequested?Promise.reject(Pc):new Promise((a,s)=>{let l=this.onBuildPhase(e,()=>{if(l.dispose(),u.dispose(),i){let h=this.langiumDocuments.getDocument(i);a(h?.uri)}else a(void 0)}),u=n.onCancellationRequested(()=>{l.dispose(),u.dispose(),s(Pc)})})}async notifyDocumentPhase(e,r,n){let a=this.documentPhaseListeners.get(r).slice();for(let s of a)try{await s(e,n)}catch(l){if(!Bc(l))throw l}}async notifyBuildPhase(e,r,n){if(e.length===0)return;let a=this.buildPhaseListeners.get(r).slice();for(let s of a)await xi(n),await s(e,n)}shouldValidate(e){return!!this.getBuildOptions(e).validation}async validate(e,r){var n,i;let a=this.serviceRegistry.getServices(e.uri).validation.DocumentValidator,s=this.getBuildOptions(e).validation,l=typeof s=="object"?s:void 0,u=await a.validateDocument(e,l,r);e.diagnostics?e.diagnostics.push(...u):e.diagnostics=u;let h=this.buildState.get(e.uri.toString());if(h){(n=h.result)!==null&&n!==void 0||(h.result={});let f=(i=l?.categories)!==null&&i!==void 0?i:g1.all;h.result.validationChecks?h.result.validationChecks.push(...f):h.result.validationChecks=[...f]}}getBuildOptions(e){var r,n;return(n=(r=this.buildState.get(e.uri.toString()))===null||r===void 0?void 0:r.options)!==null&&n!==void 0?n:{}}}});var Qx,QM=N(()=>{"use strict";is();DE();qo();Ps();Fc();Qx=class{static{o(this,"DefaultIndexManager")}constructor(e){this.symbolIndex=new Map,this.symbolByTypeIndex=new xp,this.referenceIndex=new Map,this.documents=e.workspace.LangiumDocuments,this.serviceRegistry=e.ServiceRegistry,this.astReflection=e.AstReflection}findAllReferences(e,r){let n=Pa(e).uri,i=[];return this.referenceIndex.forEach(a=>{a.forEach(s=>{hs.equals(s.targetUri,n)&&s.targetPath===r&&i.push(s)})}),en(i)}allElements(e,r){let n=en(this.symbolIndex.keys());return r&&(n=n.filter(i=>!r||r.has(i))),n.map(i=>this.getFileDescriptions(i,e)).flat()}getFileDescriptions(e,r){var n;return r?this.symbolByTypeIndex.get(e,r,()=>{var a;return((a=this.symbolIndex.get(e))!==null&&a!==void 0?a:[]).filter(l=>this.astReflection.isSubtype(l.type,r))}):(n=this.symbolIndex.get(e))!==null&&n!==void 0?n:[]}remove(e){let r=e.toString();this.symbolIndex.delete(r),this.symbolByTypeIndex.clear(r),this.referenceIndex.delete(r)}async updateContent(e,r=yr.CancellationToken.None){let i=await this.serviceRegistry.getServices(e.uri).references.ScopeComputation.computeExports(e,r),a=e.uri.toString();this.symbolIndex.set(a,i),this.symbolByTypeIndex.clear(a)}async updateReferences(e,r=yr.CancellationToken.None){let i=await this.serviceRegistry.getServices(e.uri).workspace.ReferenceDescriptionProvider.createDescriptions(e,r);this.referenceIndex.set(e.uri.toString(),i)}isAffected(e,r){let n=this.referenceIndex.get(e.uri.toString());return n?n.some(i=>!i.local&&r.has(i.targetUri.toString())):!1}}});var Zx,ZM=N(()=>{"use strict";qo();Yo();Fc();Zx=class{static{o(this,"DefaultWorkspaceManager")}constructor(e){this.initialBuildOptions={},this._ready=new cs,this.serviceRegistry=e.ServiceRegistry,this.langiumDocuments=e.workspace.LangiumDocuments,this.documentBuilder=e.workspace.DocumentBuilder,this.fileSystemProvider=e.workspace.FileSystemProvider,this.mutex=e.workspace.WorkspaceLock}get ready(){return this._ready.promise}get workspaceFolders(){return this.folders}initialize(e){var r;this.folders=(r=e.workspaceFolders)!==null&&r!==void 0?r:void 0}initialized(e){return this.mutex.write(r=>{var n;return this.initializeWorkspace((n=this.folders)!==null&&n!==void 0?n:[],r)})}async initializeWorkspace(e,r=yr.CancellationToken.None){let n=await this.performStartup(e);await xi(r),await this.documentBuilder.build(n,this.initialBuildOptions,r)}async performStartup(e){let r=this.serviceRegistry.all.flatMap(a=>a.LanguageMetaData.fileExtensions),n=[],i=o(a=>{n.push(a),this.langiumDocuments.hasDocument(a.uri)||this.langiumDocuments.addDocument(a)},"collector");return await this.loadAdditionalDocuments(e,i),await Promise.all(e.map(a=>[a,this.getRootFolder(a)]).map(async a=>this.traverseFolder(...a,r,i))),this._ready.resolve(),n}loadAdditionalDocuments(e,r){return Promise.resolve()}getRootFolder(e){return us.parse(e.uri)}async traverseFolder(e,r,n,i){let a=await this.fileSystemProvider.readDirectory(r);await Promise.all(a.map(async s=>{if(this.includeEntry(e,s,n)){if(s.isDirectory)await this.traverseFolder(e,s.uri,n,i);else if(s.isFile){let l=await this.langiumDocuments.getOrCreateDocument(s.uri);i(l)}}}))}includeEntry(e,r,n){let i=hs.basename(r.uri);if(i.startsWith("."))return!1;if(r.isDirectory)return i!=="node_modules"&&i!=="out";if(r.isFile){let a=hs.extname(r.uri);return n.includes(a)}return!1}}});function IE(t){return Array.isArray(t)&&(t.length===0||"name"in t[0])}function eI(t){return t&&"modes"in t&&"defaultMode"in t}function JM(t){return!IE(t)&&!eI(t)}var Jx,ME,wp,OE=N(()=>{"use strict";cf();Jx=class{static{o(this,"DefaultLexerErrorMessageProvider")}buildUnexpectedCharactersMessage(e,r,n,i,a){return Gg.buildUnexpectedCharactersMessage(e,r,n,i,a)}buildUnableToPopLexerModeMessage(e){return Gg.buildUnableToPopLexerModeMessage(e)}},ME={mode:"full"},wp=class{static{o(this,"DefaultLexer")}constructor(e){this.errorMessageProvider=e.parser.LexerErrorMessageProvider,this.tokenBuilder=e.parser.TokenBuilder;let r=this.tokenBuilder.buildTokens(e.Grammar,{caseInsensitive:e.LanguageMetaData.caseInsensitive});this.tokenTypes=this.toTokenTypeDictionary(r);let n=JM(r)?Object.values(r):r,i=e.LanguageMetaData.mode==="production";this.chevrotainLexer=new Xn(n,{positionTracking:"full",skipValidations:i,errorMessageProvider:this.errorMessageProvider})}get definition(){return this.tokenTypes}tokenize(e,r=ME){var n,i,a;let s=this.chevrotainLexer.tokenize(e);return{tokens:s.tokens,errors:s.errors,hidden:(n=s.groups.hidden)!==null&&n!==void 0?n:[],report:(a=(i=this.tokenBuilder).flushLexingReport)===null||a===void 0?void 0:a.call(i,e)}}toTokenTypeDictionary(e){if(JM(e))return e;let r=eI(e)?Object.values(e.modes).flat():e,n={};return r.forEach(i=>n[i.name]=i),n}};o(IE,"isTokenTypeArray");o(eI,"isIMultiModeLexerDefinition");o(JM,"isTokenTypeDictionary")});function nI(t,e,r){let n,i;typeof t=="string"?(i=e,n=r):(i=t.range.start,n=e),i||(i=jr.create(0,0));let a=Qle(t),s=aI(n),l=wFe({lines:a,position:i,options:s});return CFe({index:0,tokens:l,position:i})}function iI(t,e){let r=aI(e),n=Qle(t);if(n.length===0)return!1;let i=n[0],a=n[n.length-1],s=r.start,l=r.end;return!!s?.exec(i)&&!!l?.exec(a)}function Qle(t){let e="";return typeof t=="string"?e=t:e=t.text,e.split(JR)}function wFe(t){var e,r,n;let i=[],a=t.position.line,s=t.position.character;for(let l=0;l<t.lines.length;l++){let u=l===0,h=l===t.lines.length-1,f=t.lines[l],d=0;if(u&&t.options.start){let m=(e=t.options.start)===null||e===void 0?void 0:e.exec(f);m&&(d=m.index+m[0].length)}else{let m=(r=t.options.line)===null||r===void 0?void 0:r.exec(f);m&&(d=m.index+m[0].length)}if(h){let m=(n=t.options.end)===null||n===void 0?void 0:n.exec(f);m&&(f=f.substring(0,m.index))}if(f=f.substring(0,SFe(f)),rI(f,d)>=f.length){if(i.length>0){let m=jr.create(a,s);i.push({type:"break",content:"",range:Pr.create(m,m)})}}else{jle.lastIndex=d;let m=jle.exec(f);if(m){let g=m[0],y=m[1],v=jr.create(a,s+d),x=jr.create(a,s+d+g.length);i.push({type:"tag",content:y,range:Pr.create(v,x)}),d+=g.length,d=rI(f,d)}if(d<f.length){let g=f.substring(d),y=Array.from(g.matchAll(bFe));i.push(...TFe(y,g,a,s+d))}}a++,s=0}return i.length>0&&i[i.length-1].type==="break"?i.slice(0,-1):i}function TFe(t,e,r,n){let i=[];if(t.length===0){let a=jr.create(r,n),s=jr.create(r,n+e.length);i.push({type:"text",content:e,range:Pr.create(a,s)})}else{let a=0;for(let l of t){let u=l.index,h=e.substring(a,u);h.length>0&&i.push({type:"text",content:e.substring(a,u),range:Pr.create(jr.create(r,a+n),jr.create(r,u+n))});let f=h.length+1,d=l[1];if(i.push({type:"inline-tag",content:d,range:Pr.create(jr.create(r,a+f+n),jr.create(r,a+f+d.length+n))}),f+=d.length,l.length===4){f+=l[2].length;let p=l[3];i.push({type:"text",content:p,range:Pr.create(jr.create(r,a+f+n),jr.create(r,a+f+p.length+n))})}else i.push({type:"text",content:"",range:Pr.create(jr.create(r,a+f+n),jr.create(r,a+f+n))});a=u+l[0].length}let s=e.substring(a);s.length>0&&i.push({type:"text",content:s,range:Pr.create(jr.create(r,a+n),jr.create(r,a+n+s.length))})}return i}function rI(t,e){let r=t.substring(e).match(kFe);return r?e+r.index:t.length}function SFe(t){let e=t.match(EFe);if(e&&typeof e.index=="number")return e.index}function CFe(t){var e,r,n,i;let a=jr.create(t.position.line,t.position.character);if(t.tokens.length===0)return new PE([],Pr.create(a,a));let s=[];for(;t.index<t.tokens.length;){let h=AFe(t,s[s.length-1]);h&&s.push(h)}let l=(r=(e=s[0])===null||e===void 0?void 0:e.range.start)!==null&&r!==void 0?r:a,u=(i=(n=s[s.length-1])===null||n===void 0?void 0:n.range.end)!==null&&i!==void 0?i:a;return new PE(s,Pr.create(l,u))}function AFe(t,e){let r=t.tokens[t.index];if(r.type==="tag")return Jle(t,!1);if(r.type==="text"||r.type==="inline-tag")return Zle(t);_Fe(r,e),t.index++}function _Fe(t,e){if(e){let r=new BE("",t.range);"inlines"in e?e.inlines.push(r):e.content.inlines.push(r)}}function Zle(t){let e=t.tokens[t.index],r=e,n=e,i=[];for(;e&&e.type!=="break"&&e.type!=="tag";)i.push(DFe(t)),n=e,e=t.tokens[t.index];return new tb(i,Pr.create(r.range.start,n.range.end))}function DFe(t){return t.tokens[t.index].type==="inline-tag"?Jle(t,!0):ece(t)}function Jle(t,e){let r=t.tokens[t.index++],n=r.content.substring(1),i=t.tokens[t.index];if(i?.type==="text")if(e){let a=ece(t);return new eb(n,new tb([a],a.range),e,Pr.create(r.range.start,a.range.end))}else{let a=Zle(t);return new eb(n,a,e,Pr.create(r.range.start,a.range.end))}else{let a=r.range;return new eb(n,new tb([],a),e,a)}}function ece(t){let e=t.tokens[t.index++];return new BE(e.content,e.range)}function aI(t){if(!t)return aI({start:"/**",end:"*/",line:"*"});let{start:e,end:r,line:n}=t;return{start:tI(e,!0),end:tI(r,!1),line:tI(n,!0)}}function tI(t,e){if(typeof t=="string"||typeof t=="object"){let r=typeof t=="string"?ap(t):t.source;return e?new RegExp(`^\\s*${r}`):new RegExp(`\\s*${r}\\s*$`)}else return t}function LFe(t,e,r){var n,i;if(t==="linkplain"||t==="linkcode"||t==="link"){let a=e.indexOf(" "),s=e;if(a>0){let u=rI(e,a);s=e.substring(u),e=e.substring(0,a)}return(t==="linkcode"||t==="link"&&r.link==="code")&&(s=`\`${s}\``),(i=(n=r.renderLink)===null||n===void 0?void 0:n.call(r,e,s))!==null&&i!==void 0?i:RFe(e,s)}}function RFe(t,e){try{return us.parse(t,!0),`[${e}](${t})`}catch{return t}}function Kle(t){return t.endsWith(`
+`)?`
+`:`
+
+`}var jle,bFe,kFe,EFe,PE,eb,tb,BE,sI=N(()=>{"use strict";mM();Lg();Fc();o(nI,"parseJSDoc");o(iI,"isJSDoc");o(Qle,"getLines");jle=/\s*(@([\p{L}][\p{L}\p{N}]*)?)/uy,bFe=/\{(@[\p{L}][\p{L}\p{N}]*)(\s*)([^\r\n}]+)?\}/gu;o(wFe,"tokenize");o(TFe,"buildInlineTokens");kFe=/\S/,EFe=/\s*$/;o(rI,"skipWhitespace");o(SFe,"lastCharacter");o(CFe,"parseJSDocComment");o(AFe,"parseJSDocElement");o(_Fe,"appendEmptyLine");o(Zle,"parseJSDocText");o(DFe,"parseJSDocInline");o(Jle,"parseJSDocTag");o(ece,"parseJSDocLine");o(aI,"normalizeOptions");o(tI,"normalizeOption");PE=class{static{o(this,"JSDocCommentImpl")}constructor(e,r){this.elements=e,this.range=r}getTag(e){return this.getAllTags().find(r=>r.name===e)}getTags(e){return this.getAllTags().filter(r=>r.name===e)}getAllTags(){return this.elements.filter(e=>"name"in e)}toString(){let e="";for(let r of this.elements)if(e.length===0)e=r.toString();else{let n=r.toString();e+=Kle(e)+n}return e.trim()}toMarkdown(e){let r="";for(let n of this.elements)if(r.length===0)r=n.toMarkdown(e);else{let i=n.toMarkdown(e);r+=Kle(r)+i}return r.trim()}},eb=class{static{o(this,"JSDocTagImpl")}constructor(e,r,n,i){this.name=e,this.content=r,this.inline=n,this.range=i}toString(){let e=`@${this.name}`,r=this.content.toString();return this.content.inlines.length===1?e=`${e} ${r}`:this.content.inlines.length>1&&(e=`${e}
+${r}`),this.inline?`{${e}}`:e}toMarkdown(e){var r,n;return(n=(r=e?.renderTag)===null||r===void 0?void 0:r.call(e,this))!==null&&n!==void 0?n:this.toMarkdownDefault(e)}toMarkdownDefault(e){let r=this.content.toMarkdown(e);if(this.inline){let a=LFe(this.name,r,e??{});if(typeof a=="string")return a}let n="";e?.tag==="italic"||e?.tag===void 0?n="*":e?.tag==="bold"?n="**":e?.tag==="bold-italic"&&(n="***");let i=`${n}@${this.name}${n}`;return this.content.inlines.length===1?i=`${i} \u2014 ${r}`:this.content.inlines.length>1&&(i=`${i}
+${r}`),this.inline?`{${i}}`:i}};o(LFe,"renderInlineTag");o(RFe,"renderLinkDefault");tb=class{static{o(this,"JSDocTextImpl")}constructor(e,r){this.inlines=e,this.range=r}toString(){let e="";for(let r=0;r<this.inlines.length;r++){let n=this.inlines[r],i=this.inlines[r+1];e+=n.toString(),i&&i.range.start.line>n.range.start.line&&(e+=`
+`)}return e}toMarkdown(e){let r="";for(let n=0;n<this.inlines.length;n++){let i=this.inlines[n],a=this.inlines[n+1];r+=i.toMarkdown(e),a&&a.range.start.line>i.range.start.line&&(r+=`
+`)}return r}},BE=class{static{o(this,"JSDocLineImpl")}constructor(e,r){this.text=e,this.range=r}toString(){return this.text}toMarkdown(){return this.text}};o(Kle,"fillNewlines")});var rb,oI=N(()=>{"use strict";is();sI();rb=class{static{o(this,"JSDocDocumentationProvider")}constructor(e){this.indexManager=e.shared.workspace.IndexManager,this.commentProvider=e.documentation.CommentProvider}getDocumentation(e){let r=this.commentProvider.getComment(e);if(r&&iI(r))return nI(r).toMarkdown({renderLink:o((i,a)=>this.documentationLinkRenderer(e,i,a),"renderLink"),renderTag:o(i=>this.documentationTagRenderer(e,i),"renderTag")})}documentationLinkRenderer(e,r,n){var i;let a=(i=this.findNameInPrecomputedScopes(e,r))!==null&&i!==void 0?i:this.findNameInGlobalScope(e,r);if(a&&a.nameSegment){let s=a.nameSegment.range.start.line+1,l=a.nameSegment.range.start.character+1,u=a.documentUri.with({fragment:`L${s},${l}`});return`[${n}](${u.toString()})`}else return}documentationTagRenderer(e,r){}findNameInPrecomputedScopes(e,r){let i=Pa(e).precomputedScopes;if(!i)return;let a=e;do{let l=i.get(a).find(u=>u.name===r);if(l)return l;a=a.$container}while(a)}findNameInGlobalScope(e,r){return this.indexManager.allElements().find(i=>i.name===r)}}});var nb,lI=N(()=>{"use strict";LE();Nl();nb=class{static{o(this,"DefaultCommentProvider")}constructor(e){this.grammarConfig=()=>e.parser.GrammarConfig}getComment(e){var r;return UM(e)?e.$comment:(r=AR(e.$cstNode,this.grammarConfig().multilineCommentRules))===null||r===void 0?void 0:r.text}}});var ib,cI,uI,hI=N(()=>{"use strict";Yo();NE();ib=class{static{o(this,"DefaultAsyncParser")}constructor(e){this.syncParser=e.parser.LangiumParser}parse(e,r){return Promise.resolve(this.syncParser.parse(e))}},cI=class{static{o(this,"AbstractThreadedAsyncParser")}constructor(e){this.threadCount=8,this.terminationDelay=200,this.workerPool=[],this.queue=[],this.hydrator=e.serializer.Hydrator}initializeWorkers(){for(;this.workerPool.length<this.threadCount;){let e=this.createWorker();e.onReady(()=>{if(this.queue.length>0){let r=this.queue.shift();r&&(e.lock(),r.resolve(e))}}),this.workerPool.push(e)}}async parse(e,r){let n=await this.acquireParserWorker(r),i=new cs,a,s=r.onCancellationRequested(()=>{a=setTimeout(()=>{this.terminateWorker(n)},this.terminationDelay)});return n.parse(e).then(l=>{let u=this.hydrator.hydrate(l);i.resolve(u)}).catch(l=>{i.reject(l)}).finally(()=>{s.dispose(),clearTimeout(a)}),i.promise}terminateWorker(e){e.terminate();let r=this.workerPool.indexOf(e);r>=0&&this.workerPool.splice(r,1)}async acquireParserWorker(e){this.initializeWorkers();for(let n of this.workerPool)if(n.ready)return n.lock(),n;let r=new cs;return e.onCancellationRequested(()=>{let n=this.queue.indexOf(r);n>=0&&this.queue.splice(n,1),r.reject(Pc)}),this.queue.push(r),r.promise}},uI=class{static{o(this,"ParserWorker")}get ready(){return this._ready}get onReady(){return this.onReadyEmitter.event}constructor(e,r,n,i){this.onReadyEmitter=new Kn.Emitter,this.deferred=new cs,this._ready=!0,this._parsing=!1,this.sendMessage=e,this._terminate=i,r(a=>{let s=a;this.deferred.resolve(s),this.unlock()}),n(a=>{this.deferred.reject(a),this.unlock()})}terminate(){this.deferred.reject(Pc),this._terminate()}lock(){this._ready=!1}unlock(){this._parsing=!1,this._ready=!0,this.onReadyEmitter.fire()}parse(e){if(this._parsing)throw new Error("Parser worker is busy");return this._parsing=!0,this.deferred=new cs,this.sendMessage(e),this.deferred.promise}}});var ab,fI=N(()=>{"use strict";qo();Yo();ab=class{static{o(this,"DefaultWorkspaceLock")}constructor(){this.previousTokenSource=new yr.CancellationTokenSource,this.writeQueue=[],this.readQueue=[],this.done=!0}write(e){this.cancelWrite();let r=CE();return this.previousTokenSource=r,this.enqueue(this.writeQueue,e,r.token)}read(e){return this.enqueue(this.readQueue,e)}enqueue(e,r,n=yr.CancellationToken.None){let i=new cs,a={action:r,deferred:i,cancellationToken:n};return e.push(a),this.performNextOperation(),i.promise}async performNextOperation(){if(!this.done)return;let e=[];if(this.writeQueue.length>0)e.push(this.writeQueue.shift());else if(this.readQueue.length>0)e.push(...this.readQueue.splice(0,this.readQueue.length));else return;this.done=!1,await Promise.all(e.map(async({action:r,deferred:n,cancellationToken:i})=>{try{let a=await Promise.resolve().then(()=>r(i));n.resolve(a)}catch(a){Bc(a)?n.resolve(void 0):n.reject(a)}})),this.done=!0,this.performNextOperation()}cancelWrite(){this.previousTokenSource.cancel()}}});var sb,dI=N(()=>{"use strict";gE();Rc();Rl();is();f1();Nl();sb=class{static{o(this,"DefaultHydrator")}constructor(e){this.grammarElementIdMap=new vp,this.tokenTypeIdMap=new vp,this.grammar=e.Grammar,this.lexer=e.parser.Lexer,this.linker=e.references.Linker}dehydrate(e){return{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport?this.dehydrateLexerReport(e.lexerReport):void 0,parserErrors:e.parserErrors.map(r=>Object.assign(Object.assign({},r),{message:r.message})),value:this.dehydrateAstNode(e.value,this.createDehyrationContext(e.value))}}dehydrateLexerReport(e){return e}createDehyrationContext(e){let r=new Map,n=new Map;for(let i of Wo(e))r.set(i,{});if(e.$cstNode)for(let i of Kd(e.$cstNode))n.set(i,{});return{astNodes:r,cstNodes:n}}dehydrateAstNode(e,r){let n=r.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode!==void 0&&(n.$cstNode=this.dehydrateCstNode(e.$cstNode,r));for(let[i,a]of Object.entries(e))if(!i.startsWith("$"))if(Array.isArray(a)){let s=[];n[i]=s;for(let l of a)ii(l)?s.push(this.dehydrateAstNode(l,r)):va(l)?s.push(this.dehydrateReference(l,r)):s.push(l)}else ii(a)?n[i]=this.dehydrateAstNode(a,r):va(a)?n[i]=this.dehydrateReference(a,r):a!==void 0&&(n[i]=a);return n}dehydrateReference(e,r){let n={};return n.$refText=e.$refText,e.$refNode&&(n.$refNode=r.cstNodes.get(e.$refNode)),n}dehydrateCstNode(e,r){let n=r.cstNodes.get(e);return M2(e)?n.fullText=e.fullText:n.grammarSource=this.getGrammarElementId(e.grammarSource),n.hidden=e.hidden,n.astNode=r.astNodes.get(e.astNode),Ll(e)?n.content=e.content.map(i=>this.dehydrateCstNode(i,r)):af(e)&&(n.tokenType=e.tokenType.name,n.offset=e.offset,n.length=e.length,n.startLine=e.range.start.line,n.startColumn=e.range.start.character,n.endLine=e.range.end.line,n.endColumn=e.range.end.character),n}hydrate(e){let r=e.value,n=this.createHydrationContext(r);return"$cstNode"in r&&this.hydrateCstNode(r.$cstNode,n),{lexerErrors:e.lexerErrors,lexerReport:e.lexerReport,parserErrors:e.parserErrors,value:this.hydrateAstNode(r,n)}}createHydrationContext(e){let r=new Map,n=new Map;for(let a of Wo(e))r.set(a,{});let i;if(e.$cstNode)for(let a of Kd(e.$cstNode)){let s;"fullText"in a?(s=new a1(a.fullText),i=s):"content"in a?s=new mp:"tokenType"in a&&(s=this.hydrateCstLeafNode(a)),s&&(n.set(a,s),s.root=i)}return{astNodes:r,cstNodes:n}}hydrateAstNode(e,r){let n=r.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode&&(n.$cstNode=r.cstNodes.get(e.$cstNode));for(let[i,a]of Object.entries(e))if(!i.startsWith("$"))if(Array.isArray(a)){let s=[];n[i]=s;for(let l of a)ii(l)?s.push(this.setParent(this.hydrateAstNode(l,r),n)):va(l)?s.push(this.hydrateReference(l,n,i,r)):s.push(l)}else ii(a)?n[i]=this.setParent(this.hydrateAstNode(a,r),n):va(a)?n[i]=this.hydrateReference(a,n,i,r):a!==void 0&&(n[i]=a);return n}setParent(e,r){return e.$container=r,e}hydrateReference(e,r,n,i){return this.linker.buildReference(r,n,i.cstNodes.get(e.$refNode),e.$refText)}hydrateCstNode(e,r,n=0){let i=r.cstNodes.get(e);if(typeof e.grammarSource=="number"&&(i.grammarSource=this.getGrammarElement(e.grammarSource)),i.astNode=r.astNodes.get(e.astNode),Ll(i))for(let a of e.content){let s=this.hydrateCstNode(a,r,n++);i.content.push(s)}return i}hydrateCstLeafNode(e){let r=this.getTokenType(e.tokenType),n=e.offset,i=e.length,a=e.startLine,s=e.startColumn,l=e.endLine,u=e.endColumn,h=e.hidden;return new pp(n,i,{start:{line:a,character:s},end:{line:l,character:u}},r,h)}getTokenType(e){return this.lexer.definition[e]}getGrammarElementId(e){if(e)return this.grammarElementIdMap.size===0&&this.createGrammarElementIdMap(),this.grammarElementIdMap.get(e)}getGrammarElement(e){return this.grammarElementIdMap.size===0&&this.createGrammarElementIdMap(),this.grammarElementIdMap.getKey(e)}createGrammarElementIdMap(){let e=0;for(let r of Wo(this.grammar))G2(r)&&this.grammarElementIdMap.set(r,e++)}}});function fs(t){return{documentation:{CommentProvider:o(e=>new nb(e),"CommentProvider"),DocumentationProvider:o(e=>new rb(e),"DocumentationProvider")},parser:{AsyncParser:o(e=>new ib(e),"AsyncParser"),GrammarConfig:o(e=>pN(e),"GrammarConfig"),LangiumParser:o(e=>TM(e),"LangiumParser"),CompletionParser:o(e=>bM(e),"CompletionParser"),ValueConverter:o(()=>new yp,"ValueConverter"),TokenBuilder:o(()=>new Uu,"TokenBuilder"),Lexer:o(e=>new wp(e),"Lexer"),ParserErrorMessageProvider:o(()=>new s1,"ParserErrorMessageProvider"),LexerErrorMessageProvider:o(()=>new Jx,"LexerErrorMessageProvider")},workspace:{AstNodeLocator:o(()=>new Xx,"AstNodeLocator"),AstNodeDescriptionProvider:o(e=>new qx(e),"AstNodeDescriptionProvider"),ReferenceDescriptionProvider:o(e=>new Yx(e),"ReferenceDescriptionProvider")},references:{Linker:o(e=>new Ix(e),"Linker"),NameProvider:o(()=>new Ox,"NameProvider"),ScopeProvider:o(e=>new zx(e),"ScopeProvider"),ScopeComputation:o(e=>new Bx(e),"ScopeComputation"),References:o(e=>new Px(e),"References")},serializer:{Hydrator:o(e=>new sb(e),"Hydrator"),JsonSerializer:o(e=>new Gx(e),"JsonSerializer")},validation:{DocumentValidator:o(e=>new Wx(e),"DocumentValidator"),ValidationRegistry:o(e=>new Ux(e),"ValidationRegistry")},shared:o(()=>t.shared,"shared")}}function ds(t){return{ServiceRegistry:o(e=>new Vx(e),"ServiceRegistry"),workspace:{LangiumDocuments:o(e=>new Mx(e),"LangiumDocuments"),LangiumDocumentFactory:o(e=>new Nx(e),"LangiumDocumentFactory"),DocumentBuilder:o(e=>new Kx(e),"DocumentBuilder"),IndexManager:o(e=>new Qx(e),"IndexManager"),WorkspaceManager:o(e=>new Zx(e),"WorkspaceManager"),FileSystemProvider:o(e=>t.fileSystemProvider(e),"FileSystemProvider"),WorkspaceLock:o(()=>new ab,"WorkspaceLock"),ConfigurationProvider:o(e=>new jx(e),"ConfigurationProvider")}}}var pI=N(()=>{"use strict";mN();wM();kM();wE();EM();BM();FM();$M();zM();VM();LE();HM();WM();Hx();qM();YM();XM();KM();h1();QM();ZM();OE();oI();lI();Lx();hI();fI();dI();o(fs,"createDefaultCoreModule");o(ds,"createDefaultSharedCoreModule")});function ui(t,e,r,n,i,a,s,l,u){let h=[t,e,r,n,i,a,s,l,u].reduce(FE,{});return ace(h)}function ice(t){if(t&&t[nce])for(let e of Object.values(t))ice(e);return t}function ace(t,e){let r=new Proxy({},{deleteProperty:o(()=>!1,"deleteProperty"),set:o(()=>{throw new Error("Cannot set property on injected service container")},"set"),get:o((n,i)=>i===nce?!0:rce(n,i,t,e||r),"get"),getOwnPropertyDescriptor:o((n,i)=>(rce(n,i,t,e||r),Object.getOwnPropertyDescriptor(n,i)),"getOwnPropertyDescriptor"),has:o((n,i)=>i in t,"has"),ownKeys:o(()=>[...Object.getOwnPropertyNames(t)],"ownKeys")});return r}function rce(t,e,r,n){if(e in t){if(t[e]instanceof Error)throw new Error("Construction failure. Please make sure that your dependencies are constructable.",{cause:t[e]});if(t[e]===tce)throw new Error('Cycle detected. Please make "'+String(e)+'" lazy. Visit https://langium.org/docs/reference/configuration-services/#resolving-cyclic-dependencies');return t[e]}else if(e in r){let i=r[e];t[e]=tce;try{t[e]=typeof i=="function"?i(n):ace(i,n)}catch(a){throw t[e]=a instanceof Error?a:void 0,a}return t[e]}else return}function FE(t,e){if(e){for(let[r,n]of Object.entries(e))if(n!==void 0){let i=t[r];i!==null&&n!==null&&typeof i=="object"&&typeof n=="object"?t[r]=FE(i,n):t[r]=n}}return t}var mI,nce,tce,gI=N(()=>{"use strict";(function(t){t.merge=(e,r)=>FE(FE({},e),r)})(mI||(mI={}));o(ui,"inject");nce=Symbol("isProxy");o(ice,"eagerLoad");o(ace,"_inject");tce=Symbol();o(rce,"_resolve");o(FE,"_merge")});var sce=N(()=>{"use strict"});var oce=N(()=>{"use strict";lI();oI();sI()});var lce=N(()=>{"use strict"});var cce=N(()=>{"use strict";mN();lce()});var yI,Tp,$E,vI,uce=N(()=>{"use strict";cf();wE();OE();yI={indentTokenName:"INDENT",dedentTokenName:"DEDENT",whitespaceTokenName:"WS",ignoreIndentationDelimiters:[]};(function(t){t.REGULAR="indentation-sensitive",t.IGNORE_INDENTATION="ignore-indentation"})(Tp||(Tp={}));$E=class extends Uu{static{o(this,"IndentationAwareTokenBuilder")}constructor(e=yI){super(),this.indentationStack=[0],this.whitespaceRegExp=/[ \t]+/y,this.options=Object.assign(Object.assign({},yI),e),this.indentTokenType=of({name:this.options.indentTokenName,pattern:this.indentMatcher.bind(this),line_breaks:!1}),this.dedentTokenType=of({name:this.options.dedentTokenName,pattern:this.dedentMatcher.bind(this),line_breaks:!1})}buildTokens(e,r){let n=super.buildTokens(e,r);if(!IE(n))throw new Error("Invalid tokens built by default builder");let{indentTokenName:i,dedentTokenName:a,whitespaceTokenName:s,ignoreIndentationDelimiters:l}=this.options,u,h,f,d=[];for(let p of n){for(let[m,g]of l)p.name===m?p.PUSH_MODE=Tp.IGNORE_INDENTATION:p.name===g&&(p.POP_MODE=!0);p.name===a?u=p:p.name===i?h=p:p.name===s?f=p:d.push(p)}if(!u||!h||!f)throw new Error("Some indentation/whitespace tokens not found!");return l.length>0?{modes:{[Tp.REGULAR]:[u,h,...d,f],[Tp.IGNORE_INDENTATION]:[...d,f]},defaultMode:Tp.REGULAR}:[u,h,f,...d]}flushLexingReport(e){let r=super.flushLexingReport(e);return Object.assign(Object.assign({},r),{remainingDedents:this.flushRemainingDedents(e)})}isStartOfLine(e,r){return r===0||`\r
+`.includes(e[r-1])}matchWhitespace(e,r,n,i){var a;this.whitespaceRegExp.lastIndex=r;let s=this.whitespaceRegExp.exec(e);return{currIndentLevel:(a=s?.[0].length)!==null&&a!==void 0?a:0,prevIndentLevel:this.indentationStack.at(-1),match:s}}createIndentationTokenInstance(e,r,n,i){let a=this.getLineNumber(r,i);return $u(e,n,i,i+n.length,a,a,1,n.length)}getLineNumber(e,r){return e.substring(0,r).split(/\r\n|\r|\n/).length}indentMatcher(e,r,n,i){if(!this.isStartOfLine(e,r))return null;let{currIndentLevel:a,prevIndentLevel:s,match:l}=this.matchWhitespace(e,r,n,i);return a<=s?null:(this.indentationStack.push(a),l)}dedentMatcher(e,r,n,i){var a,s,l,u;if(!this.isStartOfLine(e,r))return null;let{currIndentLevel:h,prevIndentLevel:f,match:d}=this.matchWhitespace(e,r,n,i);if(h>=f)return null;let p=this.indentationStack.lastIndexOf(h);if(p===-1)return this.diagnostics.push({severity:"error",message:`Invalid dedent level ${h} at offset: ${r}. Current indentation stack: ${this.indentationStack}`,offset:r,length:(s=(a=d?.[0])===null||a===void 0?void 0:a.length)!==null&&s!==void 0?s:0,line:this.getLineNumber(e,r),column:1}),null;let m=this.indentationStack.length-p-1,g=(u=(l=e.substring(0,r).match(/[\r\n]+$/))===null||l===void 0?void 0:l[0].length)!==null&&u!==void 0?u:1;for(let y=0;y<m;y++){let v=this.createIndentationTokenInstance(this.dedentTokenType,e,"",r-(g-1));n.push(v),this.indentationStack.pop()}return null}buildTerminalToken(e){let r=super.buildTerminalToken(e),{indentTokenName:n,dedentTokenName:i,whitespaceTokenName:a}=this.options;return r.name===n?this.indentTokenType:r.name===i?this.dedentTokenType:r.name===a?of({name:a,pattern:this.whitespaceRegExp,group:Xn.SKIPPED}):r}flushRemainingDedents(e){let r=[];for(;this.indentationStack.length>1;)r.push(this.createIndentationTokenInstance(this.dedentTokenType,e,"",e.length)),this.indentationStack.pop();return this.indentationStack=[0],r}},vI=class extends wp{static{o(this,"IndentationAwareLexer")}constructor(e){if(super(e),e.parser.TokenBuilder instanceof $E)this.indentationTokenBuilder=e.parser.TokenBuilder;else throw new Error("IndentationAwareLexer requires an accompanying IndentationAwareTokenBuilder")}tokenize(e,r=ME){let n=super.tokenize(e),i=n.report;r?.mode==="full"&&n.tokens.push(...i.remainingDedents),i.remainingDedents=[];let{indentTokenType:a,dedentTokenType:s}=this.indentationTokenBuilder,l=a.tokenTypeIdx,u=s.tokenTypeIdx,h=[],f=n.tokens.length-1;for(let d=0;d<f;d++){let p=n.tokens[d],m=n.tokens[d+1];if(p.tokenTypeIdx===l&&m.tokenTypeIdx===u){d++;continue}h.push(p)}return f>=0&&h.push(n.tokens[f]),n.tokens=h,n}}});var hce=N(()=>{"use strict"});var fce=N(()=>{"use strict";hI();wM();gE();uce();kM();Lx();OE();bE();hce();wE();EM()});var dce=N(()=>{"use strict";BM();FM();$M();GM();zM();VM()});var pce=N(()=>{"use strict";dI();LE()});var zE,ps,xI=N(()=>{"use strict";zE=class{static{o(this,"EmptyFileSystemProvider")}readFile(){throw new Error("No file system is available.")}async readDirectory(){return[]}},ps={fileSystemProvider:o(()=>new zE,"fileSystemProvider")}});function IFe(){let t=ui(ds(ps),MFe),e=ui(fs({shared:t}),NFe);return t.ServiceRegistry.register(e),e}function Hu(t){var e;let r=IFe(),n=r.serializer.JsonSerializer.deserialize(t);return r.shared.workspace.LangiumDocumentFactory.fromModel(n,us.parse(`memory://${(e=n.name)!==null&&e!==void 0?e:"grammar"}.langium`)),n}var NFe,MFe,mce=N(()=>{"use strict";pI();gI();Rc();xI();Fc();NFe={Grammar:o(()=>{},"Grammar"),LanguageMetaData:o(()=>({caseInsensitive:!1,fileExtensions:[".langium"],languageId:"langium"}),"LanguageMetaData")},MFe={AstReflection:o(()=>new Cg,"AstReflection")};o(IFe,"createMinimalGrammarServices");o(Hu,"loadGrammarFromJson")});var Gr={};hr(Gr,{AstUtils:()=>xk,BiMap:()=>vp,Cancellation:()=>yr,ContextCache:()=>xp,CstUtils:()=>ck,DONE_RESULT:()=>Ia,Deferred:()=>cs,Disposable:()=>ff,DisposableCache:()=>p1,DocumentCache:()=>_E,EMPTY_STREAM:()=>I2,ErrorWithLocation:()=>Zd,GrammarUtils:()=>Ek,MultiMap:()=>Bl,OperationCancelled:()=>Pc,Reduction:()=>zm,RegExpUtils:()=>Tk,SimpleCache:()=>$x,StreamImpl:()=>ao,TreeStreamImpl:()=>_c,URI:()=>us,UriUtils:()=>hs,WorkspaceCache:()=>m1,assertUnreachable:()=>Lc,delayNextTick:()=>MM,interruptAndCheck:()=>xi,isOperationCancelled:()=>Bc,loadGrammarFromJson:()=>Hu,setInterruptionPeriod:()=>$le,startCancelableOperation:()=>CE,stream:()=>en});var gce=N(()=>{"use strict";DE();NE();Sr(Gr,Kn);f1();jM();uk();mce();Yo();Ps();Fc();is();qo();Nl();Ol();Lg()});var yce=N(()=>{"use strict";WM();Hx()});var vce=N(()=>{"use strict";qM();YM();XM();KM();h1();xI();QM();fI();ZM()});var xa={};hr(xa,{AbstractAstReflection:()=>Xd,AbstractCstNode:()=>Cx,AbstractLangiumParser:()=>Ax,AbstractParserErrorMessageProvider:()=>vE,AbstractThreadedAsyncParser:()=>cI,AstUtils:()=>xk,BiMap:()=>vp,Cancellation:()=>yr,CompositeCstNodeImpl:()=>mp,ContextCache:()=>xp,CstNodeBuilder:()=>Sx,CstUtils:()=>ck,DEFAULT_TOKENIZE_OPTIONS:()=>ME,DONE_RESULT:()=>Ia,DatatypeSymbol:()=>yE,DefaultAstNodeDescriptionProvider:()=>qx,DefaultAstNodeLocator:()=>Xx,DefaultAsyncParser:()=>ib,DefaultCommentProvider:()=>nb,DefaultConfigurationProvider:()=>jx,DefaultDocumentBuilder:()=>Kx,DefaultDocumentValidator:()=>Wx,DefaultHydrator:()=>sb,DefaultIndexManager:()=>Qx,DefaultJsonSerializer:()=>Gx,DefaultLangiumDocumentFactory:()=>Nx,DefaultLangiumDocuments:()=>Mx,DefaultLexer:()=>wp,DefaultLexerErrorMessageProvider:()=>Jx,DefaultLinker:()=>Ix,DefaultNameProvider:()=>Ox,DefaultReferenceDescriptionProvider:()=>Yx,DefaultReferences:()=>Px,DefaultScopeComputation:()=>Bx,DefaultScopeProvider:()=>zx,DefaultServiceRegistry:()=>Vx,DefaultTokenBuilder:()=>Uu,DefaultValueConverter:()=>yp,DefaultWorkspaceLock:()=>ab,DefaultWorkspaceManager:()=>Zx,Deferred:()=>cs,Disposable:()=>ff,DisposableCache:()=>p1,DocumentCache:()=>_E,DocumentState:()=>kn,DocumentValidator:()=>jo,EMPTY_SCOPE:()=>xFe,EMPTY_STREAM:()=>I2,EmptyFileSystem:()=>ps,EmptyFileSystemProvider:()=>zE,ErrorWithLocation:()=>Zd,GrammarAST:()=>U2,GrammarUtils:()=>Ek,IndentationAwareLexer:()=>vI,IndentationAwareTokenBuilder:()=>$E,JSDocDocumentationProvider:()=>rb,LangiumCompletionParser:()=>Dx,LangiumParser:()=>_x,LangiumParserErrorMessageProvider:()=>s1,LeafCstNodeImpl:()=>pp,LexingMode:()=>Tp,MapScope:()=>Fx,Module:()=>mI,MultiMap:()=>Bl,OperationCancelled:()=>Pc,ParserWorker:()=>uI,Reduction:()=>zm,RegExpUtils:()=>Tk,RootCstNodeImpl:()=>a1,SimpleCache:()=>$x,StreamImpl:()=>ao,StreamScope:()=>d1,TextDocument:()=>c1,TreeStreamImpl:()=>_c,URI:()=>us,UriUtils:()=>hs,ValidationCategory:()=>g1,ValidationRegistry:()=>Ux,ValueConverter:()=>Oc,WorkspaceCache:()=>m1,assertUnreachable:()=>Lc,createCompletionParser:()=>bM,createDefaultCoreModule:()=>fs,createDefaultSharedCoreModule:()=>ds,createGrammarConfig:()=>pN,createLangiumParser:()=>TM,createParser:()=>Rx,delayNextTick:()=>MM,diagnosticData:()=>bp,eagerLoad:()=>ice,getDiagnosticRange:()=>Yle,indentationBuilderDefaultOptions:()=>yI,inject:()=>ui,interruptAndCheck:()=>xi,isAstNode:()=>ii,isAstNodeDescription:()=>kR,isAstNodeWithComment:()=>UM,isCompositeCstNode:()=>Ll,isIMultiModeLexerDefinition:()=>eI,isJSDoc:()=>iI,isLeafCstNode:()=>af,isLinkingError:()=>jd,isNamed:()=>Wle,isOperationCancelled:()=>Bc,isReference:()=>va,isRootCstNode:()=>M2,isTokenTypeArray:()=>IE,isTokenTypeDictionary:()=>JM,loadGrammarFromJson:()=>Hu,parseJSDoc:()=>nI,prepareLangiumParser:()=>Nle,setInterruptionPeriod:()=>$le,startCancelableOperation:()=>CE,stream:()=>en,toDiagnosticData:()=>Xle,toDiagnosticSeverity:()=>RE});var Xo=N(()=>{"use strict";pI();gI();HM();sce();Rl();oce();cce();fce();dce();pce();gce();Sr(xa,Gr);yce();vce();Rc()});function Sce(t){return Fl.isInstance(t,ob)}function Cce(t){return Fl.isInstance(t,y1)}function Ace(t){return Fl.isInstance(t,v1)}function _ce(t){return Fl.isInstance(t,WE)}function Dce(t){return Fl.isInstance(t,x1)}function Lce(t){return Fl.isInstance(t,lb)}function Rce(t){return Fl.isInstance(t,b1)}function Nce(t){return Fl.isInstance(t,cb)}function Mce(t){return Fl.isInstance(t,ub)}function Ice(t){return Fl.isInstance(t,hb)}function Oce(t){return Fl.isInstance(t,fb)}var OFe,Lt,AI,ob,GE,y1,VE,UE,v1,WE,bI,wI,TI,x1,kI,lb,EI,b1,SI,cb,ub,hb,fb,qE,CI,HE,Pce,Fl,xce,PFe,bce,BFe,wce,FFe,Tce,$Fe,kce,zFe,Ece,GFe,VFe,UFe,HFe,WFe,qFe,YFe,co,_I,DI,LI,RI,NI,MI,XFe,jFe,KFe,QFe,w1,Wu,$s,ZFe,zs=N(()=>{"use strict";Xo();Xo();Xo();Xo();OFe=Object.defineProperty,Lt=o((t,e)=>OFe(t,"name",{value:e,configurable:!0}),"__name"),AI="Statement",ob="Architecture";o(Sce,"isArchitecture");Lt(Sce,"isArchitecture");GE="Axis",y1="Branch";o(Cce,"isBranch");Lt(Cce,"isBranch");VE="Checkout",UE="CherryPicking",v1="Commit";o(Ace,"isCommit");Lt(Ace,"isCommit");WE="Common";o(_ce,"isCommon");Lt(_ce,"isCommon");bI="Curve",wI="Edge",TI="Entry",x1="GitGraph";o(Dce,"isGitGraph");Lt(Dce,"isGitGraph");kI="Group",lb="Info";o(Lce,"isInfo");Lt(Lce,"isInfo");EI="Junction",b1="Merge";o(Rce,"isMerge");Lt(Rce,"isMerge");SI="Option",cb="Packet";o(Nce,"isPacket");Lt(Nce,"isPacket");ub="PacketBlock";o(Mce,"isPacketBlock");Lt(Mce,"isPacketBlock");hb="Pie";o(Ice,"isPie");Lt(Ice,"isPie");fb="PieSection";o(Oce,"isPieSection");Lt(Oce,"isPieSection");qE="Radar",CI="Service",HE="Direction",Pce=class extends Xd{static{o(this,"MermaidAstReflection")}static{Lt(this,"MermaidAstReflection")}getAllTypes(){return[ob,GE,y1,VE,UE,v1,WE,bI,HE,wI,TI,x1,kI,lb,EI,b1,SI,cb,ub,hb,fb,qE,CI,AI]}computeIsSubtype(t,e){switch(t){case y1:case VE:case UE:case v1:case b1:return this.isSubtype(AI,e);case HE:return this.isSubtype(x1,e);default:return!1}}getReferenceType(t){let e=`${t.container.$type}:${t.property}`;switch(e){case"Entry:axis":return GE;default:throw new Error(`${e} is not a valid reference id.`)}}getTypeMetaData(t){switch(t){case ob:return{name:ob,properties:[{name:"accDescr"},{name:"accTitle"},{name:"edges",defaultValue:[]},{name:"groups",defaultValue:[]},{name:"junctions",defaultValue:[]},{name:"services",defaultValue:[]},{name:"title"}]};case GE:return{name:GE,properties:[{name:"label"},{name:"name"}]};case y1:return{name:y1,properties:[{name:"name"},{name:"order"}]};case VE:return{name:VE,properties:[{name:"branch"}]};case UE:return{name:UE,properties:[{name:"id"},{name:"parent"},{name:"tags",defaultValue:[]}]};case v1:return{name:v1,properties:[{name:"id"},{name:"message"},{name:"tags",defaultValue:[]},{name:"type"}]};case WE:return{name:WE,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case bI:return{name:bI,properties:[{name:"entries",defaultValue:[]},{name:"label"},{name:"name"}]};case wI:return{name:wI,properties:[{name:"lhsDir"},{name:"lhsGroup",defaultValue:!1},{name:"lhsId"},{name:"lhsInto",defaultValue:!1},{name:"rhsDir"},{name:"rhsGroup",defaultValue:!1},{name:"rhsId"},{name:"rhsInto",defaultValue:!1},{name:"title"}]};case TI:return{name:TI,properties:[{name:"axis"},{name:"value"}]};case x1:return{name:x1,properties:[{name:"accDescr"},{name:"accTitle"},{name:"statements",defaultValue:[]},{name:"title"}]};case kI:return{name:kI,properties:[{name:"icon"},{name:"id"},{name:"in"},{name:"title"}]};case lb:return{name:lb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case EI:return{name:EI,properties:[{name:"id"},{name:"in"}]};case b1:return{name:b1,properties:[{name:"branch"},{name:"id"},{name:"tags",defaultValue:[]},{name:"type"}]};case SI:return{name:SI,properties:[{name:"name"},{name:"value",defaultValue:!1}]};case cb:return{name:cb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"blocks",defaultValue:[]},{name:"title"}]};case ub:return{name:ub,properties:[{name:"end"},{name:"label"},{name:"start"}]};case hb:return{name:hb,properties:[{name:"accDescr"},{name:"accTitle"},{name:"sections",defaultValue:[]},{name:"showData",defaultValue:!1},{name:"title"}]};case fb:return{name:fb,properties:[{name:"label"},{name:"value"}]};case qE:return{name:qE,properties:[{name:"accDescr"},{name:"accTitle"},{name:"axes",defaultValue:[]},{name:"curves",defaultValue:[]},{name:"options",defaultValue:[]},{name:"title"}]};case CI:return{name:CI,properties:[{name:"icon"},{name:"iconText"},{name:"id"},{name:"in"},{name:"title"}]};case HE:return{name:HE,properties:[{name:"accDescr"},{name:"accTitle"},{name:"dir"},{name:"statements",defaultValue:[]},{name:"title"}]};default:return{name:t,properties:[]}}}},Fl=new Pce,PFe=Lt(()=>xce??(xce=Hu('{"$type":"Grammar","isDeclared":true,"name":"Info","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Info","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"info"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"Keyword","value":"showInfo"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"*"}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}')),"InfoGrammar"),BFe=Lt(()=>bce??(bce=Hu(`{"$type":"Grammar","isDeclared":true,"name":"Packet","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Packet","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"packet-beta"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"+"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PacketBlock","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"start","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"end","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}}],"cardinality":"?"},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|'[^']*'/"},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}`)),"PacketGrammar"),FFe=Lt(()=>wce??(wce=Hu('{"$type":"Grammar","isDeclared":true,"name":"Pie","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Pie","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"pie"},{"$type":"Assignment","feature":"showData","operator":"?=","terminal":{"$type":"Keyword","value":"showData"},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"+"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PieSection","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"PIE_SECTION_LABEL","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]+\\"/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"PIE_SECTION_VALUE","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/(0|[1-9][0-9]*)(\\\\.[0-9]+)?/"},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}')),"PieGrammar"),$Fe=Lt(()=>Tce??(Tce=Hu('{"$type":"Grammar","isDeclared":true,"name":"Architecture","imports":[],"rules":[{"$type":"ParserRule","entry":true,"name":"Architecture","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"architecture-beta"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"*"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"groups","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"services","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"junctions","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"edges","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"LeftPort","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"lhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"RightPort","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"rhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Keyword","value":":"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Arrow","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Assignment","feature":"lhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"--"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Keyword","value":"-"}]}]},{"$type":"Assignment","feature":"rhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Group","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"group"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Service","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"service"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"iconText","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}}],"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Junction","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"junction"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Edge","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"lhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Assignment","feature":"lhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"rhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Assignment","feature":"rhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"ARROW_DIRECTION","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"L"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"R"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"T"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"B"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_ID","definition":{"$type":"RegexToken","regex":"/[\\\\w]+/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TEXT_ICON","definition":{"$type":"RegexToken","regex":"/\\\\(\\"[^\\"]+\\"\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_ICON","definition":{"$type":"RegexToken","regex":"/\\\\([\\\\w-:]+\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TITLE","definition":{"$type":"RegexToken","regex":"/\\\\[[\\\\w ]+\\\\]/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_GROUP","definition":{"$type":"RegexToken","regex":"/\\\\{group\\\\}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_INTO","definition":{"$type":"RegexToken","regex":"/<|>/"},"fragment":false,"hidden":false},{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}')),"ArchitectureGrammar"),zFe=Lt(()=>kce??(kce=Hu(`{"$type":"Grammar","isDeclared":true,"name":"GitGraph","interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"rules":[{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"ParserRule","entry":true,"name":"GitGraph","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Keyword","value":":"}]},{"$type":"Keyword","value":"gitGraph:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]},{"$type":"Keyword","value":":"}]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@0"},"arguments":[]},{"$type":"Assignment","feature":"statements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Direction","definition":{"$type":"Assignment","feature":"dir","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"LR"},{"$type":"Keyword","value":"TB"},{"$type":"Keyword","value":"BT"}]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Commit","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"commit"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"msg:","cardinality":"?"},{"$type":"Assignment","feature":"message","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Branch","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"branch"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"order:"},{"$type":"Assignment","feature":"order","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Merge","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"merge"},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]}},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Checkout","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"checkout"},{"$type":"Keyword","value":"switch"}]},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CherryPicking","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"cherry-pick"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"parent:"},{"$type":"Assignment","feature":"parent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+(?=\\\\s)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\\\w([-\\\\./\\\\w]*[-\\\\w])?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|'[^']*'/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"types":[],"usedGrammars":[]}`)),"GitGraphGrammar"),GFe=Lt(()=>Ece??(Ece=Hu(`{"$type":"Grammar","isDeclared":true,"name":"Radar","interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]},{"$type":"Interface","name":"Entry","attributes":[{"$type":"TypeAttribute","name":"axis","isOptional":true,"type":{"$type":"ReferenceType","referenceType":{"$type":"SimpleType","typeRef":{"$ref":"#/rules@12"}}}},{"$type":"TypeAttribute","name":"value","type":{"$type":"SimpleType","primitiveType":"number"},"isOptional":false}],"superTypes":[]}],"rules":[{"$type":"ParserRule","fragment":true,"name":"TitleAndAccessibilities","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"EOL","dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"ParserRule","entry":true,"name":"Radar","definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":"radar-beta:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"radar-beta"},{"$type":"Keyword","value":":"}]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@0"},"arguments":[]},{"$type":"Group","elements":[{"$type":"Keyword","value":"axis"},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"axes","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"curve"},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"curves","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"Assignment","feature":"options","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}}],"cardinality":"*"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"*"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Label","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"["},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@22"},"arguments":[]}},{"$type":"Keyword","value":"]"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Axis","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Curve","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[],"cardinality":"?"},{"$type":"Keyword","value":"{"},{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},{"$type":"Keyword","value":"}"}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","fragment":true,"name":"Entries","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":","},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Assignment","feature":"entries","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]}}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"DetailedEntry","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"axis","operator":"=","terminal":{"$type":"CrossReference","type":{"$ref":"#/rules@12"},"terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]},"deprecatedSyntax":false}},{"$type":"Keyword","value":":","cardinality":"?"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"NumberEntry","returnType":{"$ref":"#/interfaces@1"},"definition":{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Option","definition":{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"showLegend"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"ticks"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"max"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"min"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Keyword","value":"graticule"}},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NUMBER","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/(0|[1-9][0-9]*)(\\\\.[0-9]+)?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"BOOLEAN","type":{"$type":"ReturnType","name":"boolean"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"true"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"false"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"GRATICULE","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"circle"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"polygon"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/[a-zA-Z_][a-zA-Z0-9\\\\-_]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|'[^']*'/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"types":[],"usedGrammars":[]}`)),"RadarGrammar"),VFe={languageId:"info",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},UFe={languageId:"packet",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},HFe={languageId:"pie",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},WFe={languageId:"architecture",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},qFe={languageId:"gitGraph",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},YFe={languageId:"radar",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1,mode:"production"},co={AstReflection:Lt(()=>new Pce,"AstReflection")},_I={Grammar:Lt(()=>PFe(),"Grammar"),LanguageMetaData:Lt(()=>VFe,"LanguageMetaData"),parser:{}},DI={Grammar:Lt(()=>BFe(),"Grammar"),LanguageMetaData:Lt(()=>UFe,"LanguageMetaData"),parser:{}},LI={Grammar:Lt(()=>FFe(),"Grammar"),LanguageMetaData:Lt(()=>HFe,"LanguageMetaData"),parser:{}},RI={Grammar:Lt(()=>$Fe(),"Grammar"),LanguageMetaData:Lt(()=>WFe,"LanguageMetaData"),parser:{}},NI={Grammar:Lt(()=>zFe(),"Grammar"),LanguageMetaData:Lt(()=>qFe,"LanguageMetaData"),parser:{}},MI={Grammar:Lt(()=>GFe(),"Grammar"),LanguageMetaData:Lt(()=>YFe,"LanguageMetaData"),parser:{}},XFe=/accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/,jFe=/accTitle[\t ]*:([^\n\r]*)/,KFe=/title([\t ][^\n\r]*|)/,QFe={ACC_DESCR:XFe,ACC_TITLE:jFe,TITLE:KFe},w1=class extends yp{static{o(this,"AbstractMermaidValueConverter")}static{Lt(this,"AbstractMermaidValueConverter")}runConverter(t,e,r){let n=this.runCommonConverter(t,e,r);return n===void 0&&(n=this.runCustomConverter(t,e,r)),n===void 0?super.runConverter(t,e,r):n}runCommonConverter(t,e,r){let n=QFe[t.name];if(n===void 0)return;let i=n.exec(e);if(i!==null){if(i[1]!==void 0)return i[1].trim().replace(/[\t ]{2,}/gm," ");if(i[2]!==void 0)return i[2].replace(/^\s*/gm,"").replace(/\s+$/gm,"").replace(/[\t ]{2,}/gm," ").replace(/[\n\r]{2,}/gm,`
+`)}}},Wu=class extends w1{static{o(this,"CommonValueConverter")}static{Lt(this,"CommonValueConverter")}runCustomConverter(t,e,r){}},$s=class extends Uu{static{o(this,"AbstractMermaidTokenBuilder")}static{Lt(this,"AbstractMermaidTokenBuilder")}constructor(t){super(),this.keywords=new Set(t)}buildKeywordTokens(t,e,r){let n=super.buildKeywordTokens(t,e,r);return n.forEach(i=>{this.keywords.has(i.name)&&i.PATTERN!==void 0&&(i.PATTERN=new RegExp(i.PATTERN.toString()+"(?:(?=%%)|(?!\\S))"))}),n}},ZFe=class extends $s{static{o(this,"CommonTokenBuilder")}static{Lt(this,"CommonTokenBuilder")}}});function XE(t=ps){let e=ui(ds(t),co),r=ui(fs({shared:e}),NI,YE);return e.ServiceRegistry.register(r),{shared:e,GitGraph:r}}var JFe,YE,II=N(()=>{"use strict";zs();Xo();JFe=class extends $s{static{o(this,"GitGraphTokenBuilder")}static{Lt(this,"GitGraphTokenBuilder")}constructor(){super(["gitGraph"])}},YE={parser:{TokenBuilder:Lt(()=>new JFe,"TokenBuilder"),ValueConverter:Lt(()=>new Wu,"ValueConverter")}};o(XE,"createGitGraphServices");Lt(XE,"createGitGraphServices")});function KE(t=ps){let e=ui(ds(t),co),r=ui(fs({shared:e}),_I,jE);return e.ServiceRegistry.register(r),{shared:e,Info:r}}var e$e,jE,OI=N(()=>{"use strict";zs();Xo();e$e=class extends $s{static{o(this,"InfoTokenBuilder")}static{Lt(this,"InfoTokenBuilder")}constructor(){super(["info","showInfo"])}},jE={parser:{TokenBuilder:Lt(()=>new e$e,"TokenBuilder"),ValueConverter:Lt(()=>new Wu,"ValueConverter")}};o(KE,"createInfoServices");Lt(KE,"createInfoServices")});function ZE(t=ps){let e=ui(ds(t),co),r=ui(fs({shared:e}),DI,QE);return e.ServiceRegistry.register(r),{shared:e,Packet:r}}var t$e,QE,PI=N(()=>{"use strict";zs();Xo();t$e=class extends $s{static{o(this,"PacketTokenBuilder")}static{Lt(this,"PacketTokenBuilder")}constructor(){super(["packet-beta"])}},QE={parser:{TokenBuilder:Lt(()=>new t$e,"TokenBuilder"),ValueConverter:Lt(()=>new Wu,"ValueConverter")}};o(ZE,"createPacketServices");Lt(ZE,"createPacketServices")});function e6(t=ps){let e=ui(ds(t),co),r=ui(fs({shared:e}),LI,JE);return e.ServiceRegistry.register(r),{shared:e,Pie:r}}var r$e,n$e,JE,BI=N(()=>{"use strict";zs();Xo();r$e=class extends $s{static{o(this,"PieTokenBuilder")}static{Lt(this,"PieTokenBuilder")}constructor(){super(["pie","showData"])}},n$e=class extends w1{static{o(this,"PieValueConverter")}static{Lt(this,"PieValueConverter")}runCustomConverter(t,e,r){if(t.name==="PIE_SECTION_LABEL")return e.replace(/"/g,"").trim()}},JE={parser:{TokenBuilder:Lt(()=>new r$e,"TokenBuilder"),ValueConverter:Lt(()=>new n$e,"ValueConverter")}};o(e6,"createPieServices");Lt(e6,"createPieServices")});function r6(t=ps){let e=ui(ds(t),co),r=ui(fs({shared:e}),RI,t6);return e.ServiceRegistry.register(r),{shared:e,Architecture:r}}var i$e,a$e,t6,FI=N(()=>{"use strict";zs();Xo();i$e=class extends $s{static{o(this,"ArchitectureTokenBuilder")}static{Lt(this,"ArchitectureTokenBuilder")}constructor(){super(["architecture"])}},a$e=class extends w1{static{o(this,"ArchitectureValueConverter")}static{Lt(this,"ArchitectureValueConverter")}runCustomConverter(t,e,r){if(t.name==="ARCH_ICON")return e.replace(/[()]/g,"").trim();if(t.name==="ARCH_TEXT_ICON")return e.replace(/["()]/g,"");if(t.name==="ARCH_TITLE")return e.replace(/[[\]]/g,"").trim()}},t6={parser:{TokenBuilder:Lt(()=>new i$e,"TokenBuilder"),ValueConverter:Lt(()=>new a$e,"ValueConverter")}};o(r6,"createArchitectureServices");Lt(r6,"createArchitectureServices")});function i6(t=ps){let e=ui(ds(t),co),r=ui(fs({shared:e}),MI,n6);return e.ServiceRegistry.register(r),{shared:e,Radar:r}}var s$e,n6,$I=N(()=>{"use strict";zs();Xo();s$e=class extends $s{static{o(this,"RadarTokenBuilder")}static{Lt(this,"RadarTokenBuilder")}constructor(){super(["radar-beta"])}},n6={parser:{TokenBuilder:Lt(()=>new s$e,"TokenBuilder"),ValueConverter:Lt(()=>new Wu,"ValueConverter")}};o(i6,"createRadarServices");Lt(i6,"createRadarServices")});var Bce={};hr(Bce,{InfoModule:()=>jE,createInfoServices:()=>KE});var Fce=N(()=>{"use strict";OI();zs()});var $ce={};hr($ce,{PacketModule:()=>QE,createPacketServices:()=>ZE});var zce=N(()=>{"use strict";PI();zs()});var Gce={};hr(Gce,{PieModule:()=>JE,createPieServices:()=>e6});var Vce=N(()=>{"use strict";BI();zs()});var Uce={};hr(Uce,{ArchitectureModule:()=>t6,createArchitectureServices:()=>r6});var Hce=N(()=>{"use strict";FI();zs()});var Wce={};hr(Wce,{GitGraphModule:()=>YE,createGitGraphServices:()=>XE});var qce=N(()=>{"use strict";II();zs()});var Yce={};hr(Yce,{RadarModule:()=>n6,createRadarServices:()=>i6});var Xce=N(()=>{"use strict";$I();zs()});async function uo(t,e){let r=o$e[t];if(!r)throw new Error(`Unknown diagram type: ${t}`);df[t]||await r();let i=df[t].parse(e);if(i.lexerErrors.length>0||i.parserErrors.length>0)throw new l$e(i);return i.value}var df,o$e,l$e,kp=N(()=>{"use strict";II();OI();PI();BI();FI();$I();zs();df={},o$e={info:Lt(async()=>{let{createInfoServices:t}=await Promise.resolve().then(()=>(Fce(),Bce)),e=t().Info.parser.LangiumParser;df.info=e},"info"),packet:Lt(async()=>{let{createPacketServices:t}=await Promise.resolve().then(()=>(zce(),$ce)),e=t().Packet.parser.LangiumParser;df.packet=e},"packet"),pie:Lt(async()=>{let{createPieServices:t}=await Promise.resolve().then(()=>(Vce(),Gce)),e=t().Pie.parser.LangiumParser;df.pie=e},"pie"),architecture:Lt(async()=>{let{createArchitectureServices:t}=await Promise.resolve().then(()=>(Hce(),Uce)),e=t().Architecture.parser.LangiumParser;df.architecture=e},"architecture"),gitGraph:Lt(async()=>{let{createGitGraphServices:t}=await Promise.resolve().then(()=>(qce(),Wce)),e=t().GitGraph.parser.LangiumParser;df.gitGraph=e},"gitGraph"),radar:Lt(async()=>{let{createRadarServices:t}=await Promise.resolve().then(()=>(Xce(),Yce)),e=t().Radar.parser.LangiumParser;df.radar=e},"radar")};o(uo,"parse");Lt(uo,"parse");l$e=class extends Error{static{o(this,"MermaidParseError")}constructor(t){let e=t.lexerErrors.map(n=>n.message).join(`
+`),r=t.parserErrors.map(n=>n.message).join(`
+`);super(`Parsing failed: ${e} ${r}`),this.result=t}static{Lt(this,"MermaidParseError")}}});function $c(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}var T1=N(()=>{"use strict";o($c,"populateCommonDb")});var Kr,a6=N(()=>{"use strict";Kr={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4}});var pf,s6=N(()=>{"use strict";pf=class{constructor(e){this.init=e;this.records=this.init()}static{o(this,"ImperativeState")}reset(){this.records=this.init()}}});function zI(){return j9({length:7})}function u$e(t,e){let r=Object.create(null);return t.reduce((n,i)=>{let a=e(i);return r[a]||(r[a]=!0,n.push(i)),n},[])}function jce(t,e,r){let n=t.indexOf(e);n===-1?t.push(r):t.splice(n,1,r)}function Qce(t){let e=t.reduce((i,a)=>i.seq>a.seq?i:a,t[0]),r="";t.forEach(function(i){i===e?r+=" *":r+=" |"});let n=[r,e.id,e.seq];for(let i in _t.records.branches)_t.records.branches.get(i)===e.id&&n.push(i);if(Y.debug(n.join(" ")),e.parents&&e.parents.length==2&&e.parents[0]&&e.parents[1]){let i=_t.records.commits.get(e.parents[0]);jce(t,e,i),e.parents[1]&&t.push(_t.records.commits.get(e.parents[1]))}else{if(e.parents.length==0)return;if(e.parents[0]){let i=_t.records.commits.get(e.parents[0]);jce(t,e,i)}}t=u$e(t,i=>i.id),Qce(t)}var c$e,Ep,_t,h$e,f$e,d$e,p$e,m$e,g$e,y$e,Kce,v$e,x$e,b$e,w$e,T$e,Zce,k$e,E$e,S$e,o6,GI=N(()=>{"use strict";vt();ir();ji();gr();mi();a6();s6();Ya();c$e=or.gitGraph,Ep=o(()=>Fi({...c$e,...cr().gitGraph}),"getConfig"),_t=new pf(()=>{let t=Ep(),e=t.mainBranchName,r=t.mainBranchOrder;return{mainBranchName:e,commits:new Map,head:null,branchConfig:new Map([[e,{name:e,order:r}]]),branches:new Map([[e,null]]),currBranch:e,direction:"LR",seq:0,options:{}}});o(zI,"getID");o(u$e,"uniqBy");h$e=o(function(t){_t.records.direction=t},"setDirection"),f$e=o(function(t){Y.debug("options str",t),t=t?.trim(),t=t||"{}";try{_t.records.options=JSON.parse(t)}catch(e){Y.error("error while parsing gitGraph options",e.message)}},"setOptions"),d$e=o(function(){return _t.records.options},"getOptions"),p$e=o(function(t){let e=t.msg,r=t.id,n=t.type,i=t.tags;Y.info("commit",e,r,n,i),Y.debug("Entering commit:",e,r,n,i);let a=Ep();r=Ze.sanitizeText(r,a),e=Ze.sanitizeText(e,a),i=i?.map(l=>Ze.sanitizeText(l,a));let s={id:r||_t.records.seq+"-"+zI(),message:e,seq:_t.records.seq++,type:n??Kr.NORMAL,tags:i??[],parents:_t.records.head==null?[]:[_t.records.head.id],branch:_t.records.currBranch};_t.records.head=s,Y.info("main branch",a.mainBranchName),_t.records.commits.set(s.id,s),_t.records.branches.set(_t.records.currBranch,s.id),Y.debug("in pushCommit "+s.id)},"commit"),m$e=o(function(t){let e=t.name,r=t.order;if(e=Ze.sanitizeText(e,Ep()),_t.records.branches.has(e))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${e}")`);_t.records.branches.set(e,_t.records.head!=null?_t.records.head.id:null),_t.records.branchConfig.set(e,{name:e,order:r}),Kce(e),Y.debug("in createBranch")},"branch"),g$e=o(t=>{let e=t.branch,r=t.id,n=t.type,i=t.tags,a=Ep();e=Ze.sanitizeText(e,a),r&&(r=Ze.sanitizeText(r,a));let s=_t.records.branches.get(_t.records.currBranch),l=_t.records.branches.get(e),u=s?_t.records.commits.get(s):void 0,h=l?_t.records.commits.get(l):void 0;if(u&&h&&u.branch===e)throw new Error(`Cannot merge branch '${e}' into itself.`);if(_t.records.currBranch===e){let p=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["branch abc"]},p}if(u===void 0||!u){let p=new Error(`Incorrect usage of "merge". Current branch (${_t.records.currBranch})has no commits`);throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["commit"]},p}if(!_t.records.branches.has(e)){let p=new Error('Incorrect usage of "merge". Branch to be merged ('+e+") does not exist");throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:[`branch ${e}`]},p}if(h===void 0||!h){let p=new Error('Incorrect usage of "merge". Branch to be merged ('+e+") has no commits");throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:['"commit"']},p}if(u===h){let p=new Error('Incorrect usage of "merge". Both branches have same head');throw p.hash={text:`merge ${e}`,token:`merge ${e}`,expected:["branch abc"]},p}if(r&&_t.records.commits.has(r)){let p=new Error('Incorrect usage of "merge". Commit with id:'+r+" already exists, use different custom Id");throw p.hash={text:`merge ${e} ${r} ${n} ${i?.join(" ")}`,token:`merge ${e} ${r} ${n} ${i?.join(" ")}`,expected:[`merge ${e} ${r}_UNIQUE ${n} ${i?.join(" ")}`]},p}let f=l||"",d={id:r||`${_t.records.seq}-${zI()}`,message:`merged branch ${e} into ${_t.records.currBranch}`,seq:_t.records.seq++,parents:_t.records.head==null?[]:[_t.records.head.id,f],branch:_t.records.currBranch,type:Kr.MERGE,customType:n,customId:!!r,tags:i??[]};_t.records.head=d,_t.records.commits.set(d.id,d),_t.records.branches.set(_t.records.currBranch,d.id),Y.debug(_t.records.branches),Y.debug("in mergeBranch")},"merge"),y$e=o(function(t){let e=t.id,r=t.targetId,n=t.tags,i=t.parent;Y.debug("Entering cherryPick:",e,r,n);let a=Ep();if(e=Ze.sanitizeText(e,a),r=Ze.sanitizeText(r,a),n=n?.map(u=>Ze.sanitizeText(u,a)),i=Ze.sanitizeText(i,a),!e||!_t.records.commits.has(e)){let u=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw u.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},u}let s=_t.records.commits.get(e);if(s===void 0||!s)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(i&&!(Array.isArray(s.parents)&&s.parents.includes(i)))throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.");let l=s.branch;if(s.type===Kr.MERGE&&!i)throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.");if(!r||!_t.records.commits.has(r)){if(l===_t.records.currBranch){let d=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let u=_t.records.branches.get(_t.records.currBranch);if(u===void 0||!u){let d=new Error(`Incorrect usage of "cherry-pick". Current branch (${_t.records.currBranch})has no commits`);throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let h=_t.records.commits.get(u);if(h===void 0||!h){let d=new Error(`Incorrect usage of "cherry-pick". Current branch (${_t.records.currBranch})has no commits`);throw d.hash={text:`cherryPick ${e} ${r}`,token:`cherryPick ${e} ${r}`,expected:["cherry-pick abc"]},d}let f={id:_t.records.seq+"-"+zI(),message:`cherry-picked ${s?.message} into ${_t.records.currBranch}`,seq:_t.records.seq++,parents:_t.records.head==null?[]:[_t.records.head.id,s.id],branch:_t.records.currBranch,type:Kr.CHERRY_PICK,tags:n?n.filter(Boolean):[`cherry-pick:${s.id}${s.type===Kr.MERGE?`|parent:${i}`:""}`]};_t.records.head=f,_t.records.commits.set(f.id,f),_t.records.branches.set(_t.records.currBranch,f.id),Y.debug(_t.records.branches),Y.debug("in cherryPick")}},"cherryPick"),Kce=o(function(t){if(t=Ze.sanitizeText(t,Ep()),_t.records.branches.has(t)){_t.records.currBranch=t;let e=_t.records.branches.get(_t.records.currBranch);e===void 0||!e?_t.records.head=null:_t.records.head=_t.records.commits.get(e)??null}else{let e=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${t}")`);throw e.hash={text:`checkout ${t}`,token:`checkout ${t}`,expected:[`branch ${t}`]},e}},"checkout");o(jce,"upsert");o(Qce,"prettyPrintCommitHistory");v$e=o(function(){Y.debug(_t.records.commits);let t=Zce()[0];Qce([t])},"prettyPrint"),x$e=o(function(){_t.reset(),Ar()},"clear"),b$e=o(function(){return[..._t.records.branchConfig.values()].map((e,r)=>e.order!==null&&e.order!==void 0?e:{...e,order:parseFloat(`0.${r}`)}).sort((e,r)=>(e.order??0)-(r.order??0)).map(({name:e})=>({name:e}))},"getBranchesAsObjArray"),w$e=o(function(){return _t.records.branches},"getBranches"),T$e=o(function(){return _t.records.commits},"getCommits"),Zce=o(function(){let t=[..._t.records.commits.values()];return t.forEach(function(e){Y.debug(e.id)}),t.sort((e,r)=>e.seq-r.seq),t},"getCommitsArray"),k$e=o(function(){return _t.records.currBranch},"getCurrentBranch"),E$e=o(function(){return _t.records.direction},"getDirection"),S$e=o(function(){return _t.records.head},"getHead"),o6={commitType:Kr,getConfig:Ep,setDirection:h$e,setOptions:f$e,getOptions:d$e,commit:p$e,branch:m$e,merge:g$e,cherryPick:y$e,checkout:Kce,prettyPrint:v$e,clear:x$e,getBranchesAsObjArray:b$e,getBranches:w$e,getCommits:T$e,getCommitsArray:Zce,getCurrentBranch:k$e,getDirection:E$e,getHead:S$e,setAccTitle:Lr,getAccTitle:Rr,getAccDescription:Mr,setAccDescription:Nr,setDiagramTitle:$r,getDiagramTitle:Ir}});var C$e,A$e,_$e,D$e,L$e,R$e,N$e,Jce,eue=N(()=>{"use strict";kp();vt();T1();GI();a6();C$e=o((t,e)=>{$c(t,e),t.dir&&e.setDirection(t.dir);for(let r of t.statements)A$e(r,e)},"populate"),A$e=o((t,e)=>{let n={Commit:o(i=>e.commit(_$e(i)),"Commit"),Branch:o(i=>e.branch(D$e(i)),"Branch"),Merge:o(i=>e.merge(L$e(i)),"Merge"),Checkout:o(i=>e.checkout(R$e(i)),"Checkout"),CherryPicking:o(i=>e.cherryPick(N$e(i)),"CherryPicking")}[t.$type];n?n(t):Y.error(`Unknown statement type: ${t.$type}`)},"parseStatement"),_$e=o(t=>({id:t.id,msg:t.message??"",type:t.type!==void 0?Kr[t.type]:Kr.NORMAL,tags:t.tags??void 0}),"parseCommit"),D$e=o(t=>({name:t.name,order:t.order??0}),"parseBranch"),L$e=o(t=>({branch:t.branch,id:t.id??"",type:t.type!==void 0?Kr[t.type]:void 0,tags:t.tags??void 0}),"parseMerge"),R$e=o(t=>t.branch,"parseCheckout"),N$e=o(t=>({id:t.id,targetId:"",tags:t.tags?.length===0?void 0:t.tags,parent:t.parent}),"parseCherryPicking"),Jce={parse:o(async t=>{let e=await uo("gitGraph",t);Y.debug(e),C$e(e,o6)},"parse")}});var M$e,Ko,gf,yf,zc,qu,Sp,Gs,Vs,l6,db,c6,mf,Br,I$e,rue,nue,O$e,P$e,B$e,F$e,$$e,z$e,G$e,V$e,U$e,H$e,W$e,q$e,tue,Y$e,pb,X$e,j$e,K$e,Q$e,Z$e,iue,aue=N(()=>{"use strict";dr();zt();vt();ir();a6();M$e=me(),Ko=M$e?.gitGraph,gf=10,yf=40,zc=4,qu=2,Sp=8,Gs=new Map,Vs=new Map,l6=30,db=new Map,c6=[],mf=0,Br="LR",I$e=o(()=>{Gs.clear(),Vs.clear(),db.clear(),mf=0,c6=[],Br="LR"},"clear"),rue=o(t=>{let e=document.createElementNS("http://www.w3.org/2000/svg","text");return(typeof t=="string"?t.split(/\\n|\n|<br\s*\/?>/gi):t).forEach(n=>{let i=document.createElementNS("http://www.w3.org/2000/svg","tspan");i.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),i.setAttribute("dy","1em"),i.setAttribute("x","0"),i.setAttribute("class","row"),i.textContent=n.trim(),e.appendChild(i)}),e},"drawText"),nue=o(t=>{let e,r,n;return Br==="BT"?(r=o((i,a)=>i<=a,"comparisonFunc"),n=1/0):(r=o((i,a)=>i>=a,"comparisonFunc"),n=0),t.forEach(i=>{let a=Br==="TB"||Br=="BT"?Vs.get(i)?.y:Vs.get(i)?.x;a!==void 0&&r(a,n)&&(e=i,n=a)}),e},"findClosestParent"),O$e=o(t=>{let e="",r=1/0;return t.forEach(n=>{let i=Vs.get(n).y;i<=r&&(e=n,r=i)}),e||void 0},"findClosestParentBT"),P$e=o((t,e,r)=>{let n=r,i=r,a=[];t.forEach(s=>{let l=e.get(s);if(!l)throw new Error(`Commit not found for key ${s}`);l.parents.length?(n=F$e(l),i=Math.max(n,i)):a.push(l),$$e(l,n)}),n=i,a.forEach(s=>{z$e(s,n,r)}),t.forEach(s=>{let l=e.get(s);if(l?.parents.length){let u=O$e(l.parents);n=Vs.get(u).y-yf,n<=i&&(i=n);let h=Gs.get(l.branch).pos,f=n-gf;Vs.set(l.id,{x:h,y:f})}})},"setParallelBTPos"),B$e=o(t=>{let e=nue(t.parents.filter(n=>n!==null));if(!e)throw new Error(`Closest parent not found for commit ${t.id}`);let r=Vs.get(e)?.y;if(r===void 0)throw new Error(`Closest parent position not found for commit ${t.id}`);return r},"findClosestParentPos"),F$e=o(t=>B$e(t)+yf,"calculateCommitPosition"),$$e=o((t,e)=>{let r=Gs.get(t.branch);if(!r)throw new Error(`Branch not found for commit ${t.id}`);let n=r.pos,i=e+gf;return Vs.set(t.id,{x:n,y:i}),{x:n,y:i}},"setCommitPosition"),z$e=o((t,e,r)=>{let n=Gs.get(t.branch);if(!n)throw new Error(`Branch not found for commit ${t.id}`);let i=e+r,a=n.pos;Vs.set(t.id,{x:a,y:i})},"setRootPosition"),G$e=o((t,e,r,n,i,a)=>{if(a===Kr.HIGHLIGHT)t.append("rect").attr("x",r.x-10).attr("y",r.y-10).attr("width",20).attr("height",20).attr("class",`commit ${e.id} commit-highlight${i%Sp} ${n}-outer`),t.append("rect").attr("x",r.x-6).attr("y",r.y-6).attr("width",12).attr("height",12).attr("class",`commit ${e.id} commit${i%Sp} ${n}-inner`);else if(a===Kr.CHERRY_PICK)t.append("circle").attr("cx",r.x).attr("cy",r.y).attr("r",10).attr("class",`commit ${e.id} ${n}`),t.append("circle").attr("cx",r.x-3).attr("cy",r.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${e.id} ${n}`),t.append("circle").attr("cx",r.x+3).attr("cy",r.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${e.id} ${n}`),t.append("line").attr("x1",r.x+3).attr("y1",r.y+1).attr("x2",r.x).attr("y2",r.y-5).attr("stroke","#fff").attr("class",`commit ${e.id} ${n}`),t.append("line").attr("x1",r.x-3).attr("y1",r.y+1).attr("x2",r.x).attr("y2",r.y-5).attr("stroke","#fff").attr("class",`commit ${e.id} ${n}`);else{let s=t.append("circle");if(s.attr("cx",r.x),s.attr("cy",r.y),s.attr("r",e.type===Kr.MERGE?9:10),s.attr("class",`commit ${e.id} commit${i%Sp}`),a===Kr.MERGE){let l=t.append("circle");l.attr("cx",r.x),l.attr("cy",r.y),l.attr("r",6),l.attr("class",`commit ${n} ${e.id} commit${i%Sp}`)}a===Kr.REVERSE&&t.append("path").attr("d",`M ${r.x-5},${r.y-5}L${r.x+5},${r.y+5}M${r.x-5},${r.y+5}L${r.x+5},${r.y-5}`).attr("class",`commit ${n} ${e.id} commit${i%Sp}`)}},"drawCommitBullet"),V$e=o((t,e,r,n)=>{if(e.type!==Kr.CHERRY_PICK&&(e.customId&&e.type===Kr.MERGE||e.type!==Kr.MERGE)&&Ko?.showCommitLabel){let i=t.append("g"),a=i.insert("rect").attr("class","commit-label-bkg"),s=i.append("text").attr("x",n).attr("y",r.y+25).attr("class","commit-label").text(e.id),l=s.node()?.getBBox();if(l&&(a.attr("x",r.posWithOffset-l.width/2-qu).attr("y",r.y+13.5).attr("width",l.width+2*qu).attr("height",l.height+2*qu),Br==="TB"||Br==="BT"?(a.attr("x",r.x-(l.width+4*zc+5)).attr("y",r.y-12),s.attr("x",r.x-(l.width+4*zc)).attr("y",r.y+l.height-12)):s.attr("x",r.posWithOffset-l.width/2),Ko.rotateCommitLabel))if(Br==="TB"||Br==="BT")s.attr("transform","rotate(-45, "+r.x+", "+r.y+")"),a.attr("transform","rotate(-45, "+r.x+", "+r.y+")");else{let u=-7.5-(l.width+10)/25*9.5,h=10+l.width/25*8.5;i.attr("transform","translate("+u+", "+h+") rotate(-45, "+n+", "+r.y+")")}}},"drawCommitLabel"),U$e=o((t,e,r,n)=>{if(e.tags.length>0){let i=0,a=0,s=0,l=[];for(let u of e.tags.reverse()){let h=t.insert("polygon"),f=t.append("circle"),d=t.append("text").attr("y",r.y-16-i).attr("class","tag-label").text(u),p=d.node()?.getBBox();if(!p)throw new Error("Tag bbox not found");a=Math.max(a,p.width),s=Math.max(s,p.height),d.attr("x",r.posWithOffset-p.width/2),l.push({tag:d,hole:f,rect:h,yOffset:i}),i+=20}for(let{tag:u,hole:h,rect:f,yOffset:d}of l){let p=s/2,m=r.y-19.2-d;if(f.attr("class","tag-label-bkg").attr("points",`
+ ${n-a/2-zc/2},${m+qu}
+ ${n-a/2-zc/2},${m-qu}
+ ${r.posWithOffset-a/2-zc},${m-p-qu}
+ ${r.posWithOffset+a/2+zc},${m-p-qu}
+ ${r.posWithOffset+a/2+zc},${m+p+qu}
+ ${r.posWithOffset-a/2-zc},${m+p+qu}`),h.attr("cy",m).attr("cx",n-a/2+zc/2).attr("r",1.5).attr("class","tag-hole"),Br==="TB"||Br==="BT"){let g=n+d;f.attr("class","tag-label-bkg").attr("points",`
+ ${r.x},${g+2}
+ ${r.x},${g-2}
+ ${r.x+gf},${g-p-2}
+ ${r.x+gf+a+4},${g-p-2}
+ ${r.x+gf+a+4},${g+p+2}
+ ${r.x+gf},${g+p+2}`).attr("transform","translate(12,12) rotate(45, "+r.x+","+n+")"),h.attr("cx",r.x+zc/2).attr("cy",g).attr("transform","translate(12,12) rotate(45, "+r.x+","+n+")"),u.attr("x",r.x+5).attr("y",g+3).attr("transform","translate(14,14) rotate(45, "+r.x+","+n+")")}}}},"drawCommitTags"),H$e=o(t=>{switch(t.customType??t.type){case Kr.NORMAL:return"commit-normal";case Kr.REVERSE:return"commit-reverse";case Kr.HIGHLIGHT:return"commit-highlight";case Kr.MERGE:return"commit-merge";case Kr.CHERRY_PICK:return"commit-cherry-pick";default:return"commit-normal"}},"getCommitClassType"),W$e=o((t,e,r,n)=>{let i={x:0,y:0};if(t.parents.length>0){let a=nue(t.parents);if(a){let s=n.get(a)??i;return e==="TB"?s.y+yf:e==="BT"?(n.get(t.id)??i).y-yf:s.x+yf}}else return e==="TB"?l6:e==="BT"?(n.get(t.id)??i).y-yf:0;return 0},"calculatePosition"),q$e=o((t,e,r)=>{let n=Br==="BT"&&r?e:e+gf,i=Br==="TB"||Br==="BT"?n:Gs.get(t.branch)?.pos,a=Br==="TB"||Br==="BT"?Gs.get(t.branch)?.pos:n;if(a===void 0||i===void 0)throw new Error(`Position were undefined for commit ${t.id}`);return{x:a,y:i,posWithOffset:n}},"getCommitPosition"),tue=o((t,e,r)=>{if(!Ko)throw new Error("GitGraph config not found");let n=t.append("g").attr("class","commit-bullets"),i=t.append("g").attr("class","commit-labels"),a=Br==="TB"||Br==="BT"?l6:0,s=[...e.keys()],l=Ko?.parallelCommits??!1,u=o((f,d)=>{let p=e.get(f)?.seq,m=e.get(d)?.seq;return p!==void 0&&m!==void 0?p-m:0},"sortKeys"),h=s.sort(u);Br==="BT"&&(l&&P$e(h,e,a),h=h.reverse()),h.forEach(f=>{let d=e.get(f);if(!d)throw new Error(`Commit not found for key ${f}`);l&&(a=W$e(d,Br,a,Vs));let p=q$e(d,a,l);if(r){let m=H$e(d),g=d.customType??d.type,y=Gs.get(d.branch)?.index??0;G$e(n,d,p,m,y,g),V$e(i,d,p,a),U$e(i,d,p,a)}Br==="TB"||Br==="BT"?Vs.set(d.id,{x:p.x,y:p.posWithOffset}):Vs.set(d.id,{x:p.posWithOffset,y:p.y}),a=Br==="BT"&&l?a+yf:a+yf+gf,a>mf&&(mf=a)})},"drawCommits"),Y$e=o((t,e,r,n,i)=>{let s=(Br==="TB"||Br==="BT"?r.x<n.x:r.y<n.y)?e.branch:t.branch,l=o(h=>h.branch===s,"isOnBranchToGetCurve"),u=o(h=>h.seq>t.seq&&h.seq<e.seq,"isBetweenCommits");return[...i.values()].some(h=>u(h)&&l(h))},"shouldRerouteArrow"),pb=o((t,e,r=0)=>{let n=t+Math.abs(t-e)/2;if(r>5)return n;if(c6.every(s=>Math.abs(s-n)>=10))return c6.push(n),n;let a=Math.abs(t-e);return pb(t,e-a/5,r+1)},"findLane"),X$e=o((t,e,r,n)=>{let i=Vs.get(e.id),a=Vs.get(r.id);if(i===void 0||a===void 0)throw new Error(`Commit positions not found for commits ${e.id} and ${r.id}`);let s=Y$e(e,r,i,a,n),l="",u="",h=0,f=0,d=Gs.get(r.branch)?.index;r.type===Kr.MERGE&&e.id!==r.parents[0]&&(d=Gs.get(e.branch)?.index);let p;if(s){l="A 10 10, 0, 0, 0,",u="A 10 10, 0, 0, 1,",h=10,f=10;let m=i.y<a.y?pb(i.y,a.y):pb(a.y,i.y),g=i.x<a.x?pb(i.x,a.x):pb(a.x,i.x);Br==="TB"?i.x<a.x?p=`M ${i.x} ${i.y} L ${g-h} ${i.y} ${u} ${g} ${i.y+f} L ${g} ${a.y-h} ${l} ${g+f} ${a.y} L ${a.x} ${a.y}`:(d=Gs.get(e.branch)?.index,p=`M ${i.x} ${i.y} L ${g+h} ${i.y} ${l} ${g} ${i.y+f} L ${g} ${a.y-h} ${u} ${g-f} ${a.y} L ${a.x} ${a.y}`):Br==="BT"?i.x<a.x?p=`M ${i.x} ${i.y} L ${g-h} ${i.y} ${l} ${g} ${i.y-f} L ${g} ${a.y+h} ${u} ${g+f} ${a.y} L ${a.x} ${a.y}`:(d=Gs.get(e.branch)?.index,p=`M ${i.x} ${i.y} L ${g+h} ${i.y} ${u} ${g} ${i.y-f} L ${g} ${a.y+h} ${l} ${g-f} ${a.y} L ${a.x} ${a.y}`):i.y<a.y?p=`M ${i.x} ${i.y} L ${i.x} ${m-h} ${l} ${i.x+f} ${m} L ${a.x-h} ${m} ${u} ${a.x} ${m+f} L ${a.x} ${a.y}`:(d=Gs.get(e.branch)?.index,p=`M ${i.x} ${i.y} L ${i.x} ${m+h} ${u} ${i.x+f} ${m} L ${a.x-h} ${m} ${l} ${a.x} ${m-f} L ${a.x} ${a.y}`)}else l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,Br==="TB"?(i.x<a.x&&(r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y-h} ${l} ${i.x+f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${u} ${a.x} ${i.y+f} L ${a.x} ${a.y}`),i.x>a.x&&(l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y-h} ${u} ${i.x-f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x+h} ${i.y} ${l} ${a.x} ${i.y+f} L ${a.x} ${a.y}`),i.x===a.x&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`)):Br==="BT"?(i.x<a.x&&(r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${u} ${i.x+f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`),i.x>a.x&&(l="A 20 20, 0, 0, 0,",u="A 20 20, 0, 0, 1,",h=20,f=20,r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${l} ${i.x-f} ${a.y} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`),i.x===a.x&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`)):(i.y<a.y&&(r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${u} ${a.x} ${i.y+f} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${i.x} ${a.y-h} ${l} ${i.x+f} ${a.y} L ${a.x} ${a.y}`),i.y>a.y&&(r.type===Kr.MERGE&&e.id!==r.parents[0]?p=`M ${i.x} ${i.y} L ${a.x-h} ${i.y} ${l} ${a.x} ${i.y-f} L ${a.x} ${a.y}`:p=`M ${i.x} ${i.y} L ${i.x} ${a.y+h} ${u} ${i.x+f} ${a.y} L ${a.x} ${a.y}`),i.y===a.y&&(p=`M ${i.x} ${i.y} L ${a.x} ${a.y}`));if(p===void 0)throw new Error("Line definition not found");t.append("path").attr("d",p).attr("class","arrow arrow"+d%Sp)},"drawArrow"),j$e=o((t,e)=>{let r=t.append("g").attr("class","commit-arrows");[...e.keys()].forEach(n=>{let i=e.get(n);i.parents&&i.parents.length>0&&i.parents.forEach(a=>{X$e(r,e.get(a),i,e)})})},"drawArrows"),K$e=o((t,e)=>{let r=t.append("g");e.forEach((n,i)=>{let a=i%Sp,s=Gs.get(n.name)?.pos;if(s===void 0)throw new Error(`Position not found for branch ${n.name}`);let l=r.append("line");l.attr("x1",0),l.attr("y1",s),l.attr("x2",mf),l.attr("y2",s),l.attr("class","branch branch"+a),Br==="TB"?(l.attr("y1",l6),l.attr("x1",s),l.attr("y2",mf),l.attr("x2",s)):Br==="BT"&&(l.attr("y1",mf),l.attr("x1",s),l.attr("y2",l6),l.attr("x2",s)),c6.push(s);let u=n.name,h=rue(u),f=r.insert("rect"),p=r.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+a);p.node().appendChild(h);let m=h.getBBox();f.attr("class","branchLabelBkg label"+a).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(Ko?.rotateCommitLabel===!0?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),p.attr("transform","translate("+(-m.width-14-(Ko?.rotateCommitLabel===!0?30:0))+", "+(s-m.height/2-1)+")"),Br==="TB"?(f.attr("x",s-m.width/2-10).attr("y",0),p.attr("transform","translate("+(s-m.width/2-5)+", 0)")):Br==="BT"?(f.attr("x",s-m.width/2-10).attr("y",mf),p.attr("transform","translate("+(s-m.width/2-5)+", "+mf+")")):f.attr("transform","translate(-19, "+(s-m.height/2)+")")})},"drawBranches"),Q$e=o(function(t,e,r,n,i){return Gs.set(t,{pos:e,index:r}),e+=50+(i?40:0)+(Br==="TB"||Br==="BT"?n.width/2:0),e},"setBranchPosition"),Z$e=o(function(t,e,r,n){if(I$e(),Y.debug("in gitgraph renderer",t+`
+`,"id:",e,r),!Ko)throw new Error("GitGraph config not found");let i=Ko.rotateCommitLabel??!1,a=n.db;db=a.getCommits();let s=a.getBranchesAsObjArray();Br=a.getDirection();let l=Ge(`[id="${e}"]`),u=0;s.forEach((h,f)=>{let d=rue(h.name),p=l.append("g"),m=p.insert("g").attr("class","branchLabel"),g=m.insert("g").attr("class","label branch-label");g.node()?.appendChild(d);let y=d.getBBox();u=Q$e(h.name,u,f,y,i),g.remove(),m.remove(),p.remove()}),tue(l,db,!1),Ko.showBranches&&K$e(l,s),j$e(l,db),tue(l,db,!0),Gt.insertTitle(l,"gitTitleText",Ko.titleTopMargin??0,a.getDiagramTitle()),oA(void 0,l,Ko.diagramPadding,Ko.useMaxWidth)},"draw"),iue={draw:Z$e}});var J$e,sue,oue=N(()=>{"use strict";J$e=o(t=>`
+ .commit-id,
+ .commit-msg,
+ .branch-label {
+ fill: lightgrey;
+ color: lightgrey;
+ font-family: 'trebuchet ms', verdana, arial, sans-serif;
+ font-family: var(--mermaid-font-family);
+ }
+ ${[0,1,2,3,4,5,6,7].map(e=>`
+ .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }
+ .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }
+ .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }
+ .label${e} { fill: ${t["git"+e]}; }
+ .arrow${e} { stroke: ${t["git"+e]}; }
+ `).join(`
+`)}
+
+ .branch {
+ stroke-width: 1;
+ stroke: ${t.lineColor};
+ stroke-dasharray: 2;
+ }
+ .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}
+ .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }
+ .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}
+ .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }
+ .tag-hole { fill: ${t.textColor}; }
+
+ .commit-merge {
+ stroke: ${t.primaryColor};
+ fill: ${t.primaryColor};
+ }
+ .commit-reverse {
+ stroke: ${t.primaryColor};
+ fill: ${t.primaryColor};
+ stroke-width: 3;
+ }
+ .commit-highlight-outer {
+ }
+ .commit-highlight-inner {
+ stroke: ${t.primaryColor};
+ fill: ${t.primaryColor};
+ }
+
+ .arrow { stroke-width: 8; stroke-linecap: round; fill: none}
+ .gitTitleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: ${t.textColor};
+ }
+`,"getStyles"),sue=J$e});var lue={};hr(lue,{diagram:()=>eze});var eze,cue=N(()=>{"use strict";eue();GI();aue();oue();eze={parser:Jce,db:o6,renderer:iue,styles:sue}});var VI,fue,due=N(()=>{"use strict";VI=function(){var t=o(function(L,R,O,M){for(O=O||{},M=L.length;M--;O[L[M]]=R);return O},"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],r=[1,26],n=[1,27],i=[1,28],a=[1,29],s=[1,30],l=[1,31],u=[1,32],h=[1,33],f=[1,34],d=[1,9],p=[1,10],m=[1,11],g=[1,12],y=[1,13],v=[1,14],x=[1,15],b=[1,16],w=[1,19],C=[1,20],T=[1,21],E=[1,22],A=[1,23],S=[1,25],_=[1,35],I={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:o(function(R,O,M,B,F,P,z){var $=P.length-1;switch(F){case 1:return P[$-1];case 2:this.$=[];break;case 3:P[$-1].push(P[$]),this.$=P[$-1];break;case 4:case 5:this.$=P[$];break;case 6:case 7:this.$=[];break;case 8:B.setWeekday("monday");break;case 9:B.setWeekday("tuesday");break;case 10:B.setWeekday("wednesday");break;case 11:B.setWeekday("thursday");break;case 12:B.setWeekday("friday");break;case 13:B.setWeekday("saturday");break;case 14:B.setWeekday("sunday");break;case 15:B.setWeekend("friday");break;case 16:B.setWeekend("saturday");break;case 17:B.setDateFormat(P[$].substr(11)),this.$=P[$].substr(11);break;case 18:B.enableInclusiveEndDates(),this.$=P[$].substr(18);break;case 19:B.TopAxis(),this.$=P[$].substr(8);break;case 20:B.setAxisFormat(P[$].substr(11)),this.$=P[$].substr(11);break;case 21:B.setTickInterval(P[$].substr(13)),this.$=P[$].substr(13);break;case 22:B.setExcludes(P[$].substr(9)),this.$=P[$].substr(9);break;case 23:B.setIncludes(P[$].substr(9)),this.$=P[$].substr(9);break;case 24:B.setTodayMarker(P[$].substr(12)),this.$=P[$].substr(12);break;case 27:B.setDiagramTitle(P[$].substr(6)),this.$=P[$].substr(6);break;case 28:this.$=P[$].trim(),B.setAccTitle(this.$);break;case 29:case 30:this.$=P[$].trim(),B.setAccDescription(this.$);break;case 31:B.addSection(P[$].substr(8)),this.$=P[$].substr(8);break;case 33:B.addTask(P[$-1],P[$]),this.$="task";break;case 34:this.$=P[$-1],B.setClickEvent(P[$-1],P[$],null);break;case 35:this.$=P[$-2],B.setClickEvent(P[$-2],P[$-1],P[$]);break;case 36:this.$=P[$-2],B.setClickEvent(P[$-2],P[$-1],null),B.setLink(P[$-2],P[$]);break;case 37:this.$=P[$-3],B.setClickEvent(P[$-3],P[$-2],P[$-1]),B.setLink(P[$-3],P[$]);break;case 38:this.$=P[$-2],B.setClickEvent(P[$-2],P[$],null),B.setLink(P[$-2],P[$-1]);break;case 39:this.$=P[$-3],B.setClickEvent(P[$-3],P[$-1],P[$]),B.setLink(P[$-3],P[$-2]);break;case 40:this.$=P[$-1],B.setLink(P[$-1],P[$]);break;case 41:case 47:this.$=P[$-1]+" "+P[$];break;case 42:case 43:case 45:this.$=P[$-2]+" "+P[$-1]+" "+P[$];break;case 44:case 46:this.$=P[$-3]+" "+P[$-2]+" "+P[$-1]+" "+P[$];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:r,13:n,14:i,15:a,16:s,17:l,18:u,19:18,20:h,21:f,22:d,23:p,24:m,25:g,26:y,27:v,28:x,29:b,30:w,31:C,33:T,35:E,36:A,37:24,38:S,40:_},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:r,13:n,14:i,15:a,16:s,17:l,18:u,19:18,20:h,21:f,22:d,23:p,24:m,25:g,26:y,27:v,28:x,29:b,30:w,31:C,33:T,35:E,36:A,37:24,38:S,40:_},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:o(function(R,O){if(O.recoverable)this.trace(R);else{var M=new Error(R);throw M.hash=O,M}},"parseError"),parse:o(function(R){var O=this,M=[0],B=[],F=[null],P=[],z=this.table,$="",H=0,Q=0,j=0,ie=2,ne=1,le=P.slice.call(arguments,1),he=Object.create(this.lexer),K={yy:{}};for(var X in this.yy)Object.prototype.hasOwnProperty.call(this.yy,X)&&(K.yy[X]=this.yy[X]);he.setInput(R,K.yy),K.yy.lexer=he,K.yy.parser=this,typeof he.yylloc>"u"&&(he.yylloc={});var te=he.yylloc;P.push(te);var J=he.options&&he.options.ranges;typeof K.yy.parseError=="function"?this.parseError=K.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function se(W){M.length=M.length-2*W,F.length=F.length-W,P.length=P.length-W}o(se,"popStack");function ue(){var W;return W=B.pop()||he.lex()||ne,typeof W!="number"&&(W instanceof Array&&(B=W,W=B.pop()),W=O.symbols_[W]||W),W}o(ue,"lex");for(var Z,Se,ce,ae,Oe,ge,ze={},He,$e,Re,Ie;;){if(ce=M[M.length-1],this.defaultActions[ce]?ae=this.defaultActions[ce]:((Z===null||typeof Z>"u")&&(Z=ue()),ae=z[ce]&&z[ce][Z]),typeof ae>"u"||!ae.length||!ae[0]){var be="";Ie=[];for(He in z[ce])this.terminals_[He]&&He>ie&&Ie.push("'"+this.terminals_[He]+"'");he.showPosition?be="Parse error on line "+(H+1)+`:
+`+he.showPosition()+`
+Expecting `+Ie.join(", ")+", got '"+(this.terminals_[Z]||Z)+"'":be="Parse error on line "+(H+1)+": Unexpected "+(Z==ne?"end of input":"'"+(this.terminals_[Z]||Z)+"'"),this.parseError(be,{text:he.match,token:this.terminals_[Z]||Z,line:he.yylineno,loc:te,expected:Ie})}if(ae[0]instanceof Array&&ae.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ce+", token: "+Z);switch(ae[0]){case 1:M.push(Z),F.push(he.yytext),P.push(he.yylloc),M.push(ae[1]),Z=null,Se?(Z=Se,Se=null):(Q=he.yyleng,$=he.yytext,H=he.yylineno,te=he.yylloc,j>0&&j--);break;case 2:if($e=this.productions_[ae[1]][1],ze.$=F[F.length-$e],ze._$={first_line:P[P.length-($e||1)].first_line,last_line:P[P.length-1].last_line,first_column:P[P.length-($e||1)].first_column,last_column:P[P.length-1].last_column},J&&(ze._$.range=[P[P.length-($e||1)].range[0],P[P.length-1].range[1]]),ge=this.performAction.apply(ze,[$,Q,H,K.yy,ae[1],F,P].concat(le)),typeof ge<"u")return ge;$e&&(M=M.slice(0,-1*$e*2),F=F.slice(0,-1*$e),P=P.slice(0,-1*$e)),M.push(this.productions_[ae[1]][0]),F.push(ze.$),P.push(ze._$),Re=z[M[M.length-2]][M[M.length-1]],M.push(Re);break;case 3:return!0}}return!0},"parse")},D=function(){var L={EOF:1,parseError:o(function(O,M){if(this.yy.parser)this.yy.parser.parseError(O,M);else throw new Error(O)},"parseError"),setInput:o(function(R,O){return this.yy=O||this.yy||{},this._input=R,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var R=this._input[0];this.yytext+=R,this.yyleng++,this.offset++,this.match+=R,this.matched+=R;var O=R.match(/(?:\r\n?|\n).*/g);return O?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),R},"input"),unput:o(function(R){var O=R.length,M=R.split(/(?:\r\n?|\n)/g);this._input=R+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-O),this.offset-=O;var B=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),M.length-1&&(this.yylineno-=M.length-1);var F=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:M?(M.length===B.length?this.yylloc.first_column:0)+B[B.length-M.length].length-M[0].length:this.yylloc.first_column-O},this.options.ranges&&(this.yylloc.range=[F[0],F[0]+this.yyleng-O]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(R){this.unput(this.match.slice(R))},"less"),pastInput:o(function(){var R=this.matched.substr(0,this.matched.length-this.match.length);return(R.length>20?"...":"")+R.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var R=this.match;return R.length<20&&(R+=this._input.substr(0,20-R.length)),(R.substr(0,20)+(R.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var R=this.pastInput(),O=new Array(R.length+1).join("-");return R+this.upcomingInput()+`
+`+O+"^"},"showPosition"),test_match:o(function(R,O){var M,B,F;if(this.options.backtrack_lexer&&(F={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(F.yylloc.range=this.yylloc.range.slice(0))),B=R[0].match(/(?:\r\n?|\n).*/g),B&&(this.yylineno+=B.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:B?B[B.length-1].length-B[B.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+R[0].length},this.yytext+=R[0],this.match+=R[0],this.matches=R,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(R[0].length),this.matched+=R[0],M=this.performAction.call(this,this.yy,this,O,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),M)return M;if(this._backtrack){for(var P in F)this[P]=F[P];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var R,O,M,B;this._more||(this.yytext="",this.match="");for(var F=this._currentRules(),P=0;P<F.length;P++)if(M=this._input.match(this.rules[F[P]]),M&&(!O||M[0].length>O[0].length)){if(O=M,B=P,this.options.backtrack_lexer){if(R=this.test_match(M,F[P]),R!==!1)return R;if(this._backtrack){O=!1;continue}else return!1}else if(!this.options.flex)break}return O?(R=this.test_match(O,F[B]),R!==!1?R:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var O=this.next();return O||this.lex()},"lex"),begin:o(function(O){this.conditionStack.push(O)},"begin"),popState:o(function(){var O=this.conditionStack.length-1;return O>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(O){return O=this.conditionStack.length-1-Math.abs(O||0),O>=0?this.conditionStack[O]:"INITIAL"},"topState"),pushState:o(function(O){this.begin(O)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(O,M,B,F){var P=F;switch(B){case 0:return this.begin("open_directive"),"open_directive";break;case 1:return this.begin("acc_title"),31;break;case 2:return this.popState(),"acc_title_value";break;case 3:return this.begin("acc_descr"),33;break;case 4:return this.popState(),"acc_descr_value";break;case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:break;case 9:break;case 10:break;case 11:return 10;case 12:break;case 13:break;case 14:this.begin("href");break;case 15:this.popState();break;case 16:return 43;case 17:this.begin("callbackname");break;case 18:this.popState();break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 41;case 21:this.popState();break;case 22:return 42;case 23:this.begin("click");break;case 24:this.popState();break;case 25:return 40;case 26:return 4;case 27:return 22;case 28:return 23;case 29:return 24;case 30:return 25;case 31:return 26;case 32:return 28;case 33:return 27;case 34:return 29;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return 20;case 43:return 21;case 44:return"date";case 45:return 30;case 46:return"accDescription";case 47:return 36;case 48:return 38;case 49:return 39;case 50:return":";case 51:return 6;case 52:return"INVALID"}},"anonymous"),rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:weekend\s+friday\b)/i,/^(?:weekend\s+saturday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],inclusive:!0}}};return L}();I.lexer=D;function k(){this.yy={}}return o(k,"Parser"),k.prototype=I,I.Parser=k,new k}();VI.parser=VI;fue=VI});var pue=Mi((UI,HI)=>{"use strict";(function(t,e){typeof UI=="object"&&typeof HI<"u"?HI.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_isoWeek=e()})(UI,function(){"use strict";var t="day";return function(e,r,n){var i=o(function(l){return l.add(4-l.isoWeekday(),t)},"a"),a=r.prototype;a.isoWeekYear=function(){return i(this).year()},a.isoWeek=function(l){if(!this.$utils().u(l))return this.add(7*(l-this.isoWeek()),t);var u,h,f,d,p=i(this),m=(u=this.isoWeekYear(),h=this.$u,f=(h?n.utc:n)().year(u).startOf("year"),d=4-f.isoWeekday(),f.isoWeekday()>4&&(d+=7),f.add(d,t));return p.diff(m,"week")+1},a.isoWeekday=function(l){return this.$utils().u(l)?this.day()||7:this.day(this.day()%7?l:l-7)};var s=a.startOf;a.startOf=function(l,u){var h=this.$utils(),f=!!h.u(u)||u;return h.p(l)==="isoweek"?f?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(l,u)}}})});var mue=Mi((WI,qI)=>{"use strict";(function(t,e){typeof WI=="object"&&typeof qI<"u"?qI.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_customParseFormat=e()})(WI,function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,r=/\d/,n=/\d\d/,i=/\d\d?/,a=/\d*[^-_:/,()\s\d]+/,s={},l=o(function(g){return(g=+g)+(g>68?1900:2e3)},"a"),u=o(function(g){return function(y){this[g]=+y}},"f"),h=[/[+-]\d\d:?(\d\d)?|Z/,function(g){(this.zone||(this.zone={})).offset=function(y){if(!y||y==="Z")return 0;var v=y.match(/([+-]|\d\d)/g),x=60*v[1]+(+v[2]||0);return x===0?0:v[0]==="+"?-x:x}(g)}],f=o(function(g){var y=s[g];return y&&(y.indexOf?y:y.s.concat(y.f))},"u"),d=o(function(g,y){var v,x=s.meridiem;if(x){for(var b=1;b<=24;b+=1)if(g.indexOf(x(b,0,y))>-1){v=b>12;break}}else v=g===(y?"pm":"PM");return v},"d"),p={A:[a,function(g){this.afternoon=d(g,!1)}],a:[a,function(g){this.afternoon=d(g,!0)}],Q:[r,function(g){this.month=3*(g-1)+1}],S:[r,function(g){this.milliseconds=100*+g}],SS:[n,function(g){this.milliseconds=10*+g}],SSS:[/\d{3}/,function(g){this.milliseconds=+g}],s:[i,u("seconds")],ss:[i,u("seconds")],m:[i,u("minutes")],mm:[i,u("minutes")],H:[i,u("hours")],h:[i,u("hours")],HH:[i,u("hours")],hh:[i,u("hours")],D:[i,u("day")],DD:[n,u("day")],Do:[a,function(g){var y=s.ordinal,v=g.match(/\d+/);if(this.day=v[0],y)for(var x=1;x<=31;x+=1)y(x).replace(/\[|\]/g,"")===g&&(this.day=x)}],w:[i,u("week")],ww:[n,u("week")],M:[i,u("month")],MM:[n,u("month")],MMM:[a,function(g){var y=f("months"),v=(f("monthsShort")||y.map(function(x){return x.slice(0,3)})).indexOf(g)+1;if(v<1)throw new Error;this.month=v%12||v}],MMMM:[a,function(g){var y=f("months").indexOf(g)+1;if(y<1)throw new Error;this.month=y%12||y}],Y:[/[+-]?\d+/,u("year")],YY:[n,function(g){this.year=l(g)}],YYYY:[/\d{4}/,u("year")],Z:h,ZZ:h};function m(g){var y,v;y=g,v=s&&s.formats;for(var x=(g=y.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(S,_,I){var D=I&&I.toUpperCase();return _||v[I]||t[I]||v[D].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(k,L,R){return L||R.slice(1)})})).match(e),b=x.length,w=0;w<b;w+=1){var C=x[w],T=p[C],E=T&&T[0],A=T&&T[1];x[w]=A?{regex:E,parser:A}:C.replace(/^\[|\]$/g,"")}return function(S){for(var _={},I=0,D=0;I<b;I+=1){var k=x[I];if(typeof k=="string")D+=k.length;else{var L=k.regex,R=k.parser,O=S.slice(D),M=L.exec(O)[0];R.call(_,M),S=S.replace(M,"")}}return function(B){var F=B.afternoon;if(F!==void 0){var P=B.hours;F?P<12&&(B.hours+=12):P===12&&(B.hours=0),delete B.afternoon}}(_),_}}return o(m,"l"),function(g,y,v){v.p.customParseFormat=!0,g&&g.parseTwoDigitYear&&(l=g.parseTwoDigitYear);var x=y.prototype,b=x.parse;x.parse=function(w){var C=w.date,T=w.utc,E=w.args;this.$u=T;var A=E[1];if(typeof A=="string"){var S=E[2]===!0,_=E[3]===!0,I=S||_,D=E[2];_&&(D=E[2]),s=this.$locale(),!S&&D&&(s=v.Ls[D]),this.$d=function(O,M,B,F){try{if(["x","X"].indexOf(M)>-1)return new Date((M==="X"?1e3:1)*O);var P=m(M)(O),z=P.year,$=P.month,H=P.day,Q=P.hours,j=P.minutes,ie=P.seconds,ne=P.milliseconds,le=P.zone,he=P.week,K=new Date,X=H||(z||$?1:K.getDate()),te=z||K.getFullYear(),J=0;z&&!$||(J=$>0?$-1:K.getMonth());var se,ue=Q||0,Z=j||0,Se=ie||0,ce=ne||0;return le?new Date(Date.UTC(te,J,X,ue,Z,Se,ce+60*le.offset*1e3)):B?new Date(Date.UTC(te,J,X,ue,Z,Se,ce)):(se=new Date(te,J,X,ue,Z,Se,ce),he&&(se=F(se).week(he).toDate()),se)}catch{return new Date("")}}(C,A,T,v),this.init(),D&&D!==!0&&(this.$L=this.locale(D).$L),I&&C!=this.format(A)&&(this.$d=new Date("")),s={}}else if(A instanceof Array)for(var k=A.length,L=1;L<=k;L+=1){E[1]=A[L-1];var R=v.apply(this,E);if(R.isValid()){this.$d=R.$d,this.$L=R.$L,this.init();break}L===k&&(this.$d=new Date(""))}else b.call(this,w)}}})});var gue=Mi((YI,XI)=>{"use strict";(function(t,e){typeof YI=="object"&&typeof XI<"u"?XI.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self).dayjs_plugin_advancedFormat=e()})(YI,function(){"use strict";return function(t,e){var r=e.prototype,n=r.format;r.format=function(i){var a=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var l=this.$utils(),u=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(h){switch(h){case"Q":return Math.ceil((a.$M+1)/3);case"Do":return s.ordinal(a.$D);case"gggg":return a.weekYear();case"GGGG":return a.isoWeekYear();case"wo":return s.ordinal(a.week(),"W");case"w":case"ww":return l.s(a.week(),h==="w"?1:2,"0");case"W":case"WW":return l.s(a.isoWeek(),h==="W"?1:2,"0");case"k":case"kk":return l.s(String(a.$H===0?24:a.$H),h==="k"?1:2,"0");case"X":return Math.floor(a.$d.getTime()/1e3);case"x":return a.$d.getTime();case"z":return"["+a.offsetName()+"]";case"zzz":return"["+a.offsetName("long")+"]";default:return h}});return n.bind(this)(u)}}})});function Nue(t,e,r){let n=!0;for(;n;)n=!1,r.forEach(function(i){let a="^\\s*"+i+"\\s*$",s=new RegExp(a);t[0].match(s)&&(e[i]=!0,t.shift(1),n=!0)})}var xue,ho,bue,wue,Tue,yue,Gc,ZI,JI,eO,mb,gb,tO,rO,f6,E1,nO,kue,iO,yb,aO,sO,d6,jI,ize,aze,sze,oze,lze,cze,uze,hze,fze,dze,pze,mze,gze,yze,vze,xze,bze,wze,Tze,kze,Eze,Sze,Cze,Eue,Aze,_ze,Dze,Sue,Lze,KI,Cue,Aue,u6,k1,Rze,Nze,QI,h6,Gi,_ue,Mze,Cp,Ize,vue,Oze,Due,Pze,Lue,Bze,Fze,Rue,Mue=N(()=>{"use strict";xue=Sa(z0(),1),ho=Sa(R4(),1),bue=Sa(pue(),1),wue=Sa(mue(),1),Tue=Sa(gue(),1);vt();zt();ir();mi();ho.default.extend(bue.default);ho.default.extend(wue.default);ho.default.extend(Tue.default);yue={friday:5,saturday:6},Gc="",ZI="",eO="",mb=[],gb=[],tO=new Map,rO=[],f6=[],E1="",nO="",kue=["active","done","crit","milestone"],iO=[],yb=!1,aO=!1,sO="sunday",d6="saturday",jI=0,ize=o(function(){rO=[],f6=[],E1="",iO=[],u6=0,QI=void 0,h6=void 0,Gi=[],Gc="",ZI="",nO="",JI=void 0,eO="",mb=[],gb=[],yb=!1,aO=!1,jI=0,tO=new Map,Ar(),sO="sunday",d6="saturday"},"clear"),aze=o(function(t){ZI=t},"setAxisFormat"),sze=o(function(){return ZI},"getAxisFormat"),oze=o(function(t){JI=t},"setTickInterval"),lze=o(function(){return JI},"getTickInterval"),cze=o(function(t){eO=t},"setTodayMarker"),uze=o(function(){return eO},"getTodayMarker"),hze=o(function(t){Gc=t},"setDateFormat"),fze=o(function(){yb=!0},"enableInclusiveEndDates"),dze=o(function(){return yb},"endDatesAreInclusive"),pze=o(function(){aO=!0},"enableTopAxis"),mze=o(function(){return aO},"topAxisEnabled"),gze=o(function(t){nO=t},"setDisplayMode"),yze=o(function(){return nO},"getDisplayMode"),vze=o(function(){return Gc},"getDateFormat"),xze=o(function(t){mb=t.toLowerCase().split(/[\s,]+/)},"setIncludes"),bze=o(function(){return mb},"getIncludes"),wze=o(function(t){gb=t.toLowerCase().split(/[\s,]+/)},"setExcludes"),Tze=o(function(){return gb},"getExcludes"),kze=o(function(){return tO},"getLinks"),Eze=o(function(t){E1=t,rO.push(t)},"addSection"),Sze=o(function(){return rO},"getSections"),Cze=o(function(){let t=vue(),e=10,r=0;for(;!t&&r<e;)t=vue(),r++;return f6=Gi,f6},"getTasks"),Eue=o(function(t,e,r,n){return n.includes(t.format(e.trim()))?!1:r.includes("weekends")&&(t.isoWeekday()===yue[d6]||t.isoWeekday()===yue[d6]+1)||r.includes(t.format("dddd").toLowerCase())?!0:r.includes(t.format(e.trim()))},"isInvalidDate"),Aze=o(function(t){sO=t},"setWeekday"),_ze=o(function(){return sO},"getWeekday"),Dze=o(function(t){d6=t},"setWeekend"),Sue=o(function(t,e,r,n){if(!r.length||t.manualEndTime)return;let i;t.startTime instanceof Date?i=(0,ho.default)(t.startTime):i=(0,ho.default)(t.startTime,e,!0),i=i.add(1,"d");let a;t.endTime instanceof Date?a=(0,ho.default)(t.endTime):a=(0,ho.default)(t.endTime,e,!0);let[s,l]=Lze(i,a,e,r,n);t.endTime=s.toDate(),t.renderEndTime=l},"checkTaskDates"),Lze=o(function(t,e,r,n,i){let a=!1,s=null;for(;t<=e;)a||(s=e.toDate()),a=Eue(t,r,n,i),a&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,s]},"fixTaskDates"),KI=o(function(t,e,r){r=r.trim();let i=/^after\s+(?<ids>[\d\w- ]+)/.exec(r);if(i!==null){let s=null;for(let u of i.groups.ids.split(" ")){let h=Cp(u);h!==void 0&&(!s||h.endTime>s.endTime)&&(s=h)}if(s)return s.endTime;let l=new Date;return l.setHours(0,0,0,0),l}let a=(0,ho.default)(r,e.trim(),!0);if(a.isValid())return a.toDate();{Y.debug("Invalid date:"+r),Y.debug("With date format:"+e.trim());let s=new Date(r);if(s===void 0||isNaN(s.getTime())||s.getFullYear()<-1e4||s.getFullYear()>1e4)throw new Error("Invalid date:"+r);return s}},"getStartDate"),Cue=o(function(t){let e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return e!==null?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},"parseDuration"),Aue=o(function(t,e,r,n=!1){r=r.trim();let a=/^until\s+(?<ids>[\d\w- ]+)/.exec(r);if(a!==null){let f=null;for(let p of a.groups.ids.split(" ")){let m=Cp(p);m!==void 0&&(!f||m.startTime<f.startTime)&&(f=m)}if(f)return f.startTime;let d=new Date;return d.setHours(0,0,0,0),d}let s=(0,ho.default)(r,e.trim(),!0);if(s.isValid())return n&&(s=s.add(1,"d")),s.toDate();let l=(0,ho.default)(t),[u,h]=Cue(r);if(!Number.isNaN(u)){let f=l.add(u,h);f.isValid()&&(l=f)}return l.toDate()},"getEndDate"),u6=0,k1=o(function(t){return t===void 0?(u6=u6+1,"task"+u6):t},"parseId"),Rze=o(function(t,e){let r;e.substr(0,1)===":"?r=e.substr(1,e.length):r=e;let n=r.split(","),i={};Nue(n,i,kue);for(let s=0;s<n.length;s++)n[s]=n[s].trim();let a="";switch(n.length){case 1:i.id=k1(),i.startTime=t.endTime,a=n[0];break;case 2:i.id=k1(),i.startTime=KI(void 0,Gc,n[0]),a=n[1];break;case 3:i.id=k1(n[0]),i.startTime=KI(void 0,Gc,n[1]),a=n[2];break;default:}return a&&(i.endTime=Aue(i.startTime,Gc,a,yb),i.manualEndTime=(0,ho.default)(a,"YYYY-MM-DD",!0).isValid(),Sue(i,Gc,gb,mb)),i},"compileData"),Nze=o(function(t,e){let r;e.substr(0,1)===":"?r=e.substr(1,e.length):r=e;let n=r.split(","),i={};Nue(n,i,kue);for(let a=0;a<n.length;a++)n[a]=n[a].trim();switch(n.length){case 1:i.id=k1(),i.startTime={type:"prevTaskEnd",id:t},i.endTime={data:n[0]};break;case 2:i.id=k1(),i.startTime={type:"getStartDate",startData:n[0]},i.endTime={data:n[1]};break;case 3:i.id=k1(n[0]),i.startTime={type:"getStartDate",startData:n[1]},i.endTime={data:n[2]};break;default:}return i},"parseData"),Gi=[],_ue={},Mze=o(function(t,e){let r={section:E1,type:E1,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},n=Nze(h6,e);r.raw.startTime=n.startTime,r.raw.endTime=n.endTime,r.id=n.id,r.prevTaskId=h6,r.active=n.active,r.done=n.done,r.crit=n.crit,r.milestone=n.milestone,r.order=jI,jI++;let i=Gi.push(r);h6=r.id,_ue[r.id]=i-1},"addTask"),Cp=o(function(t){let e=_ue[t];return Gi[e]},"findTaskById"),Ize=o(function(t,e){let r={section:E1,type:E1,description:t,task:t,classes:[]},n=Rze(QI,e);r.startTime=n.startTime,r.endTime=n.endTime,r.id=n.id,r.active=n.active,r.done=n.done,r.crit=n.crit,r.milestone=n.milestone,QI=r,f6.push(r)},"addTaskOrg"),vue=o(function(){let t=o(function(r){let n=Gi[r],i="";switch(Gi[r].raw.startTime.type){case"prevTaskEnd":{let a=Cp(n.prevTaskId);n.startTime=a.endTime;break}case"getStartDate":i=KI(void 0,Gc,Gi[r].raw.startTime.startData),i&&(Gi[r].startTime=i);break}return Gi[r].startTime&&(Gi[r].endTime=Aue(Gi[r].startTime,Gc,Gi[r].raw.endTime.data,yb),Gi[r].endTime&&(Gi[r].processed=!0,Gi[r].manualEndTime=(0,ho.default)(Gi[r].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),Sue(Gi[r],Gc,gb,mb))),Gi[r].processed},"compileTask"),e=!0;for(let[r,n]of Gi.entries())t(r),e=e&&n.processed;return e},"compileTasks"),Oze=o(function(t,e){let r=e;me().securityLevel!=="loose"&&(r=(0,xue.sanitizeUrl)(e)),t.split(",").forEach(function(n){Cp(n)!==void 0&&(Lue(n,()=>{window.open(r,"_self")}),tO.set(n,r))}),Due(t,"clickable")},"setLink"),Due=o(function(t,e){t.split(",").forEach(function(r){let n=Cp(r);n!==void 0&&n.classes.push(e)})},"setClass"),Pze=o(function(t,e,r){if(me().securityLevel!=="loose"||e===void 0)return;let n=[];if(typeof r=="string"){n=r.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let a=0;a<n.length;a++){let s=n[a].trim();s.startsWith('"')&&s.endsWith('"')&&(s=s.substr(1,s.length-2)),n[a]=s}}n.length===0&&n.push(t),Cp(t)!==void 0&&Lue(t,()=>{Gt.runFunc(e,...n)})},"setClickFun"),Lue=o(function(t,e){iO.push(function(){let r=document.querySelector(`[id="${t}"]`);r!==null&&r.addEventListener("click",function(){e()})},function(){let r=document.querySelector(`[id="${t}-text"]`);r!==null&&r.addEventListener("click",function(){e()})})},"pushFun"),Bze=o(function(t,e,r){t.split(",").forEach(function(n){Pze(n,e,r)}),Due(t,"clickable")},"setClickEvent"),Fze=o(function(t){iO.forEach(function(e){e(t)})},"bindFunctions"),Rue={getConfig:o(()=>me().gantt,"getConfig"),clear:ize,setDateFormat:hze,getDateFormat:vze,enableInclusiveEndDates:fze,endDatesAreInclusive:dze,enableTopAxis:pze,topAxisEnabled:mze,setAxisFormat:aze,getAxisFormat:sze,setTickInterval:oze,getTickInterval:lze,setTodayMarker:cze,getTodayMarker:uze,setAccTitle:Lr,getAccTitle:Rr,setDiagramTitle:$r,getDiagramTitle:Ir,setDisplayMode:gze,getDisplayMode:yze,setAccDescription:Nr,getAccDescription:Mr,addSection:Eze,getSections:Sze,getTasks:Cze,addTask:Mze,findTaskById:Cp,addTaskOrg:Ize,setIncludes:xze,getIncludes:bze,setExcludes:wze,getExcludes:Tze,setClickEvent:Bze,setLink:Oze,getLinks:kze,bindFunctions:Fze,parseDuration:Cue,isInvalidDate:Eue,setWeekday:Aze,getWeekday:_ze,setWeekend:Dze};o(Nue,"getTaskTags")});var p6,$ze,Iue,zze,Yu,Gze,Oue,Pue=N(()=>{"use strict";p6=Sa(R4(),1);vt();dr();gr();zt();Ei();$ze=o(function(){Y.debug("Something is calling, setConf, remove the call")},"setConf"),Iue={monday:Ch,tuesday:T5,wednesday:k5,thursday:oc,friday:E5,saturday:S5,sunday:yl},zze=o((t,e)=>{let r=[...t].map(()=>-1/0),n=[...t].sort((a,s)=>a.startTime-s.startTime||a.order-s.order),i=0;for(let a of n)for(let s=0;s<r.length;s++)if(a.startTime>=r[s]){r[s]=a.endTime,a.order=s+e,s>i&&(i=s);break}return i},"getMaxIntersections"),Gze=o(function(t,e,r,n){let i=me().gantt,a=me().securityLevel,s;a==="sandbox"&&(s=Ge("#i"+e));let l=a==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body"),u=a==="sandbox"?s.nodes()[0].contentDocument:document,h=u.getElementById(e);Yu=h.parentElement.offsetWidth,Yu===void 0&&(Yu=1200),i.useWidth!==void 0&&(Yu=i.useWidth);let f=n.db.getTasks(),d=[];for(let S of f)d.push(S.type);d=A(d);let p={},m=2*i.topPadding;if(n.db.getDisplayMode()==="compact"||i.displayMode==="compact"){let S={};for(let I of f)S[I.section]===void 0?S[I.section]=[I]:S[I.section].push(I);let _=0;for(let I of Object.keys(S)){let D=zze(S[I],_)+1;_+=D,m+=D*(i.barHeight+i.barGap),p[I]=D}}else{m+=f.length*(i.barHeight+i.barGap);for(let S of d)p[S]=f.filter(_=>_.type===S).length}h.setAttribute("viewBox","0 0 "+Yu+" "+m);let g=l.select(`[id="${e}"]`),y=_5().domain([M3(f,function(S){return S.startTime}),N3(f,function(S){return S.endTime})]).rangeRound([0,Yu-i.leftPadding-i.rightPadding]);function v(S,_){let I=S.startTime,D=_.startTime,k=0;return I>D?k=1:I<D&&(k=-1),k}o(v,"taskCompare"),f.sort(v),x(f,Yu,m),vn(g,m,Yu,i.useMaxWidth),g.append("text").text(n.db.getDiagramTitle()).attr("x",Yu/2).attr("y",i.titleTopMargin).attr("class","titleText");function x(S,_,I){let D=i.barHeight,k=D+i.barGap,L=i.topPadding,R=i.leftPadding,O=gl().domain([0,d.length]).range(["#00B9FA","#F95002"]).interpolate($8);w(k,L,R,_,I,S,n.db.getExcludes(),n.db.getIncludes()),C(R,L,_,I),b(S,k,L,R,D,O,_,I),T(k,L,R,D,O),E(R,L,_,I)}o(x,"makeGantt");function b(S,_,I,D,k,L,R){let M=[...new Set(S.map(z=>z.order))].map(z=>S.find($=>$.order===z));g.append("g").selectAll("rect").data(M).enter().append("rect").attr("x",0).attr("y",function(z,$){return $=z.order,$*_+I-2}).attr("width",function(){return R-i.rightPadding/2}).attr("height",_).attr("class",function(z){for(let[$,H]of d.entries())if(z.type===H)return"section section"+$%i.numberSectionStyles;return"section section0"});let B=g.append("g").selectAll("rect").data(S).enter(),F=n.db.getLinks();if(B.append("rect").attr("id",function(z){return z.id}).attr("rx",3).attr("ry",3).attr("x",function(z){return z.milestone?y(z.startTime)+D+.5*(y(z.endTime)-y(z.startTime))-.5*k:y(z.startTime)+D}).attr("y",function(z,$){return $=z.order,$*_+I}).attr("width",function(z){return z.milestone?k:y(z.renderEndTime||z.endTime)-y(z.startTime)}).attr("height",k).attr("transform-origin",function(z,$){return $=z.order,(y(z.startTime)+D+.5*(y(z.endTime)-y(z.startTime))).toString()+"px "+($*_+I+.5*k).toString()+"px"}).attr("class",function(z){let $="task",H="";z.classes.length>0&&(H=z.classes.join(" "));let Q=0;for(let[ie,ne]of d.entries())z.type===ne&&(Q=ie%i.numberSectionStyles);let j="";return z.active?z.crit?j+=" activeCrit":j=" active":z.done?z.crit?j=" doneCrit":j=" done":z.crit&&(j+=" crit"),j.length===0&&(j=" task"),z.milestone&&(j=" milestone "+j),j+=Q,j+=" "+H,$+j}),B.append("text").attr("id",function(z){return z.id+"-text"}).text(function(z){return z.task}).attr("font-size",i.fontSize).attr("x",function(z){let $=y(z.startTime),H=y(z.renderEndTime||z.endTime);z.milestone&&($+=.5*(y(z.endTime)-y(z.startTime))-.5*k),z.milestone&&(H=$+k);let Q=this.getBBox().width;return Q>H-$?H+Q+1.5*i.leftPadding>R?$+D-5:H+D+5:(H-$)/2+$+D}).attr("y",function(z,$){return $=z.order,$*_+i.barHeight/2+(i.fontSize/2-2)+I}).attr("text-height",k).attr("class",function(z){let $=y(z.startTime),H=y(z.endTime);z.milestone&&(H=$+k);let Q=this.getBBox().width,j="";z.classes.length>0&&(j=z.classes.join(" "));let ie=0;for(let[le,he]of d.entries())z.type===he&&(ie=le%i.numberSectionStyles);let ne="";return z.active&&(z.crit?ne="activeCritText"+ie:ne="activeText"+ie),z.done?z.crit?ne=ne+" doneCritText"+ie:ne=ne+" doneText"+ie:z.crit&&(ne=ne+" critText"+ie),z.milestone&&(ne+=" milestoneText"),Q>H-$?H+Q+1.5*i.leftPadding>R?j+" taskTextOutsideLeft taskTextOutside"+ie+" "+ne:j+" taskTextOutsideRight taskTextOutside"+ie+" "+ne+" width-"+Q:j+" taskText taskText"+ie+" "+ne+" width-"+Q}),me().securityLevel==="sandbox"){let z;z=Ge("#i"+e);let $=z.nodes()[0].contentDocument;B.filter(function(H){return F.has(H.id)}).each(function(H){var Q=$.querySelector("#"+H.id),j=$.querySelector("#"+H.id+"-text");let ie=Q.parentNode;var ne=$.createElement("a");ne.setAttribute("xlink:href",F.get(H.id)),ne.setAttribute("target","_top"),ie.appendChild(ne),ne.appendChild(Q),ne.appendChild(j)})}}o(b,"drawRects");function w(S,_,I,D,k,L,R,O){if(R.length===0&&O.length===0)return;let M,B;for(let{startTime:Q,endTime:j}of L)(M===void 0||Q<M)&&(M=Q),(B===void 0||j>B)&&(B=j);if(!M||!B)return;if((0,p6.default)(B).diff((0,p6.default)(M),"year")>5){Y.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");return}let F=n.db.getDateFormat(),P=[],z=null,$=(0,p6.default)(M);for(;$.valueOf()<=B;)n.db.isInvalidDate($,F,R,O)?z?z.end=$:z={start:$,end:$}:z&&(P.push(z),z=null),$=$.add(1,"d");g.append("g").selectAll("rect").data(P).enter().append("rect").attr("id",function(Q){return"exclude-"+Q.start.format("YYYY-MM-DD")}).attr("x",function(Q){return y(Q.start)+I}).attr("y",i.gridLineStartPadding).attr("width",function(Q){let j=Q.end.add(1,"day");return y(j)-y(Q.start)}).attr("height",k-_-i.gridLineStartPadding).attr("transform-origin",function(Q,j){return(y(Q.start)+I+.5*(y(Q.end)-y(Q.start))).toString()+"px "+(j*S+.5*k).toString()+"px"}).attr("class","exclude-range")}o(w,"drawExcludeDays");function C(S,_,I,D){let k=bA(y).tickSize(-D+_+i.gridLineStartPadding).tickFormat(wd(n.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d")),R=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(n.db.getTickInterval()||i.tickInterval);if(R!==null){let O=R[1],M=R[2],B=n.db.getWeekday()||i.weekday;switch(M){case"millisecond":k.ticks(ac.every(O));break;case"second":k.ticks(Ks.every(O));break;case"minute":k.ticks(vu.every(O));break;case"hour":k.ticks(xu.every(O));break;case"day":k.ticks(_o.every(O));break;case"week":k.ticks(Iue[B].every(O));break;case"month":k.ticks(bu.every(O));break}}if(g.append("g").attr("class","grid").attr("transform","translate("+S+", "+(D-50)+")").call(k).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),n.db.topAxisEnabled()||i.topAxis){let O=xA(y).tickSize(-D+_+i.gridLineStartPadding).tickFormat(wd(n.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));if(R!==null){let M=R[1],B=R[2],F=n.db.getWeekday()||i.weekday;switch(B){case"millisecond":O.ticks(ac.every(M));break;case"second":O.ticks(Ks.every(M));break;case"minute":O.ticks(vu.every(M));break;case"hour":O.ticks(xu.every(M));break;case"day":O.ticks(_o.every(M));break;case"week":O.ticks(Iue[F].every(M));break;case"month":O.ticks(bu.every(M));break}}g.append("g").attr("class","grid").attr("transform","translate("+S+", "+_+")").call(O).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}o(C,"makeGrid");function T(S,_){let I=0,D=Object.keys(p).map(k=>[k,p[k]]);g.append("g").selectAll("text").data(D).enter().append(function(k){let L=k[0].split(Ze.lineBreakRegex),R=-(L.length-1)/2,O=u.createElementNS("http://www.w3.org/2000/svg","text");O.setAttribute("dy",R+"em");for(let[M,B]of L.entries()){let F=u.createElementNS("http://www.w3.org/2000/svg","tspan");F.setAttribute("alignment-baseline","central"),F.setAttribute("x","10"),M>0&&F.setAttribute("dy","1em"),F.textContent=B,O.appendChild(F)}return O}).attr("x",10).attr("y",function(k,L){if(L>0)for(let R=0;R<L;R++)return I+=D[L-1][1],k[1]*S/2+I*S+_;else return k[1]*S/2+_}).attr("font-size",i.sectionFontSize).attr("class",function(k){for(let[L,R]of d.entries())if(k[0]===R)return"sectionTitle sectionTitle"+L%i.numberSectionStyles;return"sectionTitle"})}o(T,"vertLabels");function E(S,_,I,D){let k=n.db.getTodayMarker();if(k==="off")return;let L=g.append("g").attr("class","today"),R=new Date,O=L.append("line");O.attr("x1",y(R)+S).attr("x2",y(R)+S).attr("y1",i.titleTopMargin).attr("y2",D-i.titleTopMargin).attr("class","today"),k!==""&&O.attr("style",k.replace(/,/g,";"))}o(E,"drawToday");function A(S){let _={},I=[];for(let D=0,k=S.length;D<k;++D)Object.prototype.hasOwnProperty.call(_,S[D])||(_[S[D]]=!0,I.push(S[D]));return I}o(A,"checkUnique")},"draw"),Oue={setConf:$ze,draw:Gze}});var Vze,Bue,Fue=N(()=>{"use strict";Vze=o(t=>`
+ .mermaid-main-font {
+ font-family: ${t.fontFamily};
+ }
+
+ .exclude-range {
+ fill: ${t.excludeBkgColor};
+ }
+
+ .section {
+ stroke: none;
+ opacity: 0.2;
+ }
+
+ .section0 {
+ fill: ${t.sectionBkgColor};
+ }
+
+ .section2 {
+ fill: ${t.sectionBkgColor2};
+ }
+
+ .section1,
+ .section3 {
+ fill: ${t.altSectionBkgColor};
+ opacity: 0.2;
+ }
+
+ .sectionTitle0 {
+ fill: ${t.titleColor};
+ }
+
+ .sectionTitle1 {
+ fill: ${t.titleColor};
+ }
+
+ .sectionTitle2 {
+ fill: ${t.titleColor};
+ }
+
+ .sectionTitle3 {
+ fill: ${t.titleColor};
+ }
+
+ .sectionTitle {
+ text-anchor: start;
+ font-family: ${t.fontFamily};
+ }
+
+
+ /* Grid and axis */
+
+ .grid .tick {
+ stroke: ${t.gridColor};
+ opacity: 0.8;
+ shape-rendering: crispEdges;
+ }
+
+ .grid .tick text {
+ font-family: ${t.fontFamily};
+ fill: ${t.textColor};
+ }
+
+ .grid path {
+ stroke-width: 0;
+ }
+
+
+ /* Today line */
+
+ .today {
+ fill: none;
+ stroke: ${t.todayLineColor};
+ stroke-width: 2px;
+ }
+
+
+ /* Task styling */
+
+ /* Default task */
+
+ .task {
+ stroke-width: 2;
+ }
+
+ .taskText {
+ text-anchor: middle;
+ font-family: ${t.fontFamily};
+ }
+
+ .taskTextOutsideRight {
+ fill: ${t.taskTextDarkColor};
+ text-anchor: start;
+ font-family: ${t.fontFamily};
+ }
+
+ .taskTextOutsideLeft {
+ fill: ${t.taskTextDarkColor};
+ text-anchor: end;
+ }
+
+
+ /* Special case clickable */
+
+ .task.clickable {
+ cursor: pointer;
+ }
+
+ .taskText.clickable {
+ cursor: pointer;
+ fill: ${t.taskTextClickableColor} !important;
+ font-weight: bold;
+ }
+
+ .taskTextOutsideLeft.clickable {
+ cursor: pointer;
+ fill: ${t.taskTextClickableColor} !important;
+ font-weight: bold;
+ }
+
+ .taskTextOutsideRight.clickable {
+ cursor: pointer;
+ fill: ${t.taskTextClickableColor} !important;
+ font-weight: bold;
+ }
+
+
+ /* Specific task settings for the sections*/
+
+ .taskText0,
+ .taskText1,
+ .taskText2,
+ .taskText3 {
+ fill: ${t.taskTextColor};
+ }
+
+ .task0,
+ .task1,
+ .task2,
+ .task3 {
+ fill: ${t.taskBkgColor};
+ stroke: ${t.taskBorderColor};
+ }
+
+ .taskTextOutside0,
+ .taskTextOutside2
+ {
+ fill: ${t.taskTextOutsideColor};
+ }
+
+ .taskTextOutside1,
+ .taskTextOutside3 {
+ fill: ${t.taskTextOutsideColor};
+ }
+
+
+ /* Active task */
+
+ .active0,
+ .active1,
+ .active2,
+ .active3 {
+ fill: ${t.activeTaskBkgColor};
+ stroke: ${t.activeTaskBorderColor};
+ }
+
+ .activeText0,
+ .activeText1,
+ .activeText2,
+ .activeText3 {
+ fill: ${t.taskTextDarkColor} !important;
+ }
+
+
+ /* Completed task */
+
+ .done0,
+ .done1,
+ .done2,
+ .done3 {
+ stroke: ${t.doneTaskBorderColor};
+ fill: ${t.doneTaskBkgColor};
+ stroke-width: 2;
+ }
+
+ .doneText0,
+ .doneText1,
+ .doneText2,
+ .doneText3 {
+ fill: ${t.taskTextDarkColor} !important;
+ }
+
+
+ /* Tasks on the critical line */
+
+ .crit0,
+ .crit1,
+ .crit2,
+ .crit3 {
+ stroke: ${t.critBorderColor};
+ fill: ${t.critBkgColor};
+ stroke-width: 2;
+ }
+
+ .activeCrit0,
+ .activeCrit1,
+ .activeCrit2,
+ .activeCrit3 {
+ stroke: ${t.critBorderColor};
+ fill: ${t.activeTaskBkgColor};
+ stroke-width: 2;
+ }
+
+ .doneCrit0,
+ .doneCrit1,
+ .doneCrit2,
+ .doneCrit3 {
+ stroke: ${t.critBorderColor};
+ fill: ${t.doneTaskBkgColor};
+ stroke-width: 2;
+ cursor: pointer;
+ shape-rendering: crispEdges;
+ }
+
+ .milestone {
+ transform: rotate(45deg) scale(0.8,0.8);
+ }
+
+ .milestoneText {
+ font-style: italic;
+ }
+ .doneCritText0,
+ .doneCritText1,
+ .doneCritText2,
+ .doneCritText3 {
+ fill: ${t.taskTextDarkColor} !important;
+ }
+
+ .activeCritText0,
+ .activeCritText1,
+ .activeCritText2,
+ .activeCritText3 {
+ fill: ${t.taskTextDarkColor} !important;
+ }
+
+ .titleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: ${t.titleColor||t.textColor};
+ font-family: ${t.fontFamily};
+ }
+`,"getStyles"),Bue=Vze});var $ue={};hr($ue,{diagram:()=>Uze});var Uze,zue=N(()=>{"use strict";due();Mue();Pue();Fue();Uze={parser:fue,db:Rue,renderer:Oue,styles:Bue}});var Uue,Hue=N(()=>{"use strict";kp();vt();Uue={parse:o(async t=>{let e=await uo("info",t);Y.debug(e)},"parse")}});var vb,oO=N(()=>{vb={name:"mermaid",version:"11.6.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",type:"module",module:"./dist/mermaid.core.mjs",types:"./dist/mermaid.d.ts",exports:{".":{types:"./dist/mermaid.d.ts",import:"./dist/mermaid.core.mjs",default:"./dist/mermaid.core.mjs"},"./*":"./*"},keywords:["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph","mindmap","packet diagram","c4 diagram","er diagram","pie chart","pie diagram","quadrant chart","requirement diagram","graph"],scripts:{clean:"rimraf dist",dev:"pnpm -w dev","docs:code":"typedoc src/defaultConfig.ts src/config.ts src/mermaid.ts && prettier --write ./src/docs/config/setup","docs:build":"rimraf ../../docs && pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts","docs:verify":"pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts --verify","docs:pre:vitepress":"pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts","docs:build:vitepress":"pnpm docs:pre:vitepress && (cd src/vitepress && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing","docs:dev":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:dev:docker":'pnpm docs:pre:vitepress && concurrently "pnpm --filter ./src/vitepress dev:docker" "tsx scripts/docs.cli.mts --watch --vitepress"',"docs:serve":"pnpm docs:build:vitepress && vitepress serve src/vitepress","docs:spellcheck":'cspell "src/docs/**/*.md"',"docs:release-version":"tsx scripts/update-release-version.mts","docs:verify-version":"tsx scripts/update-release-version.mts --verify","types:build-config":"tsx scripts/create-types-from-json-schema.mts","types:verify-config":"tsx scripts/create-types-from-json-schema.mts --verify",checkCircle:"npx madge --circular ./src",prepublishOnly:"pnpm docs:verify-version"},repository:{type:"git",url:"https://github.com/mermaid-js/mermaid"},author:"Knut Sveidqvist",license:"MIT",standard:{ignore:["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],globals:["page"]},dependencies:{"@braintree/sanitize-url":"^7.0.4","@iconify/utils":"^2.1.33","@mermaid-js/parser":"workspace:^","@types/d3":"^7.4.3",cytoscape:"^3.29.3","cytoscape-cose-bilkent":"^4.1.0","cytoscape-fcose":"^2.2.0",d3:"^7.9.0","d3-sankey":"^0.12.3","dagre-d3-es":"7.0.11",dayjs:"^1.11.13",dompurify:"^3.2.4",katex:"^0.16.9",khroma:"^2.1.0","lodash-es":"^4.17.21",marked:"^15.0.7",roughjs:"^4.6.6",stylis:"^4.3.6","ts-dedent":"^2.2.0",uuid:"^11.1.0"},devDependencies:{"@adobe/jsonschema2md":"^8.0.2","@iconify/types":"^2.0.0","@types/cytoscape":"^3.21.9","@types/cytoscape-fcose":"^2.2.4","@types/d3-sankey":"^0.12.4","@types/d3-scale":"^4.0.9","@types/d3-scale-chromatic":"^3.1.0","@types/d3-selection":"^3.0.11","@types/d3-shape":"^3.1.7","@types/jsdom":"^21.1.7","@types/katex":"^0.16.7","@types/lodash-es":"^4.17.12","@types/micromatch":"^4.0.9","@types/stylis":"^4.2.7","@types/uuid":"^10.0.0",ajv:"^8.17.1",chokidar:"^4.0.3",concurrently:"^9.1.2","csstree-validator":"^4.0.1",globby:"^14.0.2",jison:"^0.4.18","js-base64":"^3.7.7",jsdom:"^26.0.0","json-schema-to-typescript":"^15.0.4",micromatch:"^4.0.8","path-browserify":"^1.0.1",prettier:"^3.5.2",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-gfm":"^4.0.1",rimraf:"^6.0.1","start-server-and-test":"^2.0.10","type-fest":"^4.35.0",typedoc:"^0.27.8","typedoc-plugin-markdown":"^4.4.2",typescript:"~5.7.3","unist-util-flatmap":"^1.0.0","unist-util-visit":"^5.0.0",vitepress:"^1.0.2","vitepress-plugin-search":"1.0.4-alpha.22"},files:["dist/","README.md"],publishConfig:{access:"public"}}});var Xze,jze,Wue,que=N(()=>{"use strict";oO();Xze={version:vb.version},jze=o(()=>Xze.version,"getVersion"),Wue={getVersion:jze}});var sa,Vc=N(()=>{"use strict";dr();zt();sa=o(t=>{let{securityLevel:e}=me(),r=Ge("body");if(e==="sandbox"){let a=Ge(`#i${t}`).node()?.contentDocument??document;r=Ge(a.body)}return r.select(`#${t}`)},"selectSvgElement")});var Kze,Yue,Xue=N(()=>{"use strict";vt();Vc();Ei();Kze=o((t,e,r)=>{Y.debug(`rendering info diagram
+`+t);let n=sa(e);vn(n,100,400,!0),n.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${r}`)},"draw"),Yue={draw:Kze}});var jue={};hr(jue,{diagram:()=>Qze});var Qze,Kue=N(()=>{"use strict";Hue();que();Xue();Qze={parser:Uue,db:Wue,renderer:Yue}});var Jue,lO,m6,cO,eGe,tGe,rGe,nGe,iGe,aGe,sGe,g6,uO=N(()=>{"use strict";vt();mi();Ya();Jue=or.pie,lO={sections:new Map,showData:!1,config:Jue},m6=lO.sections,cO=lO.showData,eGe=structuredClone(Jue),tGe=o(()=>structuredClone(eGe),"getConfig"),rGe=o(()=>{m6=new Map,cO=lO.showData,Ar()},"clear"),nGe=o(({label:t,value:e})=>{m6.has(t)||(m6.set(t,e),Y.debug(`added new section: ${t}, with value: ${e}`))},"addSection"),iGe=o(()=>m6,"getSections"),aGe=o(t=>{cO=t},"setShowData"),sGe=o(()=>cO,"getShowData"),g6={getConfig:tGe,clear:rGe,setDiagramTitle:$r,getDiagramTitle:Ir,setAccTitle:Lr,getAccTitle:Rr,setAccDescription:Nr,getAccDescription:Mr,addSection:nGe,getSections:iGe,setShowData:aGe,getShowData:sGe}});var oGe,ehe,the=N(()=>{"use strict";kp();vt();T1();uO();oGe=o((t,e)=>{$c(t,e),e.setShowData(t.showData),t.sections.map(e.addSection)},"populateDb"),ehe={parse:o(async t=>{let e=await uo("pie",t);Y.debug(e),oGe(e,g6)},"parse")}});var lGe,rhe,nhe=N(()=>{"use strict";lGe=o(t=>`
+ .pieCircle{
+ stroke: ${t.pieStrokeColor};
+ stroke-width : ${t.pieStrokeWidth};
+ opacity : ${t.pieOpacity};
+ }
+ .pieOuterCircle{
+ stroke: ${t.pieOuterStrokeColor};
+ stroke-width: ${t.pieOuterStrokeWidth};
+ fill: none;
+ }
+ .pieTitleText {
+ text-anchor: middle;
+ font-size: ${t.pieTitleTextSize};
+ fill: ${t.pieTitleTextColor};
+ font-family: ${t.fontFamily};
+ }
+ .slice {
+ font-family: ${t.fontFamily};
+ fill: ${t.pieSectionTextColor};
+ font-size:${t.pieSectionTextSize};
+ // fill: white;
+ }
+ .legend text {
+ fill: ${t.pieLegendTextColor};
+ font-family: ${t.fontFamily};
+ font-size: ${t.pieLegendTextSize};
+ }
+`,"getStyles"),rhe=lGe});var cGe,uGe,ihe,ahe=N(()=>{"use strict";dr();zt();vt();Vc();Ei();ir();cGe=o(t=>{let e=[...t.entries()].map(n=>({label:n[0],value:n[1]})).sort((n,i)=>i.value-n.value);return I5().value(n=>n.value)(e)},"createPieArcs"),uGe=o((t,e,r,n)=>{Y.debug(`rendering pie chart
+`+t);let i=n.db,a=me(),s=Fi(i.getConfig(),a.pie),l=40,u=18,h=4,f=450,d=f,p=sa(e),m=p.append("g");m.attr("transform","translate("+d/2+","+f/2+")");let{themeVariables:g}=a,[y]=Bo(g.pieOuterStrokeWidth);y??=2;let v=s.textPosition,x=Math.min(d,f)/2-l,b=bl().innerRadius(0).outerRadius(x),w=bl().innerRadius(x*v).outerRadius(x*v);m.append("circle").attr("cx",0).attr("cy",0).attr("r",x+y/2).attr("class","pieOuterCircle");let C=i.getSections(),T=cGe(C),E=[g.pie1,g.pie2,g.pie3,g.pie4,g.pie5,g.pie6,g.pie7,g.pie8,g.pie9,g.pie10,g.pie11,g.pie12],A=gu(E);m.selectAll("mySlices").data(T).enter().append("path").attr("d",b).attr("fill",k=>A(k.data.label)).attr("class","pieCircle");let S=0;C.forEach(k=>{S+=k}),m.selectAll("mySlices").data(T).enter().append("text").text(k=>(k.data.value/S*100).toFixed(0)+"%").attr("transform",k=>"translate("+w.centroid(k)+")").style("text-anchor","middle").attr("class","slice"),m.append("text").text(i.getDiagramTitle()).attr("x",0).attr("y",-(f-50)/2).attr("class","pieTitleText");let _=m.selectAll(".legend").data(A.domain()).enter().append("g").attr("class","legend").attr("transform",(k,L)=>{let R=u+h,O=R*A.domain().length/2,M=12*u,B=L*R-O;return"translate("+M+","+B+")"});_.append("rect").attr("width",u).attr("height",u).style("fill",A).style("stroke",A),_.data(T).append("text").attr("x",u+h).attr("y",u-h).text(k=>{let{label:L,value:R}=k.data;return i.getShowData()?`${L} [${R}]`:L});let I=Math.max(..._.selectAll("text").nodes().map(k=>k?.getBoundingClientRect().width??0)),D=d+l+u+h+I;p.attr("viewBox",`0 0 ${D} ${f}`),vn(p,f,D,s.useMaxWidth)},"draw"),ihe={draw:uGe}});var she={};hr(she,{diagram:()=>hGe});var hGe,ohe=N(()=>{"use strict";the();uO();nhe();ahe();hGe={parser:ehe,db:g6,renderer:ihe,styles:rhe}});var hO,uhe,hhe=N(()=>{"use strict";hO=function(){var t=o(function(xe,q,pe,ve){for(pe=pe||{},ve=xe.length;ve--;pe[xe[ve]]=q);return pe},"o"),e=[1,3],r=[1,4],n=[1,5],i=[1,6],a=[1,7],s=[1,4,5,10,12,13,14,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],l=[1,4,5,10,12,13,14,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],u=[55,56,57],h=[2,36],f=[1,37],d=[1,36],p=[1,38],m=[1,35],g=[1,43],y=[1,41],v=[1,14],x=[1,23],b=[1,18],w=[1,19],C=[1,20],T=[1,21],E=[1,22],A=[1,24],S=[1,25],_=[1,26],I=[1,27],D=[1,28],k=[1,29],L=[1,32],R=[1,33],O=[1,34],M=[1,39],B=[1,40],F=[1,42],P=[1,44],z=[1,62],$=[1,61],H=[4,5,8,10,12,13,14,18,44,47,49,55,56,57,63,64,65,66,67],Q=[1,65],j=[1,66],ie=[1,67],ne=[1,68],le=[1,69],he=[1,70],K=[1,71],X=[1,72],te=[1,73],J=[1,74],se=[1,75],ue=[1,76],Z=[4,5,6,7,8,9,10,11,12,13,14,15,18],Se=[1,90],ce=[1,91],ae=[1,92],Oe=[1,99],ge=[1,93],ze=[1,96],He=[1,94],$e=[1,95],Re=[1,97],Ie=[1,98],be=[1,102],W=[10,55,56,57],de=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],re={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:o(function(q,pe,ve,Pe,_e,we,Ve){var De=we.length-1;switch(_e){case 23:this.$=we[De];break;case 24:this.$=we[De-1]+""+we[De];break;case 26:this.$=we[De-1]+we[De];break;case 27:this.$=[we[De].trim()];break;case 28:we[De-2].push(we[De].trim()),this.$=we[De-2];break;case 29:this.$=we[De-4],Pe.addClass(we[De-2],we[De]);break;case 37:this.$=[];break;case 42:this.$=we[De].trim(),Pe.setDiagramTitle(this.$);break;case 43:this.$=we[De].trim(),Pe.setAccTitle(this.$);break;case 44:case 45:this.$=we[De].trim(),Pe.setAccDescription(this.$);break;case 46:Pe.addSection(we[De].substr(8)),this.$=we[De].substr(8);break;case 47:Pe.addPoint(we[De-3],"",we[De-1],we[De],[]);break;case 48:Pe.addPoint(we[De-4],we[De-3],we[De-1],we[De],[]);break;case 49:Pe.addPoint(we[De-4],"",we[De-2],we[De-1],we[De]);break;case 50:Pe.addPoint(we[De-5],we[De-4],we[De-2],we[De-1],we[De]);break;case 51:Pe.setXAxisLeftText(we[De-2]),Pe.setXAxisRightText(we[De]);break;case 52:we[De-1].text+=" \u27F6 ",Pe.setXAxisLeftText(we[De-1]);break;case 53:Pe.setXAxisLeftText(we[De]);break;case 54:Pe.setYAxisBottomText(we[De-2]),Pe.setYAxisTopText(we[De]);break;case 55:we[De-1].text+=" \u27F6 ",Pe.setYAxisBottomText(we[De-1]);break;case 56:Pe.setYAxisBottomText(we[De]);break;case 57:Pe.setQuadrant1Text(we[De]);break;case 58:Pe.setQuadrant2Text(we[De]);break;case 59:Pe.setQuadrant3Text(we[De]);break;case 60:Pe.setQuadrant4Text(we[De]);break;case 64:this.$={text:we[De],type:"text"};break;case 65:this.$={text:we[De-1].text+""+we[De],type:we[De-1].type};break;case 66:this.$={text:we[De],type:"text"};break;case 67:this.$={text:we[De],type:"markdown"};break;case 68:this.$=we[De];break;case 69:this.$=we[De-1]+""+we[De];break}},"anonymous"),table:[{18:e,26:1,27:2,28:r,55:n,56:i,57:a},{1:[3]},{18:e,26:8,27:2,28:r,55:n,56:i,57:a},{18:e,26:9,27:2,28:r,55:n,56:i,57:a},t(s,[2,33],{29:10}),t(l,[2,61]),t(l,[2,62]),t(l,[2,63]),{1:[2,30]},{1:[2,31]},t(u,h,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:f,5:d,10:p,12:m,13:g,14:y,18:v,25:x,35:b,37:w,39:C,41:T,42:E,48:A,50:S,51:_,52:I,53:D,54:k,60:L,61:R,63:O,64:M,65:B,66:F,67:P}),t(s,[2,34]),{27:45,55:n,56:i,57:a},t(u,[2,37]),t(u,h,{24:13,32:15,33:16,34:17,43:30,58:31,31:46,4:f,5:d,10:p,12:m,13:g,14:y,18:v,25:x,35:b,37:w,39:C,41:T,42:E,48:A,50:S,51:_,52:I,53:D,54:k,60:L,61:R,63:O,64:M,65:B,66:F,67:P}),t(u,[2,39]),t(u,[2,40]),t(u,[2,41]),{36:[1,47]},{38:[1,48]},{40:[1,49]},t(u,[2,45]),t(u,[2,46]),{18:[1,50]},{4:f,5:d,10:p,12:m,13:g,14:y,43:51,58:31,60:L,61:R,63:O,64:M,65:B,66:F,67:P},{4:f,5:d,10:p,12:m,13:g,14:y,43:52,58:31,60:L,61:R,63:O,64:M,65:B,66:F,67:P},{4:f,5:d,10:p,12:m,13:g,14:y,43:53,58:31,60:L,61:R,63:O,64:M,65:B,66:F,67:P},{4:f,5:d,10:p,12:m,13:g,14:y,43:54,58:31,60:L,61:R,63:O,64:M,65:B,66:F,67:P},{4:f,5:d,10:p,12:m,13:g,14:y,43:55,58:31,60:L,61:R,63:O,64:M,65:B,66:F,67:P},{4:f,5:d,10:p,12:m,13:g,14:y,43:56,58:31,60:L,61:R,63:O,64:M,65:B,66:F,67:P},{4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,44:[1,57],47:[1,58],58:60,59:59,63:O,64:M,65:B,66:F,67:P},t(H,[2,64]),t(H,[2,66]),t(H,[2,67]),t(H,[2,70]),t(H,[2,71]),t(H,[2,72]),t(H,[2,73]),t(H,[2,74]),t(H,[2,75]),t(H,[2,76]),t(H,[2,77]),t(H,[2,78]),t(H,[2,79]),t(H,[2,80]),t(s,[2,35]),t(u,[2,38]),t(u,[2,42]),t(u,[2,43]),t(u,[2,44]),{3:64,4:Q,5:j,6:ie,7:ne,8:le,9:he,10:K,11:X,12:te,13:J,14:se,15:ue,21:63},t(u,[2,53],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,49:[1,77],63:O,64:M,65:B,66:F,67:P}),t(u,[2,56],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,49:[1,78],63:O,64:M,65:B,66:F,67:P}),t(u,[2,57],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:O,64:M,65:B,66:F,67:P}),t(u,[2,58],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:O,64:M,65:B,66:F,67:P}),t(u,[2,59],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:O,64:M,65:B,66:F,67:P}),t(u,[2,60],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:O,64:M,65:B,66:F,67:P}),{45:[1,79]},{44:[1,80]},t(H,[2,65]),t(H,[2,81]),t(H,[2,82]),t(H,[2,83]),{3:82,4:Q,5:j,6:ie,7:ne,8:le,9:he,10:K,11:X,12:te,13:J,14:se,15:ue,18:[1,81]},t(Z,[2,23]),t(Z,[2,1]),t(Z,[2,2]),t(Z,[2,3]),t(Z,[2,4]),t(Z,[2,5]),t(Z,[2,6]),t(Z,[2,7]),t(Z,[2,8]),t(Z,[2,9]),t(Z,[2,10]),t(Z,[2,11]),t(Z,[2,12]),t(u,[2,52],{58:31,43:83,4:f,5:d,10:p,12:m,13:g,14:y,60:L,61:R,63:O,64:M,65:B,66:F,67:P}),t(u,[2,55],{58:31,43:84,4:f,5:d,10:p,12:m,13:g,14:y,60:L,61:R,63:O,64:M,65:B,66:F,67:P}),{46:[1,85]},{45:[1,86]},{4:Se,5:ce,6:ae,8:Oe,11:ge,13:ze,16:89,17:He,18:$e,19:Re,20:Ie,22:88,23:87},t(Z,[2,24]),t(u,[2,51],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:O,64:M,65:B,66:F,67:P}),t(u,[2,54],{59:59,58:60,4:f,5:d,8:z,10:p,12:m,13:g,14:y,18:$,63:O,64:M,65:B,66:F,67:P}),t(u,[2,47],{22:88,16:89,23:100,4:Se,5:ce,6:ae,8:Oe,11:ge,13:ze,17:He,18:$e,19:Re,20:Ie}),{46:[1,101]},t(u,[2,29],{10:be}),t(W,[2,27],{16:103,4:Se,5:ce,6:ae,8:Oe,11:ge,13:ze,17:He,18:$e,19:Re,20:Ie}),t(de,[2,25]),t(de,[2,13]),t(de,[2,14]),t(de,[2,15]),t(de,[2,16]),t(de,[2,17]),t(de,[2,18]),t(de,[2,19]),t(de,[2,20]),t(de,[2,21]),t(de,[2,22]),t(u,[2,49],{10:be}),t(u,[2,48],{22:88,16:89,23:104,4:Se,5:ce,6:ae,8:Oe,11:ge,13:ze,17:He,18:$e,19:Re,20:Ie}),{4:Se,5:ce,6:ae,8:Oe,11:ge,13:ze,16:89,17:He,18:$e,19:Re,20:Ie,22:105},t(de,[2,26]),t(u,[2,50],{10:be}),t(W,[2,28],{16:103,4:Se,5:ce,6:ae,8:Oe,11:ge,13:ze,17:He,18:$e,19:Re,20:Ie})],defaultActions:{8:[2,30],9:[2,31]},parseError:o(function(q,pe){if(pe.recoverable)this.trace(q);else{var ve=new Error(q);throw ve.hash=pe,ve}},"parseError"),parse:o(function(q){var pe=this,ve=[0],Pe=[],_e=[null],we=[],Ve=this.table,De="",qe=0,at=0,Rt=0,st=2,Ue=1,ct=we.slice.call(arguments,1),We=Object.create(this.lexer),ot={yy:{}};for(var Yt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Yt)&&(ot.yy[Yt]=this.yy[Yt]);We.setInput(q,ot.yy),ot.yy.lexer=We,ot.yy.parser=this,typeof We.yylloc>"u"&&(We.yylloc={});var bt=We.yylloc;we.push(bt);var Mt=We.options&&We.options.ranges;typeof ot.yy.parseError=="function"?this.parseError=ot.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function xt(Ce){ve.length=ve.length-2*Ce,_e.length=_e.length-Ce,we.length=we.length-Ce}o(xt,"popStack");function ut(){var Ce;return Ce=Pe.pop()||We.lex()||Ue,typeof Ce!="number"&&(Ce instanceof Array&&(Pe=Ce,Ce=Pe.pop()),Ce=pe.symbols_[Ce]||Ce),Ce}o(ut,"lex");for(var Et,ft,yt,nt,dn,Tt,On={},tn,_r,Dr,Pn;;){if(yt=ve[ve.length-1],this.defaultActions[yt]?nt=this.defaultActions[yt]:((Et===null||typeof Et>"u")&&(Et=ut()),nt=Ve[yt]&&Ve[yt][Et]),typeof nt>"u"||!nt.length||!nt[0]){var At="";Pn=[];for(tn in Ve[yt])this.terminals_[tn]&&tn>st&&Pn.push("'"+this.terminals_[tn]+"'");We.showPosition?At="Parse error on line "+(qe+1)+`:
+`+We.showPosition()+`
+Expecting `+Pn.join(", ")+", got '"+(this.terminals_[Et]||Et)+"'":At="Parse error on line "+(qe+1)+": Unexpected "+(Et==Ue?"end of input":"'"+(this.terminals_[Et]||Et)+"'"),this.parseError(At,{text:We.match,token:this.terminals_[Et]||Et,line:We.yylineno,loc:bt,expected:Pn})}if(nt[0]instanceof Array&&nt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+yt+", token: "+Et);switch(nt[0]){case 1:ve.push(Et),_e.push(We.yytext),we.push(We.yylloc),ve.push(nt[1]),Et=null,ft?(Et=ft,ft=null):(at=We.yyleng,De=We.yytext,qe=We.yylineno,bt=We.yylloc,Rt>0&&Rt--);break;case 2:if(_r=this.productions_[nt[1]][1],On.$=_e[_e.length-_r],On._$={first_line:we[we.length-(_r||1)].first_line,last_line:we[we.length-1].last_line,first_column:we[we.length-(_r||1)].first_column,last_column:we[we.length-1].last_column},Mt&&(On._$.range=[we[we.length-(_r||1)].range[0],we[we.length-1].range[1]]),Tt=this.performAction.apply(On,[De,at,qe,ot.yy,nt[1],_e,we].concat(ct)),typeof Tt<"u")return Tt;_r&&(ve=ve.slice(0,-1*_r*2),_e=_e.slice(0,-1*_r),we=we.slice(0,-1*_r)),ve.push(this.productions_[nt[1]][0]),_e.push(On.$),we.push(On._$),Dr=Ve[ve[ve.length-2]][ve[ve.length-1]],ve.push(Dr);break;case 3:return!0}}return!0},"parse")},oe=function(){var xe={EOF:1,parseError:o(function(pe,ve){if(this.yy.parser)this.yy.parser.parseError(pe,ve);else throw new Error(pe)},"parseError"),setInput:o(function(q,pe){return this.yy=pe||this.yy||{},this._input=q,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var q=this._input[0];this.yytext+=q,this.yyleng++,this.offset++,this.match+=q,this.matched+=q;var pe=q.match(/(?:\r\n?|\n).*/g);return pe?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),q},"input"),unput:o(function(q){var pe=q.length,ve=q.split(/(?:\r\n?|\n)/g);this._input=q+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-pe),this.offset-=pe;var Pe=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),ve.length-1&&(this.yylineno-=ve.length-1);var _e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:ve?(ve.length===Pe.length?this.yylloc.first_column:0)+Pe[Pe.length-ve.length].length-ve[0].length:this.yylloc.first_column-pe},this.options.ranges&&(this.yylloc.range=[_e[0],_e[0]+this.yyleng-pe]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(q){this.unput(this.match.slice(q))},"less"),pastInput:o(function(){var q=this.matched.substr(0,this.matched.length-this.match.length);return(q.length>20?"...":"")+q.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var q=this.match;return q.length<20&&(q+=this._input.substr(0,20-q.length)),(q.substr(0,20)+(q.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var q=this.pastInput(),pe=new Array(q.length+1).join("-");return q+this.upcomingInput()+`
+`+pe+"^"},"showPosition"),test_match:o(function(q,pe){var ve,Pe,_e;if(this.options.backtrack_lexer&&(_e={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(_e.yylloc.range=this.yylloc.range.slice(0))),Pe=q[0].match(/(?:\r\n?|\n).*/g),Pe&&(this.yylineno+=Pe.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:Pe?Pe[Pe.length-1].length-Pe[Pe.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+q[0].length},this.yytext+=q[0],this.match+=q[0],this.matches=q,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(q[0].length),this.matched+=q[0],ve=this.performAction.call(this,this.yy,this,pe,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),ve)return ve;if(this._backtrack){for(var we in _e)this[we]=_e[we];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var q,pe,ve,Pe;this._more||(this.yytext="",this.match="");for(var _e=this._currentRules(),we=0;we<_e.length;we++)if(ve=this._input.match(this.rules[_e[we]]),ve&&(!pe||ve[0].length>pe[0].length)){if(pe=ve,Pe=we,this.options.backtrack_lexer){if(q=this.test_match(ve,_e[we]),q!==!1)return q;if(this._backtrack){pe=!1;continue}else return!1}else if(!this.options.flex)break}return pe?(q=this.test_match(pe,_e[Pe]),q!==!1?q:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var pe=this.next();return pe||this.lex()},"lex"),begin:o(function(pe){this.conditionStack.push(pe)},"begin"),popState:o(function(){var pe=this.conditionStack.length-1;return pe>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(pe){return pe=this.conditionStack.length-1-Math.abs(pe||0),pe>=0?this.conditionStack[pe]:"INITIAL"},"topState"),pushState:o(function(pe){this.begin(pe)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(pe,ve,Pe,_e){var we=_e;switch(Pe){case 0:break;case 1:break;case 2:return 55;case 3:break;case 4:return this.begin("title"),35;break;case 5:return this.popState(),"title_value";break;case 6:return this.begin("acc_title"),37;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),39;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 48;case 14:return 50;case 15:return 49;case 16:return 51;case 17:return 52;case 18:return 53;case 19:return 54;case 20:return 25;case 21:this.begin("md_string");break;case 22:return"MD_STR";case 23:this.popState();break;case 24:this.begin("string");break;case 25:this.popState();break;case 26:return"STR";case 27:this.begin("class_name");break;case 28:return this.popState(),47;break;case 29:return this.begin("point_start"),44;break;case 30:return this.begin("point_x"),45;break;case 31:this.popState();break;case 32:this.popState(),this.begin("point_y");break;case 33:return this.popState(),46;break;case 34:return 28;case 35:return 4;case 36:return 11;case 37:return 64;case 38:return 10;case 39:return 65;case 40:return 65;case 41:return 14;case 42:return 13;case 43:return 67;case 44:return 66;case 45:return 12;case 46:return 8;case 47:return 5;case 48:return 18;case 49:return 56;case 50:return 63;case 51:return 57}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:classDef\b)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?::::)/i,/^(?:^\w+)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{class_name:{rules:[28],inclusive:!1},point_y:{rules:[33],inclusive:!1},point_x:{rules:[32],inclusive:!1},point_start:{rules:[30,31],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[22,23],inclusive:!1},string:{rules:[25,26],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,21,24,27,29,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],inclusive:!0}}};return xe}();re.lexer=oe;function V(){this.yy={}}return o(V,"Parser"),V.prototype=re,re.Parser=V,new V}();hO.parser=hO;uhe=hO});var ms,y6,fhe=N(()=>{"use strict";dr();Ya();vt();_y();ms=oh(),y6=class{constructor(){this.classes=new Map;this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}static{o(this,"QuadrantBuilder")}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:or.quadrantChart?.chartWidth||500,chartWidth:or.quadrantChart?.chartHeight||500,titlePadding:or.quadrantChart?.titlePadding||10,titleFontSize:or.quadrantChart?.titleFontSize||20,quadrantPadding:or.quadrantChart?.quadrantPadding||5,xAxisLabelPadding:or.quadrantChart?.xAxisLabelPadding||5,yAxisLabelPadding:or.quadrantChart?.yAxisLabelPadding||5,xAxisLabelFontSize:or.quadrantChart?.xAxisLabelFontSize||16,yAxisLabelFontSize:or.quadrantChart?.yAxisLabelFontSize||16,quadrantLabelFontSize:or.quadrantChart?.quadrantLabelFontSize||16,quadrantTextTopPadding:or.quadrantChart?.quadrantTextTopPadding||5,pointTextPadding:or.quadrantChart?.pointTextPadding||5,pointLabelFontSize:or.quadrantChart?.pointLabelFontSize||12,pointRadius:or.quadrantChart?.pointRadius||5,xAxisPosition:or.quadrantChart?.xAxisPosition||"top",yAxisPosition:or.quadrantChart?.yAxisPosition||"left",quadrantInternalBorderStrokeWidth:or.quadrantChart?.quadrantInternalBorderStrokeWidth||1,quadrantExternalBorderStrokeWidth:or.quadrantChart?.quadrantExternalBorderStrokeWidth||2}}getDefaultThemeConfig(){return{quadrant1Fill:ms.quadrant1Fill,quadrant2Fill:ms.quadrant2Fill,quadrant3Fill:ms.quadrant3Fill,quadrant4Fill:ms.quadrant4Fill,quadrant1TextFill:ms.quadrant1TextFill,quadrant2TextFill:ms.quadrant2TextFill,quadrant3TextFill:ms.quadrant3TextFill,quadrant4TextFill:ms.quadrant4TextFill,quadrantPointFill:ms.quadrantPointFill,quadrantPointTextFill:ms.quadrantPointTextFill,quadrantXAxisTextFill:ms.quadrantXAxisTextFill,quadrantYAxisTextFill:ms.quadrantYAxisTextFill,quadrantTitleFill:ms.quadrantTitleFill,quadrantInternalBorderStrokeFill:ms.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:ms.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),this.classes=new Map,Y.info("clear called")}setData(e){this.data={...this.data,...e}}addPoints(e){this.data.points=[...e,...this.data.points]}addClass(e,r){this.classes.set(e,r)}setConfig(e){Y.trace("setConfig called with: ",e),this.config={...this.config,...e}}setThemeConfig(e){Y.trace("setThemeConfig called with: ",e),this.themeConfig={...this.themeConfig,...e}}calculateSpace(e,r,n,i){let a=this.config.xAxisLabelPadding*2+this.config.xAxisLabelFontSize,s={top:e==="top"&&r?a:0,bottom:e==="bottom"&&r?a:0},l=this.config.yAxisLabelPadding*2+this.config.yAxisLabelFontSize,u={left:this.config.yAxisPosition==="left"&&n?l:0,right:this.config.yAxisPosition==="right"&&n?l:0},h=this.config.titleFontSize+this.config.titlePadding*2,f={top:i?h:0},d=this.config.quadrantPadding+u.left,p=this.config.quadrantPadding+s.top+f.top,m=this.config.chartWidth-this.config.quadrantPadding*2-u.left-u.right,g=this.config.chartHeight-this.config.quadrantPadding*2-s.top-s.bottom-f.top,y=m/2,v=g/2;return{xAxisSpace:s,yAxisSpace:u,titleSpace:f,quadrantSpace:{quadrantLeft:d,quadrantTop:p,quadrantWidth:m,quadrantHalfWidth:y,quadrantHeight:g,quadrantHalfHeight:v}}}getAxisLabels(e,r,n,i){let{quadrantSpace:a,titleSpace:s}=i,{quadrantHalfHeight:l,quadrantHeight:u,quadrantLeft:h,quadrantHalfWidth:f,quadrantTop:d,quadrantWidth:p}=a,m=!!this.data.xAxisRightText,g=!!this.data.yAxisTopText,y=[];return this.data.xAxisLeftText&&r&&y.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:h+(m?f/2:0),y:e==="top"?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+d+u+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:m?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&r&&y.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:h+f+(m?f/2:0),y:e==="top"?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+d+u+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:m?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&n&&y.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+h+p+this.config.quadrantPadding,y:d+u-(g?l/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:g?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&n&&y.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:this.config.yAxisPosition==="left"?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+h+p+this.config.quadrantPadding,y:d+l-(g?l/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:g?"center":"left",horizontalPos:"top",rotation:-90}),y}getQuadrants(e){let{quadrantSpace:r}=e,{quadrantHalfHeight:n,quadrantLeft:i,quadrantHalfWidth:a,quadrantTop:s}=r,l=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i+a,y:s,width:a,height:n,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i,y:s,width:a,height:n,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i,y:s+n,width:a,height:n,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:i+a,y:s+n,width:a,height:n,fill:this.themeConfig.quadrant4Fill}];for(let u of l)u.text.x=u.x+u.width/2,this.data.points.length===0?(u.text.y=u.y+u.height/2,u.text.horizontalPos="middle"):(u.text.y=u.y+this.config.quadrantTextTopPadding,u.text.horizontalPos="top");return l}getQuadrantPoints(e){let{quadrantSpace:r}=e,{quadrantHeight:n,quadrantLeft:i,quadrantTop:a,quadrantWidth:s}=r,l=gl().domain([0,1]).range([i,s+i]),u=gl().domain([0,1]).range([n+a,a]);return this.data.points.map(f=>{let d=this.classes.get(f.className);return d&&(f={...d,...f}),{x:l(f.x),y:u(f.y),fill:f.color??this.themeConfig.quadrantPointFill,radius:f.radius??this.config.pointRadius,text:{text:f.text,fill:this.themeConfig.quadrantPointTextFill,x:l(f.x),y:u(f.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0},strokeColor:f.strokeColor??this.themeConfig.quadrantPointFill,strokeWidth:f.strokeWidth??"0px"}})}getBorders(e){let r=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:n}=e,{quadrantHalfHeight:i,quadrantHeight:a,quadrantLeft:s,quadrantHalfWidth:l,quadrantTop:u,quadrantWidth:h}=n;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-r,y1:u,x2:s+h+r,y2:u},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s+h,y1:u+r,x2:s+h,y2:u+a-r},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-r,y1:u+a,x2:s+h+r,y2:u+a},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s,y1:u+r,x2:s,y2:u+a-r},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+l,y1:u+r,x2:s+l,y2:u+a-r},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+r,y1:u+i,x2:s+h-r,y2:u+i}]}getTitle(e){if(e)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){let e=this.config.showXAxis&&!!(this.data.xAxisLeftText||this.data.xAxisRightText),r=this.config.showYAxis&&!!(this.data.yAxisTopText||this.data.yAxisBottomText),n=this.config.showTitle&&!!this.data.titleText,i=this.data.points.length>0?"bottom":this.config.xAxisPosition,a=this.calculateSpace(i,e,r,n);return{points:this.getQuadrantPoints(a),quadrants:this.getQuadrants(a),axisLabels:this.getAxisLabels(i,e,r,a),borderLines:this.getBorders(a),title:this.getTitle(n)}}}});function fO(t){return!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(t)}function dhe(t){return!/^\d+$/.test(t)}function phe(t){return!/^\d+px$/.test(t)}var Ap,mhe=N(()=>{"use strict";Ap=class extends Error{static{o(this,"InvalidStyleError")}constructor(e,r,n){super(`value for ${e} ${r} is invalid, please use a valid ${n}`),this.name="InvalidStyleError"}};o(fO,"validateHexCode");o(dhe,"validateNumber");o(phe,"validateSizeInPixels")});function Xu(t){return Tr(t.trim(),pGe)}function mGe(t){ba.setData({quadrant1Text:Xu(t.text)})}function gGe(t){ba.setData({quadrant2Text:Xu(t.text)})}function yGe(t){ba.setData({quadrant3Text:Xu(t.text)})}function vGe(t){ba.setData({quadrant4Text:Xu(t.text)})}function xGe(t){ba.setData({xAxisLeftText:Xu(t.text)})}function bGe(t){ba.setData({xAxisRightText:Xu(t.text)})}function wGe(t){ba.setData({yAxisTopText:Xu(t.text)})}function TGe(t){ba.setData({yAxisBottomText:Xu(t.text)})}function dO(t){let e={};for(let r of t){let[n,i]=r.trim().split(/\s*:\s*/);if(n==="radius"){if(dhe(i))throw new Ap(n,i,"number");e.radius=parseInt(i)}else if(n==="color"){if(fO(i))throw new Ap(n,i,"hex code");e.color=i}else if(n==="stroke-color"){if(fO(i))throw new Ap(n,i,"hex code");e.strokeColor=i}else if(n==="stroke-width"){if(phe(i))throw new Ap(n,i,"number of pixels (eg. 10px)");e.strokeWidth=i}else throw new Error(`style named ${n} is not supported.`)}return e}function kGe(t,e,r,n,i){let a=dO(i);ba.addPoints([{x:r,y:n,text:Xu(t.text),className:e,...a}])}function EGe(t,e){ba.addClass(t,dO(e))}function SGe(t){ba.setConfig({chartWidth:t})}function CGe(t){ba.setConfig({chartHeight:t})}function AGe(){let t=me(),{themeVariables:e,quadrantChart:r}=t;return r&&ba.setConfig(r),ba.setThemeConfig({quadrant1Fill:e.quadrant1Fill,quadrant2Fill:e.quadrant2Fill,quadrant3Fill:e.quadrant3Fill,quadrant4Fill:e.quadrant4Fill,quadrant1TextFill:e.quadrant1TextFill,quadrant2TextFill:e.quadrant2TextFill,quadrant3TextFill:e.quadrant3TextFill,quadrant4TextFill:e.quadrant4TextFill,quadrantPointFill:e.quadrantPointFill,quadrantPointTextFill:e.quadrantPointTextFill,quadrantXAxisTextFill:e.quadrantXAxisTextFill,quadrantYAxisTextFill:e.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:e.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:e.quadrantInternalBorderStrokeFill,quadrantTitleFill:e.quadrantTitleFill}),ba.setData({titleText:Ir()}),ba.build()}var pGe,ba,_Ge,ghe,yhe=N(()=>{"use strict";zt();gr();mi();fhe();mhe();pGe=me();o(Xu,"textSanitizer");ba=new y6;o(mGe,"setQuadrant1Text");o(gGe,"setQuadrant2Text");o(yGe,"setQuadrant3Text");o(vGe,"setQuadrant4Text");o(xGe,"setXAxisLeftText");o(bGe,"setXAxisRightText");o(wGe,"setYAxisTopText");o(TGe,"setYAxisBottomText");o(dO,"parseStyles");o(kGe,"addPoint");o(EGe,"addClass");o(SGe,"setWidth");o(CGe,"setHeight");o(AGe,"getQuadrantData");_Ge=o(function(){ba.clear(),Ar()},"clear"),ghe={setWidth:SGe,setHeight:CGe,setQuadrant1Text:mGe,setQuadrant2Text:gGe,setQuadrant3Text:yGe,setQuadrant4Text:vGe,setXAxisLeftText:xGe,setXAxisRightText:bGe,setYAxisTopText:wGe,setYAxisBottomText:TGe,parseStyles:dO,addPoint:kGe,addClass:EGe,getQuadrantData:AGe,clear:_Ge,setAccTitle:Lr,getAccTitle:Rr,setDiagramTitle:$r,getDiagramTitle:Ir,getAccDescription:Mr,setAccDescription:Nr}});var DGe,vhe,xhe=N(()=>{"use strict";dr();zt();vt();Ei();DGe=o((t,e,r,n)=>{function i(S){return S==="top"?"hanging":"middle"}o(i,"getDominantBaseLine");function a(S){return S==="left"?"start":"middle"}o(a,"getTextAnchor");function s(S){return`translate(${S.x}, ${S.y}) rotate(${S.rotation||0})`}o(s,"getTransformation");let l=me();Y.debug(`Rendering quadrant chart
+`+t);let u=l.securityLevel,h;u==="sandbox"&&(h=Ge("#i"+e));let d=(u==="sandbox"?Ge(h.nodes()[0].contentDocument.body):Ge("body")).select(`[id="${e}"]`),p=d.append("g").attr("class","main"),m=l.quadrantChart?.chartWidth??500,g=l.quadrantChart?.chartHeight??500;vn(d,g,m,l.quadrantChart?.useMaxWidth??!0),d.attr("viewBox","0 0 "+m+" "+g),n.db.setHeight(g),n.db.setWidth(m);let y=n.db.getQuadrantData(),v=p.append("g").attr("class","quadrants"),x=p.append("g").attr("class","border"),b=p.append("g").attr("class","data-points"),w=p.append("g").attr("class","labels"),C=p.append("g").attr("class","title");y.title&&C.append("text").attr("x",0).attr("y",0).attr("fill",y.title.fill).attr("font-size",y.title.fontSize).attr("dominant-baseline",i(y.title.horizontalPos)).attr("text-anchor",a(y.title.verticalPos)).attr("transform",s(y.title)).text(y.title.text),y.borderLines&&x.selectAll("line").data(y.borderLines).enter().append("line").attr("x1",S=>S.x1).attr("y1",S=>S.y1).attr("x2",S=>S.x2).attr("y2",S=>S.y2).style("stroke",S=>S.strokeFill).style("stroke-width",S=>S.strokeWidth);let T=v.selectAll("g.quadrant").data(y.quadrants).enter().append("g").attr("class","quadrant");T.append("rect").attr("x",S=>S.x).attr("y",S=>S.y).attr("width",S=>S.width).attr("height",S=>S.height).attr("fill",S=>S.fill),T.append("text").attr("x",0).attr("y",0).attr("fill",S=>S.text.fill).attr("font-size",S=>S.text.fontSize).attr("dominant-baseline",S=>i(S.text.horizontalPos)).attr("text-anchor",S=>a(S.text.verticalPos)).attr("transform",S=>s(S.text)).text(S=>S.text.text),w.selectAll("g.label").data(y.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text(S=>S.text).attr("fill",S=>S.fill).attr("font-size",S=>S.fontSize).attr("dominant-baseline",S=>i(S.horizontalPos)).attr("text-anchor",S=>a(S.verticalPos)).attr("transform",S=>s(S));let A=b.selectAll("g.data-point").data(y.points).enter().append("g").attr("class","data-point");A.append("circle").attr("cx",S=>S.x).attr("cy",S=>S.y).attr("r",S=>S.radius).attr("fill",S=>S.fill).attr("stroke",S=>S.strokeColor).attr("stroke-width",S=>S.strokeWidth),A.append("text").attr("x",0).attr("y",0).text(S=>S.text.text).attr("fill",S=>S.text.fill).attr("font-size",S=>S.text.fontSize).attr("dominant-baseline",S=>i(S.text.horizontalPos)).attr("text-anchor",S=>a(S.text.verticalPos)).attr("transform",S=>s(S.text))},"draw"),vhe={draw:DGe}});var bhe={};hr(bhe,{diagram:()=>LGe});var LGe,whe=N(()=>{"use strict";hhe();yhe();xhe();LGe={parser:uhe,db:ghe,renderer:vhe,styles:o(()=>"","styles")}});var pO,Ehe,She=N(()=>{"use strict";pO=function(){var t=o(function(O,M,B,F){for(B=B||{},F=O.length;F--;B[O[F]]=M);return B},"o"),e=[1,10,12,14,16,18,19,21,23],r=[2,6],n=[1,3],i=[1,5],a=[1,6],s=[1,7],l=[1,5,10,12,14,16,18,19,21,23,34,35,36],u=[1,25],h=[1,26],f=[1,28],d=[1,29],p=[1,30],m=[1,31],g=[1,32],y=[1,33],v=[1,34],x=[1,35],b=[1,36],w=[1,37],C=[1,43],T=[1,42],E=[1,47],A=[1,50],S=[1,10,12,14,16,18,19,21,23,34,35,36],_=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],I=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],D=[1,64],k={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:o(function(M,B,F,P,z,$,H){var Q=$.length-1;switch(z){case 5:P.setOrientation($[Q]);break;case 9:P.setDiagramTitle($[Q].text.trim());break;case 12:P.setLineData({text:"",type:"text"},$[Q]);break;case 13:P.setLineData($[Q-1],$[Q]);break;case 14:P.setBarData({text:"",type:"text"},$[Q]);break;case 15:P.setBarData($[Q-1],$[Q]);break;case 16:this.$=$[Q].trim(),P.setAccTitle(this.$);break;case 17:case 18:this.$=$[Q].trim(),P.setAccDescription(this.$);break;case 19:this.$=$[Q-1];break;case 20:this.$=[Number($[Q-2]),...$[Q]];break;case 21:this.$=[Number($[Q])];break;case 22:P.setXAxisTitle($[Q]);break;case 23:P.setXAxisTitle($[Q-1]);break;case 24:P.setXAxisTitle({type:"text",text:""});break;case 25:P.setXAxisBand($[Q]);break;case 26:P.setXAxisRangeData(Number($[Q-2]),Number($[Q]));break;case 27:this.$=$[Q-1];break;case 28:this.$=[$[Q-2],...$[Q]];break;case 29:this.$=[$[Q]];break;case 30:P.setYAxisTitle($[Q]);break;case 31:P.setYAxisTitle($[Q-1]);break;case 32:P.setYAxisTitle({type:"text",text:""});break;case 33:P.setYAxisRangeData(Number($[Q-2]),Number($[Q]));break;case 37:this.$={text:$[Q],type:"text"};break;case 38:this.$={text:$[Q],type:"text"};break;case 39:this.$={text:$[Q],type:"markdown"};break;case 40:this.$=$[Q];break;case 41:this.$=$[Q-1]+""+$[Q];break}},"anonymous"),table:[t(e,r,{3:1,4:2,7:4,5:n,34:i,35:a,36:s}),{1:[3]},t(e,r,{4:2,7:4,3:8,5:n,34:i,35:a,36:s}),t(e,r,{4:2,7:4,6:9,3:10,5:n,8:[1,11],34:i,35:a,36:s}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(l,[2,34]),t(l,[2,35]),t(l,[2,36]),{1:[2,1]},t(e,r,{4:2,7:4,3:21,5:n,34:i,35:a,36:s}),{1:[2,3]},t(l,[2,5]),t(e,[2,7],{4:22,34:i,35:a,36:s}),{11:23,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},{11:39,13:38,24:C,27:T,29:40,30:41,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},{11:45,15:44,27:E,33:46,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},{11:49,17:48,24:A,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},{11:52,17:51,24:A,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},{20:[1,53]},{22:[1,54]},t(S,[2,18]),{1:[2,2]},t(S,[2,8]),t(S,[2,9]),t(_,[2,37],{40:55,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w}),t(_,[2,38]),t(_,[2,39]),t(I,[2,40]),t(I,[2,42]),t(I,[2,43]),t(I,[2,44]),t(I,[2,45]),t(I,[2,46]),t(I,[2,47]),t(I,[2,48]),t(I,[2,49]),t(I,[2,50]),t(I,[2,51]),t(S,[2,10]),t(S,[2,22],{30:41,29:56,24:C,27:T}),t(S,[2,24]),t(S,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},t(S,[2,11]),t(S,[2,30],{33:60,27:E}),t(S,[2,32]),{31:[1,61]},t(S,[2,12]),{17:62,24:A},{25:63,27:D},t(S,[2,14]),{17:65,24:A},t(S,[2,16]),t(S,[2,17]),t(I,[2,41]),t(S,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(S,[2,31]),{27:[1,69]},t(S,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(S,[2,15]),t(S,[2,26]),t(S,[2,27]),{11:59,32:72,37:24,38:u,39:h,40:27,41:f,42:d,43:p,44:m,45:g,46:y,47:v,48:x,49:b,50:w},t(S,[2,33]),t(S,[2,19]),{25:73,27:D},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:o(function(M,B){if(B.recoverable)this.trace(M);else{var F=new Error(M);throw F.hash=B,F}},"parseError"),parse:o(function(M){var B=this,F=[0],P=[],z=[null],$=[],H=this.table,Q="",j=0,ie=0,ne=0,le=2,he=1,K=$.slice.call(arguments,1),X=Object.create(this.lexer),te={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(te.yy[J]=this.yy[J]);X.setInput(M,te.yy),te.yy.lexer=X,te.yy.parser=this,typeof X.yylloc>"u"&&(X.yylloc={});var se=X.yylloc;$.push(se);var ue=X.options&&X.options.ranges;typeof te.yy.parseError=="function"?this.parseError=te.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Z(re){F.length=F.length-2*re,z.length=z.length-re,$.length=$.length-re}o(Z,"popStack");function Se(){var re;return re=P.pop()||X.lex()||he,typeof re!="number"&&(re instanceof Array&&(P=re,re=P.pop()),re=B.symbols_[re]||re),re}o(Se,"lex");for(var ce,ae,Oe,ge,ze,He,$e={},Re,Ie,be,W;;){if(Oe=F[F.length-1],this.defaultActions[Oe]?ge=this.defaultActions[Oe]:((ce===null||typeof ce>"u")&&(ce=Se()),ge=H[Oe]&&H[Oe][ce]),typeof ge>"u"||!ge.length||!ge[0]){var de="";W=[];for(Re in H[Oe])this.terminals_[Re]&&Re>le&&W.push("'"+this.terminals_[Re]+"'");X.showPosition?de="Parse error on line "+(j+1)+`:
+`+X.showPosition()+`
+Expecting `+W.join(", ")+", got '"+(this.terminals_[ce]||ce)+"'":de="Parse error on line "+(j+1)+": Unexpected "+(ce==he?"end of input":"'"+(this.terminals_[ce]||ce)+"'"),this.parseError(de,{text:X.match,token:this.terminals_[ce]||ce,line:X.yylineno,loc:se,expected:W})}if(ge[0]instanceof Array&&ge.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Oe+", token: "+ce);switch(ge[0]){case 1:F.push(ce),z.push(X.yytext),$.push(X.yylloc),F.push(ge[1]),ce=null,ae?(ce=ae,ae=null):(ie=X.yyleng,Q=X.yytext,j=X.yylineno,se=X.yylloc,ne>0&&ne--);break;case 2:if(Ie=this.productions_[ge[1]][1],$e.$=z[z.length-Ie],$e._$={first_line:$[$.length-(Ie||1)].first_line,last_line:$[$.length-1].last_line,first_column:$[$.length-(Ie||1)].first_column,last_column:$[$.length-1].last_column},ue&&($e._$.range=[$[$.length-(Ie||1)].range[0],$[$.length-1].range[1]]),He=this.performAction.apply($e,[Q,ie,j,te.yy,ge[1],z,$].concat(K)),typeof He<"u")return He;Ie&&(F=F.slice(0,-1*Ie*2),z=z.slice(0,-1*Ie),$=$.slice(0,-1*Ie)),F.push(this.productions_[ge[1]][0]),z.push($e.$),$.push($e._$),be=H[F[F.length-2]][F[F.length-1]],F.push(be);break;case 3:return!0}}return!0},"parse")},L=function(){var O={EOF:1,parseError:o(function(B,F){if(this.yy.parser)this.yy.parser.parseError(B,F);else throw new Error(B)},"parseError"),setInput:o(function(M,B){return this.yy=B||this.yy||{},this._input=M,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var M=this._input[0];this.yytext+=M,this.yyleng++,this.offset++,this.match+=M,this.matched+=M;var B=M.match(/(?:\r\n?|\n).*/g);return B?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),M},"input"),unput:o(function(M){var B=M.length,F=M.split(/(?:\r\n?|\n)/g);this._input=M+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-B),this.offset-=B;var P=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),F.length-1&&(this.yylineno-=F.length-1);var z=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:F?(F.length===P.length?this.yylloc.first_column:0)+P[P.length-F.length].length-F[0].length:this.yylloc.first_column-B},this.options.ranges&&(this.yylloc.range=[z[0],z[0]+this.yyleng-B]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(M){this.unput(this.match.slice(M))},"less"),pastInput:o(function(){var M=this.matched.substr(0,this.matched.length-this.match.length);return(M.length>20?"...":"")+M.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var M=this.match;return M.length<20&&(M+=this._input.substr(0,20-M.length)),(M.substr(0,20)+(M.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var M=this.pastInput(),B=new Array(M.length+1).join("-");return M+this.upcomingInput()+`
+`+B+"^"},"showPosition"),test_match:o(function(M,B){var F,P,z;if(this.options.backtrack_lexer&&(z={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(z.yylloc.range=this.yylloc.range.slice(0))),P=M[0].match(/(?:\r\n?|\n).*/g),P&&(this.yylineno+=P.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:P?P[P.length-1].length-P[P.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+M[0].length},this.yytext+=M[0],this.match+=M[0],this.matches=M,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(M[0].length),this.matched+=M[0],F=this.performAction.call(this,this.yy,this,B,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),F)return F;if(this._backtrack){for(var $ in z)this[$]=z[$];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var M,B,F,P;this._more||(this.yytext="",this.match="");for(var z=this._currentRules(),$=0;$<z.length;$++)if(F=this._input.match(this.rules[z[$]]),F&&(!B||F[0].length>B[0].length)){if(B=F,P=$,this.options.backtrack_lexer){if(M=this.test_match(F,z[$]),M!==!1)return M;if(this._backtrack){B=!1;continue}else return!1}else if(!this.options.flex)break}return B?(M=this.test_match(B,z[P]),M!==!1?M:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var B=this.next();return B||this.lex()},"lex"),begin:o(function(B){this.conditionStack.push(B)},"begin"),popState:o(function(){var B=this.conditionStack.length-1;return B>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(B){return B=this.conditionStack.length-1-Math.abs(B||0),B>=0?this.conditionStack[B]:"INITIAL"},"topState"),pushState:o(function(B){this.begin(B)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(B,F,P,z){var $=z;switch(P){case 0:break;case 1:break;case 2:return this.popState(),34;break;case 3:return this.popState(),34;break;case 4:return 34;case 5:break;case 6:return 10;case 7:return this.pushState("acc_title"),19;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.pushState("acc_descr"),21;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.pushState("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";break;case 17:return this.pushState("axis_data"),"Y_AXIS";break;case 18:return this.pushState("axis_band_data"),24;break;case 19:return 31;case 20:return this.pushState("data"),16;break;case 21:return this.pushState("data"),18;break;case 22:return this.pushState("data_inner"),24;break;case 23:return 27;case 24:return this.popState(),26;break;case 25:this.popState();break;case 26:this.pushState("string");break;case 27:this.popState();break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 43:break;case 44:return 35;case 45:return 36}},"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}};return O}();k.lexer=L;function R(){this.yy={}}return o(R,"Parser"),R.prototype=k,k.Parser=R,new R}();pO.parser=pO;Ehe=pO});function mO(t){return t.type==="bar"}function v6(t){return t.type==="band"}function S1(t){return t.type==="linear"}var x6=N(()=>{"use strict";o(mO,"isBarPlot");o(v6,"isBandAxisData");o(S1,"isLinearAxisData")});var C1,gO=N(()=>{"use strict";to();C1=class{constructor(e){this.parentGroup=e}static{o(this,"TextDimensionCalculatorWithFont")}getMaxDimension(e,r){if(!this.parentGroup)return{width:e.reduce((a,s)=>Math.max(s.length,a),0)*r,height:r};let n={width:0,height:0},i=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",r);for(let a of e){let s=sK(i,1,a),l=s?s.width:a.length*r,u=s?s.height:r;n.width=Math.max(n.width,l),n.height=Math.max(n.height,u)}return i.remove(),n}}});var A1,yO=N(()=>{"use strict";A1=class{constructor(e,r,n,i){this.axisConfig=e;this.title=r;this.textDimensionCalculator=n;this.axisThemeConfig=i;this.boundingRect={x:0,y:0,width:0,height:0};this.axisPosition="left";this.showTitle=!1;this.showLabel=!1;this.showTick=!1;this.showAxisLine=!1;this.outerPadding=0;this.titleTextHeight=0;this.labelTextHeight=0;this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}static{o(this,"BaseAxis")}setRange(e){this.range=e,this.axisPosition==="left"||this.axisPosition==="right"?this.boundingRect.height=e[1]-e[0]:this.boundingRect.width=e[1]-e[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(e){this.axisPosition=e,this.setRange(this.range)}getTickDistance(){let e=this.getRange();return Math.abs(e[0]-e[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map(e=>e.toString()),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>this.outerPadding*2&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(e){let r=e.height;if(this.axisConfig.showAxisLine&&r>this.axisConfig.axisLineWidth&&(r-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){let n=this.getLabelDimension(),i=.2*e.width;this.outerPadding=Math.min(n.width/2,i);let a=n.height+this.axisConfig.labelPadding*2;this.labelTextHeight=n.height,a<=r&&(r-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&r>=this.axisConfig.tickLength&&(this.showTick=!0,r-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){let n=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),i=n.height+this.axisConfig.titlePadding*2;this.titleTextHeight=n.height,i<=r&&(r-=i,this.showTitle=!0)}this.boundingRect.width=e.width,this.boundingRect.height=e.height-r}calculateSpaceIfDrawnVertical(e){let r=e.width;if(this.axisConfig.showAxisLine&&r>this.axisConfig.axisLineWidth&&(r-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){let n=this.getLabelDimension(),i=.2*e.height;this.outerPadding=Math.min(n.height/2,i);let a=n.width+this.axisConfig.labelPadding*2;a<=r&&(r-=a,this.showLabel=!0)}if(this.axisConfig.showTick&&r>=this.axisConfig.tickLength&&(this.showTick=!0,r-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){let n=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),i=n.height+this.axisConfig.titlePadding*2;this.titleTextHeight=n.height,i<=r&&(r-=i,this.showTitle=!0)}this.boundingRect.width=e.width-r,this.boundingRect.height=e.height}calculateSpace(e){return this.axisPosition==="left"||this.axisPosition==="right"?this.calculateSpaceIfDrawnVertical(e):this.calculateSpaceIfDrawnHorizontally(e),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}getDrawableElementsForLeftAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${r},${this.boundingRect.y} L ${r},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(r),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"}))}),this.showTick){let r=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);e.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${r},${this.getScaleValue(n)} L ${r-this.axisConfig.tickLength},${this.getScaleValue(n)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElementsForBottomAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.y+this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${r} L ${this.boundingRect.x+this.boundingRect.width},${r}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.getScaleValue(r),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){let r=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);e.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${this.getScaleValue(n)},${r} L ${this.getScaleValue(n)},${r+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElementsForTopAxis(){let e=[];if(this.showAxisLine){let r=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;e.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${r} L ${this.boundingRect.x+this.boundingRect.width},${r}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&e.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map(r=>({text:r.toString(),x:this.getScaleValue(r),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+this.axisConfig.titlePadding*2:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}))}),this.showTick){let r=this.boundingRect.y;e.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map(n=>({path:`M ${this.getScaleValue(n)},${r+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(n)},${r+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth}))})}return this.showTitle&&e.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),e}getDrawableElements(){if(this.axisPosition==="left")return this.getDrawableElementsForLeftAxis();if(this.axisPosition==="right")throw Error("Drawing of right axis is not implemented");return this.axisPosition==="bottom"?this.getDrawableElementsForBottomAxis():this.axisPosition==="top"?this.getDrawableElementsForTopAxis():[]}}});var b6,Che=N(()=>{"use strict";dr();vt();yO();b6=class extends A1{static{o(this,"BandAxis")}constructor(e,r,n,i,a){super(e,i,a,r),this.categories=n,this.scale=L0().domain(this.categories).range(this.getRange())}setRange(e){super.setRange(e)}recalculateScale(){this.scale=L0().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),Y.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(e){return this.scale(e)??this.getRange()[0]}}});var w6,Ahe=N(()=>{"use strict";dr();yO();w6=class extends A1{static{o(this,"LinearAxis")}constructor(e,r,n,i,a){super(e,i,a,r),this.domain=n,this.scale=gl().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){let e=[...this.domain];this.axisPosition==="left"&&e.reverse(),this.scale=gl().domain(e).range(this.getRange())}getScaleValue(e){return this.scale(e)}}});function vO(t,e,r,n){let i=new C1(n);return v6(t)?new b6(e,r,t.categories,t.title,i):new w6(e,r,[t.min,t.max],t.title,i)}var _he=N(()=>{"use strict";x6();gO();Che();Ahe();o(vO,"getAxis")});function Dhe(t,e,r,n){let i=new C1(n);return new xO(i,t,e,r)}var xO,Lhe=N(()=>{"use strict";gO();xO=class{constructor(e,r,n,i){this.textDimensionCalculator=e;this.chartConfig=r;this.chartData=n;this.chartThemeConfig=i;this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}static{o(this,"ChartTitle")}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}calculateSpace(e){let r=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),n=Math.max(r.width,e.width),i=r.height+2*this.chartConfig.titlePadding;return r.width<=n&&r.height<=i&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=n,this.boundingRect.height=i,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){let e=[];return this.showChartTitle&&e.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),e}};o(Dhe,"getChartTitleComponent")});var T6,Rhe=N(()=>{"use strict";dr();T6=class{constructor(e,r,n,i,a){this.plotData=e;this.xAxis=r;this.yAxis=n;this.orientation=i;this.plotIndex=a}static{o(this,"LinePlot")}getDrawableElement(){let e=this.plotData.data.map(n=>[this.xAxis.getScaleValue(n[0]),this.yAxis.getScaleValue(n[1])]),r;return this.orientation==="horizontal"?r=wl().y(n=>n[0]).x(n=>n[1])(e):r=wl().x(n=>n[0]).y(n=>n[1])(e),r?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:r,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}});var k6,Nhe=N(()=>{"use strict";k6=class{constructor(e,r,n,i,a,s){this.barData=e;this.boundingRect=r;this.xAxis=n;this.yAxis=i;this.orientation=a;this.plotIndex=s}static{o(this,"BarPlot")}getDrawableElement(){let e=this.barData.data.map(a=>[this.xAxis.getScaleValue(a[0]),this.yAxis.getScaleValue(a[1])]),n=Math.min(this.xAxis.getAxisOuterPadding()*2,this.xAxis.getTickDistance())*(1-.05),i=n/2;return this.orientation==="horizontal"?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:e.map(a=>({x:this.boundingRect.x,y:a[0]-i,height:n,width:a[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:e.map(a=>({x:a[0]-i,y:a[1],width:n,height:this.boundingRect.y+this.boundingRect.height-a[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill}))}]}}});function Mhe(t,e,r){return new bO(t,e,r)}var bO,Ihe=N(()=>{"use strict";Rhe();Nhe();bO=class{constructor(e,r,n){this.chartConfig=e;this.chartData=r;this.chartThemeConfig=n;this.boundingRect={x:0,y:0,width:0,height:0}}static{o(this,"BasePlot")}setAxes(e,r){this.xAxis=e,this.yAxis=r}setBoundingBoxXY(e){this.boundingRect.x=e.x,this.boundingRect.y=e.y}calculateSpace(e){return this.boundingRect.width=e.width,this.boundingRect.height=e.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!(this.xAxis&&this.yAxis))throw Error("Axes must be passed to render Plots");let e=[];for(let[r,n]of this.chartData.plots.entries())switch(n.type){case"line":{let i=new T6(n,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,r);e.push(...i.getDrawableElement())}break;case"bar":{let i=new k6(n,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,r);e.push(...i.getDrawableElement())}break}return e}};o(Mhe,"getPlotComponent")});var E6,Ohe=N(()=>{"use strict";_he();Lhe();Ihe();x6();E6=class{constructor(e,r,n,i){this.chartConfig=e;this.chartData=r;this.componentStore={title:Dhe(e,r,n,i),plot:Mhe(e,r,n),xAxis:vO(r.xAxis,e.xAxis,{titleColor:n.xAxisTitleColor,labelColor:n.xAxisLabelColor,tickColor:n.xAxisTickColor,axisLineColor:n.xAxisLineColor},i),yAxis:vO(r.yAxis,e.yAxis,{titleColor:n.yAxisTitleColor,labelColor:n.yAxisLabelColor,tickColor:n.yAxisTickColor,axisLineColor:n.yAxisLineColor},i)}}static{o(this,"Orchestrator")}calculateVerticalSpace(){let e=this.chartConfig.width,r=this.chartConfig.height,n=0,i=0,a=Math.floor(e*this.chartConfig.plotReservedSpacePercent/100),s=Math.floor(r*this.chartConfig.plotReservedSpacePercent/100),l=this.componentStore.plot.calculateSpace({width:a,height:s});e-=l.width,r-=l.height,l=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:r}),i=l.height,r-=l.height,this.componentStore.xAxis.setAxisPosition("bottom"),l=this.componentStore.xAxis.calculateSpace({width:e,height:r}),r-=l.height,this.componentStore.yAxis.setAxisPosition("left"),l=this.componentStore.yAxis.calculateSpace({width:e,height:r}),n=l.width,e-=l.width,e>0&&(a+=e,e=0),r>0&&(s+=r,r=0),this.componentStore.plot.calculateSpace({width:a,height:s}),this.componentStore.plot.setBoundingBoxXY({x:n,y:i}),this.componentStore.xAxis.setRange([n,n+a]),this.componentStore.xAxis.setBoundingBoxXY({x:n,y:i+s}),this.componentStore.yAxis.setRange([i,i+s]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:i}),this.chartData.plots.some(u=>mO(u))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let e=this.chartConfig.width,r=this.chartConfig.height,n=0,i=0,a=0,s=Math.floor(e*this.chartConfig.plotReservedSpacePercent/100),l=Math.floor(r*this.chartConfig.plotReservedSpacePercent/100),u=this.componentStore.plot.calculateSpace({width:s,height:l});e-=u.width,r-=u.height,u=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:r}),n=u.height,r-=u.height,this.componentStore.xAxis.setAxisPosition("left"),u=this.componentStore.xAxis.calculateSpace({width:e,height:r}),e-=u.width,i=u.width,this.componentStore.yAxis.setAxisPosition("top"),u=this.componentStore.yAxis.calculateSpace({width:e,height:r}),r-=u.height,a=n+u.height,e>0&&(s+=e,e=0),r>0&&(l+=r,r=0),this.componentStore.plot.calculateSpace({width:s,height:l}),this.componentStore.plot.setBoundingBoxXY({x:i,y:a}),this.componentStore.yAxis.setRange([i,i+s]),this.componentStore.yAxis.setBoundingBoxXY({x:i,y:n}),this.componentStore.xAxis.setRange([a,a+l]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:a}),this.chartData.plots.some(h=>mO(h))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){this.chartConfig.chartOrientation==="horizontal"?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();let e=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(let r of Object.values(this.componentStore))e.push(...r.getDrawableElements());return e}}});var S6,Phe=N(()=>{"use strict";Ohe();S6=class{static{o(this,"XYChartBuilder")}static build(e,r,n,i){return new E6(e,r,n,i).getDrawableElement()}}});function Fhe(){let t=oh(),e=cr();return Fi(t.xyChart,e.themeVariables.xyChart)}function $he(){let t=cr();return Fi(or.xyChart,t.xyChart)}function zhe(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function kO(t){let e=cr();return Tr(t.trim(),e)}function IGe(t){Bhe=t}function OGe(t){t==="horizontal"?bb.chartOrientation="horizontal":bb.chartOrientation="vertical"}function PGe(t){fn.xAxis.title=kO(t.text)}function Ghe(t,e){fn.xAxis={type:"linear",title:fn.xAxis.title,min:t,max:e},C6=!0}function BGe(t){fn.xAxis={type:"band",title:fn.xAxis.title,categories:t.map(e=>kO(e.text))},C6=!0}function FGe(t){fn.yAxis.title=kO(t.text)}function $Ge(t,e){fn.yAxis={type:"linear",title:fn.yAxis.title,min:t,max:e},TO=!0}function zGe(t){let e=Math.min(...t),r=Math.max(...t),n=S1(fn.yAxis)?fn.yAxis.min:1/0,i=S1(fn.yAxis)?fn.yAxis.max:-1/0;fn.yAxis={type:"linear",title:fn.yAxis.title,min:Math.min(n,e),max:Math.max(i,r)}}function Vhe(t){let e=[];if(t.length===0)return e;if(!C6){let r=S1(fn.xAxis)?fn.xAxis.min:1/0,n=S1(fn.xAxis)?fn.xAxis.max:-1/0;Ghe(Math.min(r,1),Math.max(n,t.length))}if(TO||zGe(t),v6(fn.xAxis)&&(e=fn.xAxis.categories.map((r,n)=>[r,t[n]])),S1(fn.xAxis)){let r=fn.xAxis.min,n=fn.xAxis.max,i=(n-r)/(t.length-1),a=[];for(let s=r;s<=n;s+=i)a.push(`${s}`);e=a.map((s,l)=>[s,t[l]])}return e}function Uhe(t){return wO[t===0?0:t%wO.length]}function GGe(t,e){let r=Vhe(e);fn.plots.push({type:"line",strokeFill:Uhe(xb),strokeWidth:2,data:r}),xb++}function VGe(t,e){let r=Vhe(e);fn.plots.push({type:"bar",fill:Uhe(xb),data:r}),xb++}function UGe(){if(fn.plots.length===0)throw Error("No Plot to render, please provide a plot with some data");return fn.title=Ir(),S6.build(bb,fn,wb,Bhe)}function HGe(){return wb}function WGe(){return bb}var xb,Bhe,bb,wb,fn,wO,C6,TO,qGe,Hhe,Whe=N(()=>{"use strict";ji();Ya();_y();ir();gr();mi();Phe();x6();xb=0,bb=$he(),wb=Fhe(),fn=zhe(),wO=wb.plotColorPalette.split(",").map(t=>t.trim()),C6=!1,TO=!1;o(Fhe,"getChartDefaultThemeConfig");o($he,"getChartDefaultConfig");o(zhe,"getChartDefaultData");o(kO,"textSanitizer");o(IGe,"setTmpSVGG");o(OGe,"setOrientation");o(PGe,"setXAxisTitle");o(Ghe,"setXAxisRangeData");o(BGe,"setXAxisBand");o(FGe,"setYAxisTitle");o($Ge,"setYAxisRangeData");o(zGe,"setYAxisRangeFromPlotData");o(Vhe,"transformDataWithoutCategory");o(Uhe,"getPlotColorFromPalette");o(GGe,"setLineData");o(VGe,"setBarData");o(UGe,"getDrawableElem");o(HGe,"getChartThemeConfig");o(WGe,"getChartConfig");qGe=o(function(){Ar(),xb=0,bb=$he(),fn=zhe(),wb=Fhe(),wO=wb.plotColorPalette.split(",").map(t=>t.trim()),C6=!1,TO=!1},"clear"),Hhe={getDrawableElem:UGe,clear:qGe,setAccTitle:Lr,getAccTitle:Rr,setDiagramTitle:$r,getDiagramTitle:Ir,getAccDescription:Mr,setAccDescription:Nr,setOrientation:OGe,setXAxisTitle:PGe,setXAxisRangeData:Ghe,setXAxisBand:BGe,setYAxisTitle:FGe,setYAxisRangeData:$Ge,setLineData:GGe,setBarData:VGe,setTmpSVGG:IGe,getChartThemeConfig:HGe,getChartConfig:WGe}});var YGe,qhe,Yhe=N(()=>{"use strict";vt();Vc();Ei();YGe=o((t,e,r,n)=>{let i=n.db,a=i.getChartThemeConfig(),s=i.getChartConfig();function l(v){return v==="top"?"text-before-edge":"middle"}o(l,"getDominantBaseLine");function u(v){return v==="left"?"start":v==="right"?"end":"middle"}o(u,"getTextAnchor");function h(v){return`translate(${v.x}, ${v.y}) rotate(${v.rotation||0})`}o(h,"getTextTransformation"),Y.debug(`Rendering xychart chart
+`+t);let f=sa(e),d=f.append("g").attr("class","main"),p=d.append("rect").attr("width",s.width).attr("height",s.height).attr("class","background");vn(f,s.height,s.width,!0),f.attr("viewBox",`0 0 ${s.width} ${s.height}`),p.attr("fill",a.backgroundColor),i.setTmpSVGG(f.append("g").attr("class","mermaid-tmp-group"));let m=i.getDrawableElem(),g={};function y(v){let x=d,b="";for(let[w]of v.entries()){let C=d;w>0&&g[b]&&(C=g[b]),b+=v[w],x=g[b],x||(x=g[b]=C.append("g").attr("class",v[w]))}return x}o(y,"getGroup");for(let v of m){if(v.data.length===0)continue;let x=y(v.groupTexts);switch(v.type){case"rect":x.selectAll("rect").data(v.data).enter().append("rect").attr("x",b=>b.x).attr("y",b=>b.y).attr("width",b=>b.width).attr("height",b=>b.height).attr("fill",b=>b.fill).attr("stroke",b=>b.strokeFill).attr("stroke-width",b=>b.strokeWidth);break;case"text":x.selectAll("text").data(v.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",b=>b.fill).attr("font-size",b=>b.fontSize).attr("dominant-baseline",b=>l(b.verticalPos)).attr("text-anchor",b=>u(b.horizontalPos)).attr("transform",b=>h(b)).text(b=>b.text);break;case"path":x.selectAll("path").data(v.data).enter().append("path").attr("d",b=>b.path).attr("fill",b=>b.fill?b.fill:"none").attr("stroke",b=>b.strokeFill).attr("stroke-width",b=>b.strokeWidth);break}}},"draw"),qhe={draw:YGe}});var Xhe={};hr(Xhe,{diagram:()=>XGe});var XGe,jhe=N(()=>{"use strict";She();Whe();Yhe();XGe={parser:Ehe,db:Hhe,renderer:qhe}});var EO,Zhe,Jhe=N(()=>{"use strict";EO=function(){var t=o(function(re,oe,V,xe){for(V=V||{},xe=re.length;xe--;V[re[xe]]=oe);return V},"o"),e=[1,3],r=[1,4],n=[1,5],i=[1,6],a=[5,6,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],s=[1,22],l=[2,7],u=[1,26],h=[1,27],f=[1,28],d=[1,29],p=[1,33],m=[1,34],g=[1,35],y=[1,36],v=[1,37],x=[1,38],b=[1,24],w=[1,31],C=[1,32],T=[1,30],E=[1,39],A=[1,40],S=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],_=[1,61],I=[89,90],D=[5,8,9,11,13,21,22,23,24,27,29,41,42,43,44,45,46,54,61,63,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],k=[27,29],L=[1,70],R=[1,71],O=[1,72],M=[1,73],B=[1,74],F=[1,75],P=[1,76],z=[1,83],$=[1,80],H=[1,84],Q=[1,85],j=[1,86],ie=[1,87],ne=[1,88],le=[1,89],he=[1,90],K=[1,91],X=[1,92],te=[5,8,9,11,13,21,22,23,24,27,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],J=[63,64],se=[1,101],ue=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,76,77,89,90],Z=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],Se=[1,110],ce=[1,106],ae=[1,107],Oe=[1,108],ge=[1,109],ze=[1,111],He=[1,116],$e=[1,117],Re=[1,114],Ie=[1,115],be={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,direction:17,styleStatement:18,classDefStatement:19,classStatement:20,direction_tb:21,direction_bt:22,direction_rl:23,direction_lr:24,requirementType:25,requirementName:26,STRUCT_START:27,requirementBody:28,STYLE_SEPARATOR:29,idList:30,ID:31,COLONSEP:32,id:33,TEXT:34,text:35,RISK:36,riskLevel:37,VERIFYMTHD:38,verifyType:39,STRUCT_STOP:40,REQUIREMENT:41,FUNCTIONAL_REQUIREMENT:42,INTERFACE_REQUIREMENT:43,PERFORMANCE_REQUIREMENT:44,PHYSICAL_REQUIREMENT:45,DESIGN_CONSTRAINT:46,LOW_RISK:47,MED_RISK:48,HIGH_RISK:49,VERIFY_ANALYSIS:50,VERIFY_DEMONSTRATION:51,VERIFY_INSPECTION:52,VERIFY_TEST:53,ELEMENT:54,elementName:55,elementBody:56,TYPE:57,type:58,DOCREF:59,ref:60,END_ARROW_L:61,relationship:62,LINE:63,END_ARROW_R:64,CONTAINS:65,COPIES:66,DERIVES:67,SATISFIES:68,VERIFIES:69,REFINES:70,TRACES:71,CLASSDEF:72,stylesOpt:73,CLASS:74,ALPHA:75,COMMA:76,STYLE:77,style:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,MINUS:86,LABEL:87,SEMICOLON:88,unqString:89,qString:90,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",21:"direction_tb",22:"direction_bt",23:"direction_rl",24:"direction_lr",27:"STRUCT_START",29:"STYLE_SEPARATOR",31:"ID",32:"COLONSEP",34:"TEXT",36:"RISK",38:"VERIFYMTHD",40:"STRUCT_STOP",41:"REQUIREMENT",42:"FUNCTIONAL_REQUIREMENT",43:"INTERFACE_REQUIREMENT",44:"PERFORMANCE_REQUIREMENT",45:"PHYSICAL_REQUIREMENT",46:"DESIGN_CONSTRAINT",47:"LOW_RISK",48:"MED_RISK",49:"HIGH_RISK",50:"VERIFY_ANALYSIS",51:"VERIFY_DEMONSTRATION",52:"VERIFY_INSPECTION",53:"VERIFY_TEST",54:"ELEMENT",57:"TYPE",59:"DOCREF",61:"END_ARROW_L",63:"LINE",64:"END_ARROW_R",65:"CONTAINS",66:"COPIES",67:"DERIVES",68:"SATISFIES",69:"VERIFIES",70:"REFINES",71:"TRACES",72:"CLASSDEF",74:"CLASS",75:"ALPHA",76:"COMMA",77:"STYLE",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",86:"MINUS",87:"LABEL",88:"SEMICOLON",89:"unqString",90:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[17,1],[17,1],[17,1],[17,1],[14,5],[14,7],[28,5],[28,5],[28,5],[28,5],[28,2],[28,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[37,1],[37,1],[37,1],[39,1],[39,1],[39,1],[39,1],[15,5],[15,7],[56,5],[56,5],[56,2],[56,1],[16,5],[16,5],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[19,3],[20,3],[20,3],[30,1],[30,3],[30,1],[30,3],[18,3],[73,1],[73,3],[78,1],[78,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[26,1],[26,1],[33,1],[33,1],[35,1],[35,1],[55,1],[55,1],[58,1],[58,1],[60,1],[60,1]],performAction:o(function(oe,V,xe,q,pe,ve,Pe){var _e=ve.length-1;switch(pe){case 4:this.$=ve[_e].trim(),q.setAccTitle(this.$);break;case 5:case 6:this.$=ve[_e].trim(),q.setAccDescription(this.$);break;case 7:this.$=[];break;case 17:q.setDirection("TB");break;case 18:q.setDirection("BT");break;case 19:q.setDirection("RL");break;case 20:q.setDirection("LR");break;case 21:q.addRequirement(ve[_e-3],ve[_e-4]);break;case 22:q.addRequirement(ve[_e-5],ve[_e-6]),q.setClass([ve[_e-5]],ve[_e-3]);break;case 23:q.setNewReqId(ve[_e-2]);break;case 24:q.setNewReqText(ve[_e-2]);break;case 25:q.setNewReqRisk(ve[_e-2]);break;case 26:q.setNewReqVerifyMethod(ve[_e-2]);break;case 29:this.$=q.RequirementType.REQUIREMENT;break;case 30:this.$=q.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 31:this.$=q.RequirementType.INTERFACE_REQUIREMENT;break;case 32:this.$=q.RequirementType.PERFORMANCE_REQUIREMENT;break;case 33:this.$=q.RequirementType.PHYSICAL_REQUIREMENT;break;case 34:this.$=q.RequirementType.DESIGN_CONSTRAINT;break;case 35:this.$=q.RiskLevel.LOW_RISK;break;case 36:this.$=q.RiskLevel.MED_RISK;break;case 37:this.$=q.RiskLevel.HIGH_RISK;break;case 38:this.$=q.VerifyType.VERIFY_ANALYSIS;break;case 39:this.$=q.VerifyType.VERIFY_DEMONSTRATION;break;case 40:this.$=q.VerifyType.VERIFY_INSPECTION;break;case 41:this.$=q.VerifyType.VERIFY_TEST;break;case 42:q.addElement(ve[_e-3]);break;case 43:q.addElement(ve[_e-5]),q.setClass([ve[_e-5]],ve[_e-3]);break;case 44:q.setNewElementType(ve[_e-2]);break;case 45:q.setNewElementDocRef(ve[_e-2]);break;case 48:q.addRelationship(ve[_e-2],ve[_e],ve[_e-4]);break;case 49:q.addRelationship(ve[_e-2],ve[_e-4],ve[_e]);break;case 50:this.$=q.Relationships.CONTAINS;break;case 51:this.$=q.Relationships.COPIES;break;case 52:this.$=q.Relationships.DERIVES;break;case 53:this.$=q.Relationships.SATISFIES;break;case 54:this.$=q.Relationships.VERIFIES;break;case 55:this.$=q.Relationships.REFINES;break;case 56:this.$=q.Relationships.TRACES;break;case 57:this.$=ve[_e-2],q.defineClass(ve[_e-1],ve[_e]);break;case 58:q.setClass(ve[_e-1],ve[_e]);break;case 59:q.setClass([ve[_e-2]],ve[_e]);break;case 60:case 62:this.$=[ve[_e]];break;case 61:case 63:this.$=ve[_e-2].concat([ve[_e]]);break;case 64:this.$=ve[_e-2],q.setCssStyle(ve[_e-1],ve[_e]);break;case 65:this.$=[ve[_e]];break;case 66:ve[_e-2].push(ve[_e]),this.$=ve[_e-2];break;case 68:this.$=ve[_e-1]+ve[_e];break}},"anonymous"),table:[{3:1,4:2,6:e,9:r,11:n,13:i},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:r,11:n,13:i},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(a,[2,6]),{3:12,4:2,6:e,9:r,11:n,13:i},{1:[2,2]},{4:17,5:s,7:13,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},t(a,[2,4]),t(a,[2,5]),{1:[2,1]},{8:[1,41]},{4:17,5:s,7:42,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:43,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:44,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:45,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:46,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:47,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:48,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:49,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{4:17,5:s,7:50,8:l,9:r,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:u,22:h,23:f,24:d,25:23,33:25,41:p,42:m,43:g,44:y,45:v,46:x,54:b,72:w,74:C,77:T,89:E,90:A},{26:51,89:[1,52],90:[1,53]},{55:54,89:[1,55],90:[1,56]},{29:[1,59],61:[1,57],63:[1,58]},t(S,[2,17]),t(S,[2,18]),t(S,[2,19]),t(S,[2,20]),{30:60,33:62,75:_,89:E,90:A},{30:63,33:62,75:_,89:E,90:A},{30:64,33:62,75:_,89:E,90:A},t(I,[2,29]),t(I,[2,30]),t(I,[2,31]),t(I,[2,32]),t(I,[2,33]),t(I,[2,34]),t(D,[2,81]),t(D,[2,82]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{8:[2,13]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{27:[1,65],29:[1,66]},t(k,[2,79]),t(k,[2,80]),{27:[1,67],29:[1,68]},t(k,[2,85]),t(k,[2,86]),{62:69,65:L,66:R,67:O,68:M,69:B,70:F,71:P},{62:77,65:L,66:R,67:O,68:M,69:B,70:F,71:P},{30:78,33:62,75:_,89:E,90:A},{73:79,75:z,76:$,78:81,79:82,80:H,81:Q,82:j,83:ie,84:ne,85:le,86:he,87:K,88:X},t(te,[2,60]),t(te,[2,62]),{73:93,75:z,76:$,78:81,79:82,80:H,81:Q,82:j,83:ie,84:ne,85:le,86:he,87:K,88:X},{30:94,33:62,75:_,76:$,89:E,90:A},{5:[1,95]},{30:96,33:62,75:_,89:E,90:A},{5:[1,97]},{30:98,33:62,75:_,89:E,90:A},{63:[1,99]},t(J,[2,50]),t(J,[2,51]),t(J,[2,52]),t(J,[2,53]),t(J,[2,54]),t(J,[2,55]),t(J,[2,56]),{64:[1,100]},t(S,[2,59],{76:$}),t(S,[2,64],{76:se}),{33:103,75:[1,102],89:E,90:A},t(ue,[2,65],{79:104,75:z,80:H,81:Q,82:j,83:ie,84:ne,85:le,86:he,87:K,88:X}),t(Z,[2,67]),t(Z,[2,69]),t(Z,[2,70]),t(Z,[2,71]),t(Z,[2,72]),t(Z,[2,73]),t(Z,[2,74]),t(Z,[2,75]),t(Z,[2,76]),t(Z,[2,77]),t(Z,[2,78]),t(S,[2,57],{76:se}),t(S,[2,58],{76:$}),{5:Se,28:105,31:ce,34:ae,36:Oe,38:ge,40:ze},{27:[1,112],76:$},{5:He,40:$e,56:113,57:Re,59:Ie},{27:[1,118],76:$},{33:119,89:E,90:A},{33:120,89:E,90:A},{75:z,78:121,79:82,80:H,81:Q,82:j,83:ie,84:ne,85:le,86:he,87:K,88:X},t(te,[2,61]),t(te,[2,63]),t(Z,[2,68]),t(S,[2,21]),{32:[1,122]},{32:[1,123]},{32:[1,124]},{32:[1,125]},{5:Se,28:126,31:ce,34:ae,36:Oe,38:ge,40:ze},t(S,[2,28]),{5:[1,127]},t(S,[2,42]),{32:[1,128]},{32:[1,129]},{5:He,40:$e,56:130,57:Re,59:Ie},t(S,[2,47]),{5:[1,131]},t(S,[2,48]),t(S,[2,49]),t(ue,[2,66],{79:104,75:z,80:H,81:Q,82:j,83:ie,84:ne,85:le,86:he,87:K,88:X}),{33:132,89:E,90:A},{35:133,89:[1,134],90:[1,135]},{37:136,47:[1,137],48:[1,138],49:[1,139]},{39:140,50:[1,141],51:[1,142],52:[1,143],53:[1,144]},t(S,[2,27]),{5:Se,28:145,31:ce,34:ae,36:Oe,38:ge,40:ze},{58:146,89:[1,147],90:[1,148]},{60:149,89:[1,150],90:[1,151]},t(S,[2,46]),{5:He,40:$e,56:152,57:Re,59:Ie},{5:[1,153]},{5:[1,154]},{5:[2,83]},{5:[2,84]},{5:[1,155]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[1,156]},{5:[2,38]},{5:[2,39]},{5:[2,40]},{5:[2,41]},t(S,[2,22]),{5:[1,157]},{5:[2,87]},{5:[2,88]},{5:[1,158]},{5:[2,89]},{5:[2,90]},t(S,[2,43]),{5:Se,28:159,31:ce,34:ae,36:Oe,38:ge,40:ze},{5:Se,28:160,31:ce,34:ae,36:Oe,38:ge,40:ze},{5:Se,28:161,31:ce,34:ae,36:Oe,38:ge,40:ze},{5:Se,28:162,31:ce,34:ae,36:Oe,38:ge,40:ze},{5:He,40:$e,56:163,57:Re,59:Ie},{5:He,40:$e,56:164,57:Re,59:Ie},t(S,[2,23]),t(S,[2,24]),t(S,[2,25]),t(S,[2,26]),t(S,[2,44]),t(S,[2,45])],defaultActions:{8:[2,2],12:[2,1],41:[2,3],42:[2,8],43:[2,9],44:[2,10],45:[2,11],46:[2,12],47:[2,13],48:[2,14],49:[2,15],50:[2,16],134:[2,83],135:[2,84],137:[2,35],138:[2,36],139:[2,37],141:[2,38],142:[2,39],143:[2,40],144:[2,41],147:[2,87],148:[2,88],150:[2,89],151:[2,90]},parseError:o(function(oe,V){if(V.recoverable)this.trace(oe);else{var xe=new Error(oe);throw xe.hash=V,xe}},"parseError"),parse:o(function(oe){var V=this,xe=[0],q=[],pe=[null],ve=[],Pe=this.table,_e="",we=0,Ve=0,De=0,qe=2,at=1,Rt=ve.slice.call(arguments,1),st=Object.create(this.lexer),Ue={yy:{}};for(var ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ct)&&(Ue.yy[ct]=this.yy[ct]);st.setInput(oe,Ue.yy),Ue.yy.lexer=st,Ue.yy.parser=this,typeof st.yylloc>"u"&&(st.yylloc={});var We=st.yylloc;ve.push(We);var ot=st.options&&st.options.ranges;typeof Ue.yy.parseError=="function"?this.parseError=Ue.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Yt(Dr){xe.length=xe.length-2*Dr,pe.length=pe.length-Dr,ve.length=ve.length-Dr}o(Yt,"popStack");function bt(){var Dr;return Dr=q.pop()||st.lex()||at,typeof Dr!="number"&&(Dr instanceof Array&&(q=Dr,Dr=q.pop()),Dr=V.symbols_[Dr]||Dr),Dr}o(bt,"lex");for(var Mt,xt,ut,Et,ft,yt,nt={},dn,Tt,On,tn;;){if(ut=xe[xe.length-1],this.defaultActions[ut]?Et=this.defaultActions[ut]:((Mt===null||typeof Mt>"u")&&(Mt=bt()),Et=Pe[ut]&&Pe[ut][Mt]),typeof Et>"u"||!Et.length||!Et[0]){var _r="";tn=[];for(dn in Pe[ut])this.terminals_[dn]&&dn>qe&&tn.push("'"+this.terminals_[dn]+"'");st.showPosition?_r="Parse error on line "+(we+1)+`:
+`+st.showPosition()+`
+Expecting `+tn.join(", ")+", got '"+(this.terminals_[Mt]||Mt)+"'":_r="Parse error on line "+(we+1)+": Unexpected "+(Mt==at?"end of input":"'"+(this.terminals_[Mt]||Mt)+"'"),this.parseError(_r,{text:st.match,token:this.terminals_[Mt]||Mt,line:st.yylineno,loc:We,expected:tn})}if(Et[0]instanceof Array&&Et.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ut+", token: "+Mt);switch(Et[0]){case 1:xe.push(Mt),pe.push(st.yytext),ve.push(st.yylloc),xe.push(Et[1]),Mt=null,xt?(Mt=xt,xt=null):(Ve=st.yyleng,_e=st.yytext,we=st.yylineno,We=st.yylloc,De>0&&De--);break;case 2:if(Tt=this.productions_[Et[1]][1],nt.$=pe[pe.length-Tt],nt._$={first_line:ve[ve.length-(Tt||1)].first_line,last_line:ve[ve.length-1].last_line,first_column:ve[ve.length-(Tt||1)].first_column,last_column:ve[ve.length-1].last_column},ot&&(nt._$.range=[ve[ve.length-(Tt||1)].range[0],ve[ve.length-1].range[1]]),yt=this.performAction.apply(nt,[_e,Ve,we,Ue.yy,Et[1],pe,ve].concat(Rt)),typeof yt<"u")return yt;Tt&&(xe=xe.slice(0,-1*Tt*2),pe=pe.slice(0,-1*Tt),ve=ve.slice(0,-1*Tt)),xe.push(this.productions_[Et[1]][0]),pe.push(nt.$),ve.push(nt._$),On=Pe[xe[xe.length-2]][xe[xe.length-1]],xe.push(On);break;case 3:return!0}}return!0},"parse")},W=function(){var re={EOF:1,parseError:o(function(V,xe){if(this.yy.parser)this.yy.parser.parseError(V,xe);else throw new Error(V)},"parseError"),setInput:o(function(oe,V){return this.yy=V||this.yy||{},this._input=oe,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var oe=this._input[0];this.yytext+=oe,this.yyleng++,this.offset++,this.match+=oe,this.matched+=oe;var V=oe.match(/(?:\r\n?|\n).*/g);return V?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),oe},"input"),unput:o(function(oe){var V=oe.length,xe=oe.split(/(?:\r\n?|\n)/g);this._input=oe+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-V),this.offset-=V;var q=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),xe.length-1&&(this.yylineno-=xe.length-1);var pe=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:xe?(xe.length===q.length?this.yylloc.first_column:0)+q[q.length-xe.length].length-xe[0].length:this.yylloc.first_column-V},this.options.ranges&&(this.yylloc.range=[pe[0],pe[0]+this.yyleng-V]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(oe){this.unput(this.match.slice(oe))},"less"),pastInput:o(function(){var oe=this.matched.substr(0,this.matched.length-this.match.length);return(oe.length>20?"...":"")+oe.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var oe=this.match;return oe.length<20&&(oe+=this._input.substr(0,20-oe.length)),(oe.substr(0,20)+(oe.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var oe=this.pastInput(),V=new Array(oe.length+1).join("-");return oe+this.upcomingInput()+`
+`+V+"^"},"showPosition"),test_match:o(function(oe,V){var xe,q,pe;if(this.options.backtrack_lexer&&(pe={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(pe.yylloc.range=this.yylloc.range.slice(0))),q=oe[0].match(/(?:\r\n?|\n).*/g),q&&(this.yylineno+=q.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:q?q[q.length-1].length-q[q.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+oe[0].length},this.yytext+=oe[0],this.match+=oe[0],this.matches=oe,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(oe[0].length),this.matched+=oe[0],xe=this.performAction.call(this,this.yy,this,V,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),xe)return xe;if(this._backtrack){for(var ve in pe)this[ve]=pe[ve];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var oe,V,xe,q;this._more||(this.yytext="",this.match="");for(var pe=this._currentRules(),ve=0;ve<pe.length;ve++)if(xe=this._input.match(this.rules[pe[ve]]),xe&&(!V||xe[0].length>V[0].length)){if(V=xe,q=ve,this.options.backtrack_lexer){if(oe=this.test_match(xe,pe[ve]),oe!==!1)return oe;if(this._backtrack){V=!1;continue}else return!1}else if(!this.options.flex)break}return V?(oe=this.test_match(V,pe[q]),oe!==!1?oe:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var V=this.next();return V||this.lex()},"lex"),begin:o(function(V){this.conditionStack.push(V)},"begin"),popState:o(function(){var V=this.conditionStack.length-1;return V>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(V){return V=this.conditionStack.length-1-Math.abs(V||0),V>=0?this.conditionStack[V]:"INITIAL"},"topState"),pushState:o(function(V){this.begin(V)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(V,xe,q,pe){var ve=pe;switch(q){case 0:return"title";case 1:return this.begin("acc_title"),9;break;case 2:return this.popState(),"acc_title_value";break;case 3:return this.begin("acc_descr"),11;break;case 4:return this.popState(),"acc_descr_value";break;case 5:this.begin("acc_descr_multiline");break;case 6:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 21;case 9:return 22;case 10:return 23;case 11:return 24;case 12:return 5;case 13:break;case 14:break;case 15:break;case 16:return 8;case 17:return 6;case 18:return 27;case 19:return 40;case 20:return 29;case 21:return 32;case 22:return 31;case 23:return 34;case 24:return 36;case 25:return 38;case 26:return 41;case 27:return 42;case 28:return 43;case 29:return 44;case 30:return 45;case 31:return 46;case 32:return 47;case 33:return 48;case 34:return 49;case 35:return 50;case 36:return 51;case 37:return 52;case 38:return 53;case 39:return 54;case 40:return 65;case 41:return 66;case 42:return 67;case 43:return 68;case 44:return 69;case 45:return 70;case 46:return 71;case 47:return 57;case 48:return 59;case 49:return this.begin("style"),77;break;case 50:return 75;case 51:return 81;case 52:return 88;case 53:return"PERCENT";case 54:return 86;case 55:return 84;case 56:break;case 57:this.begin("string");break;case 58:this.popState();break;case 59:return this.begin("style"),72;break;case 60:return this.begin("style"),74;break;case 61:return 61;case 62:return 64;case 63:return 63;case 64:this.begin("string");break;case 65:this.popState();break;case 66:return"qString";case 67:return xe.yytext=xe.yytext.trim(),89;break;case 68:return 75;case 69:return 80;case 70:return 76}},"anonymous"),rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::{3})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:style\b)/i,/^(?:\w+)/i,/^(?::)/i,/^(?:;)/i,/^(?:%)/i,/^(?:-)/i,/^(?:#)/i,/^(?: )/i,/^(?:["])/i,/^(?:\n)/i,/^(?:classDef\b)/i,/^(?:class\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^:,\r\n\{\<\>\-\=]*)/i,/^(?:\w+)/i,/^(?:[0-9]+)/i,/^(?:,)/i],conditions:{acc_descr_multiline:{rules:[6,7,68,69,70],inclusive:!1},acc_descr:{rules:[4,68,69,70],inclusive:!1},acc_title:{rules:[2,68,69,70],inclusive:!1},style:{rules:[50,51,52,53,54,55,56,57,58,68,69,70],inclusive:!1},unqString:{rules:[68,69,70],inclusive:!1},token:{rules:[68,69,70],inclusive:!1},string:{rules:[65,66,68,69,70],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,59,60,61,62,63,64,67,68,69,70],inclusive:!0}}};return re}();be.lexer=W;function de(){this.yy={}}return o(de,"Parser"),de.prototype=be,be.Parser=de,new de}();EO.parser=EO;Zhe=EO});var A6,efe=N(()=>{"use strict";zt();vt();mi();A6=class{constructor(){this.relations=[];this.latestRequirement=this.getInitialRequirement();this.requirements=new Map;this.latestElement=this.getInitialElement();this.elements=new Map;this.classes=new Map;this.direction="TB";this.RequirementType={REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"};this.RiskLevel={LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"};this.VerifyType={VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"};this.Relationships={CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"};this.setAccTitle=Lr;this.getAccTitle=Rr;this.setAccDescription=Nr;this.getAccDescription=Mr;this.setDiagramTitle=$r;this.getDiagramTitle=Ir;this.getConfig=o(()=>me().requirement,"getConfig");this.clear(),this.setDirection=this.setDirection.bind(this),this.addRequirement=this.addRequirement.bind(this),this.setNewReqId=this.setNewReqId.bind(this),this.setNewReqRisk=this.setNewReqRisk.bind(this),this.setNewReqText=this.setNewReqText.bind(this),this.setNewReqVerifyMethod=this.setNewReqVerifyMethod.bind(this),this.addElement=this.addElement.bind(this),this.setNewElementType=this.setNewElementType.bind(this),this.setNewElementDocRef=this.setNewElementDocRef.bind(this),this.addRelationship=this.addRelationship.bind(this),this.setCssStyle=this.setCssStyle.bind(this),this.setClass=this.setClass.bind(this),this.defineClass=this.defineClass.bind(this),this.setAccTitle=this.setAccTitle.bind(this),this.setAccDescription=this.setAccDescription.bind(this)}static{o(this,"RequirementDB")}getDirection(){return this.direction}setDirection(e){this.direction=e}resetLatestRequirement(){this.latestRequirement=this.getInitialRequirement()}resetLatestElement(){this.latestElement=this.getInitialElement()}getInitialRequirement(){return{requirementId:"",text:"",risk:"",verifyMethod:"",name:"",type:"",cssStyles:[],classes:["default"]}}getInitialElement(){return{name:"",type:"",docRef:"",cssStyles:[],classes:["default"]}}addRequirement(e,r){return this.requirements.has(e)||this.requirements.set(e,{name:e,type:r,requirementId:this.latestRequirement.requirementId,text:this.latestRequirement.text,risk:this.latestRequirement.risk,verifyMethod:this.latestRequirement.verifyMethod,cssStyles:[],classes:["default"]}),this.resetLatestRequirement(),this.requirements.get(e)}getRequirements(){return this.requirements}setNewReqId(e){this.latestRequirement!==void 0&&(this.latestRequirement.requirementId=e)}setNewReqText(e){this.latestRequirement!==void 0&&(this.latestRequirement.text=e)}setNewReqRisk(e){this.latestRequirement!==void 0&&(this.latestRequirement.risk=e)}setNewReqVerifyMethod(e){this.latestRequirement!==void 0&&(this.latestRequirement.verifyMethod=e)}addElement(e){return this.elements.has(e)||(this.elements.set(e,{name:e,type:this.latestElement.type,docRef:this.latestElement.docRef,cssStyles:[],classes:["default"]}),Y.info("Added new element: ",e)),this.resetLatestElement(),this.elements.get(e)}getElements(){return this.elements}setNewElementType(e){this.latestElement!==void 0&&(this.latestElement.type=e)}setNewElementDocRef(e){this.latestElement!==void 0&&(this.latestElement.docRef=e)}addRelationship(e,r,n){this.relations.push({type:e,src:r,dst:n})}getRelationships(){return this.relations}clear(){this.relations=[],this.resetLatestRequirement(),this.requirements=new Map,this.resetLatestElement(),this.elements=new Map,this.classes=new Map,Ar()}setCssStyle(e,r){for(let n of e){let i=this.requirements.get(n)??this.elements.get(n);if(!r||!i)return;for(let a of r)a.includes(",")?i.cssStyles.push(...a.split(",")):i.cssStyles.push(a)}}setClass(e,r){for(let n of e){let i=this.requirements.get(n)??this.elements.get(n);if(i)for(let a of r){i.classes.push(a);let s=this.classes.get(a)?.styles;s&&i.cssStyles.push(...s)}}}defineClass(e,r){for(let n of e){let i=this.classes.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.classes.set(n,i)),r&&r.forEach(function(a){if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)}),this.requirements.forEach(a=>{a.classes.includes(n)&&a.cssStyles.push(...r.flatMap(s=>s.split(",")))}),this.elements.forEach(a=>{a.classes.includes(n)&&a.cssStyles.push(...r.flatMap(s=>s.split(",")))})}}getClasses(){return this.classes}getData(){let e=me(),r=[],n=[];for(let i of this.requirements.values()){let a=i;a.id=i.name,a.cssStyles=i.cssStyles,a.cssClasses=i.classes.join(" "),a.shape="requirementBox",a.look=e.look,r.push(a)}for(let i of this.elements.values()){let a=i;a.shape="requirementBox",a.look=e.look,a.id=i.name,a.cssStyles=i.cssStyles,a.cssClasses=i.classes.join(" "),r.push(a)}for(let i of this.relations){let a=0,s=i.type===this.Relationships.CONTAINS,l={id:`${i.src}-${i.dst}-${a}`,start:this.requirements.get(i.src)?.name??this.elements.get(i.src)?.name,end:this.requirements.get(i.dst)?.name??this.elements.get(i.dst)?.name,label:`&lt;&lt;${i.type}&gt;&gt;`,classes:"relationshipLine",style:["fill:none",s?"":"stroke-dasharray: 10,7"],labelpos:"c",thickness:"normal",type:"normal",pattern:s?"normal":"dashed",arrowTypeStart:s?"requirement_contains":"",arrowTypeEnd:s?"":"requirement_arrow",look:e.look};n.push(l),a++}return{nodes:r,edges:n,other:{},config:e,direction:this.getDirection()}}}});var ZGe,tfe,rfe=N(()=>{"use strict";ZGe=o(t=>`
+
+ marker {
+ fill: ${t.relationColor};
+ stroke: ${t.relationColor};
+ }
+
+ marker.cross {
+ stroke: ${t.lineColor};
+ }
+
+ svg {
+ font-family: ${t.fontFamily};
+ font-size: ${t.fontSize};
+ }
+
+ .reqBox {
+ fill: ${t.requirementBackground};
+ fill-opacity: 1.0;
+ stroke: ${t.requirementBorderColor};
+ stroke-width: ${t.requirementBorderSize};
+ }
+
+ .reqTitle, .reqLabel{
+ fill: ${t.requirementTextColor};
+ }
+ .reqLabelBox {
+ fill: ${t.relationLabelBackground};
+ fill-opacity: 1.0;
+ }
+
+ .req-title-line {
+ stroke: ${t.requirementBorderColor};
+ stroke-width: ${t.requirementBorderSize};
+ }
+ .relationshipLine {
+ stroke: ${t.relationColor};
+ stroke-width: 1;
+ }
+ .relationshipLabel {
+ fill: ${t.relationLabelColor};
+ }
+ .divider {
+ stroke: ${t.nodeBorder};
+ stroke-width: 1;
+ }
+ .label {
+ font-family: ${t.fontFamily};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+ .label text,span {
+ fill: ${t.nodeTextColor||t.textColor};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+ .labelBkg {
+ background-color: ${t.edgeLabelBackground};
+ }
+
+`,"getStyles"),tfe=ZGe});var SO={};hr(SO,{draw:()=>JGe});var JGe,nfe=N(()=>{"use strict";zt();vt();gm();Yd();$m();ir();JGe=o(async function(t,e,r,n){Y.info("REF0:"),Y.info("Drawing requirement diagram (unified)",e);let{securityLevel:i,state:a,layout:s}=me(),l=n.db.getData(),u=yc(e,i);l.type=n.type,l.layoutAlgorithm=nf(s),l.nodeSpacing=a?.nodeSpacing??50,l.rankSpacing=a?.rankSpacing??50,l.markers=["requirement_contains","requirement_arrow"],l.diagramId=e,await Cc(l,u);let h=8;Gt.insertTitle(u,"requirementDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Ac(u,h,"requirementDiagram",a?.useMaxWidth??!0)},"draw")});var ife={};hr(ife,{diagram:()=>eVe});var eVe,afe=N(()=>{"use strict";Jhe();efe();rfe();nfe();eVe={parser:Zhe,get db(){return new A6},renderer:SO,styles:tfe}});var CO,lfe,cfe=N(()=>{"use strict";CO=function(){var t=o(function(K,X,te,J){for(te=te||{},J=K.length;J--;te[K[J]]=X);return te},"o"),e=[1,2],r=[1,3],n=[1,4],i=[2,4],a=[1,9],s=[1,11],l=[1,13],u=[1,14],h=[1,16],f=[1,17],d=[1,18],p=[1,24],m=[1,25],g=[1,26],y=[1,27],v=[1,28],x=[1,29],b=[1,30],w=[1,31],C=[1,32],T=[1,33],E=[1,34],A=[1,35],S=[1,36],_=[1,37],I=[1,38],D=[1,39],k=[1,41],L=[1,42],R=[1,43],O=[1,44],M=[1,45],B=[1,46],F=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],P=[4,5,16,50,52,53],z=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],H=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],Q=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],j=[68,69,70],ie=[1,122],ne={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,BIDIRECTIONAL_SOLID_ARROW:74,DOTTED_ARROW:75,BIDIRECTIONAL_DOTTED_ARROW:76,SOLID_CROSS:77,DOTTED_CROSS:78,SOLID_POINT:79,DOTTED_POINT:80,TXT:81,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"BIDIRECTIONAL_SOLID_ARROW",75:"DOTTED_ARROW",76:"BIDIRECTIONAL_DOTTED_ARROW",77:"SOLID_CROSS",78:"DOTTED_CROSS",79:"SOLID_POINT",80:"DOTTED_POINT",81:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:o(function(X,te,J,se,ue,Z,Se){var ce=Z.length-1;switch(ue){case 3:return se.apply(Z[ce]),Z[ce];break;case 4:case 9:this.$=[];break;case 5:case 10:Z[ce-1].push(Z[ce]),this.$=Z[ce-1];break;case 6:case 7:case 11:case 12:this.$=Z[ce];break;case 8:case 13:this.$=[];break;case 15:Z[ce].type="createParticipant",this.$=Z[ce];break;case 16:Z[ce-1].unshift({type:"boxStart",boxData:se.parseBoxData(Z[ce-2])}),Z[ce-1].push({type:"boxEnd",boxText:Z[ce-2]}),this.$=Z[ce-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(Z[ce-2]),sequenceIndexStep:Number(Z[ce-1]),sequenceVisible:!0,signalType:se.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(Z[ce-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:se.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:se.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:se.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:se.LINETYPE.ACTIVE_START,actor:Z[ce-1].actor};break;case 23:this.$={type:"activeEnd",signalType:se.LINETYPE.ACTIVE_END,actor:Z[ce-1].actor};break;case 29:se.setDiagramTitle(Z[ce].substring(6)),this.$=Z[ce].substring(6);break;case 30:se.setDiagramTitle(Z[ce].substring(7)),this.$=Z[ce].substring(7);break;case 31:this.$=Z[ce].trim(),se.setAccTitle(this.$);break;case 32:case 33:this.$=Z[ce].trim(),se.setAccDescription(this.$);break;case 34:Z[ce-1].unshift({type:"loopStart",loopText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.LOOP_START}),Z[ce-1].push({type:"loopEnd",loopText:Z[ce-2],signalType:se.LINETYPE.LOOP_END}),this.$=Z[ce-1];break;case 35:Z[ce-1].unshift({type:"rectStart",color:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.RECT_START}),Z[ce-1].push({type:"rectEnd",color:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.RECT_END}),this.$=Z[ce-1];break;case 36:Z[ce-1].unshift({type:"optStart",optText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.OPT_START}),Z[ce-1].push({type:"optEnd",optText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.OPT_END}),this.$=Z[ce-1];break;case 37:Z[ce-1].unshift({type:"altStart",altText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.ALT_START}),Z[ce-1].push({type:"altEnd",signalType:se.LINETYPE.ALT_END}),this.$=Z[ce-1];break;case 38:Z[ce-1].unshift({type:"parStart",parText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.PAR_START}),Z[ce-1].push({type:"parEnd",signalType:se.LINETYPE.PAR_END}),this.$=Z[ce-1];break;case 39:Z[ce-1].unshift({type:"parStart",parText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.PAR_OVER_START}),Z[ce-1].push({type:"parEnd",signalType:se.LINETYPE.PAR_END}),this.$=Z[ce-1];break;case 40:Z[ce-1].unshift({type:"criticalStart",criticalText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.CRITICAL_START}),Z[ce-1].push({type:"criticalEnd",signalType:se.LINETYPE.CRITICAL_END}),this.$=Z[ce-1];break;case 41:Z[ce-1].unshift({type:"breakStart",breakText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.BREAK_START}),Z[ce-1].push({type:"breakEnd",optText:se.parseMessage(Z[ce-2]),signalType:se.LINETYPE.BREAK_END}),this.$=Z[ce-1];break;case 43:this.$=Z[ce-3].concat([{type:"option",optionText:se.parseMessage(Z[ce-1]),signalType:se.LINETYPE.CRITICAL_OPTION},Z[ce]]);break;case 45:this.$=Z[ce-3].concat([{type:"and",parText:se.parseMessage(Z[ce-1]),signalType:se.LINETYPE.PAR_AND},Z[ce]]);break;case 47:this.$=Z[ce-3].concat([{type:"else",altText:se.parseMessage(Z[ce-1]),signalType:se.LINETYPE.ALT_ELSE},Z[ce]]);break;case 48:Z[ce-3].draw="participant",Z[ce-3].type="addParticipant",Z[ce-3].description=se.parseMessage(Z[ce-1]),this.$=Z[ce-3];break;case 49:Z[ce-1].draw="participant",Z[ce-1].type="addParticipant",this.$=Z[ce-1];break;case 50:Z[ce-3].draw="actor",Z[ce-3].type="addParticipant",Z[ce-3].description=se.parseMessage(Z[ce-1]),this.$=Z[ce-3];break;case 51:Z[ce-1].draw="actor",Z[ce-1].type="addParticipant",this.$=Z[ce-1];break;case 52:Z[ce-1].type="destroyParticipant",this.$=Z[ce-1];break;case 53:this.$=[Z[ce-1],{type:"addNote",placement:Z[ce-2],actor:Z[ce-1].actor,text:Z[ce]}];break;case 54:Z[ce-2]=[].concat(Z[ce-1],Z[ce-1]).slice(0,2),Z[ce-2][0]=Z[ce-2][0].actor,Z[ce-2][1]=Z[ce-2][1].actor,this.$=[Z[ce-1],{type:"addNote",placement:se.PLACEMENT.OVER,actor:Z[ce-2].slice(0,2),text:Z[ce]}];break;case 55:this.$=[Z[ce-1],{type:"addLinks",actor:Z[ce-1].actor,text:Z[ce]}];break;case 56:this.$=[Z[ce-1],{type:"addALink",actor:Z[ce-1].actor,text:Z[ce]}];break;case 57:this.$=[Z[ce-1],{type:"addProperties",actor:Z[ce-1].actor,text:Z[ce]}];break;case 58:this.$=[Z[ce-1],{type:"addDetails",actor:Z[ce-1].actor,text:Z[ce]}];break;case 61:this.$=[Z[ce-2],Z[ce]];break;case 62:this.$=Z[ce];break;case 63:this.$=se.PLACEMENT.LEFTOF;break;case 64:this.$=se.PLACEMENT.RIGHTOF;break;case 65:this.$=[Z[ce-4],Z[ce-1],{type:"addMessage",from:Z[ce-4].actor,to:Z[ce-1].actor,signalType:Z[ce-3],msg:Z[ce],activate:!0},{type:"activeStart",signalType:se.LINETYPE.ACTIVE_START,actor:Z[ce-1].actor}];break;case 66:this.$=[Z[ce-4],Z[ce-1],{type:"addMessage",from:Z[ce-4].actor,to:Z[ce-1].actor,signalType:Z[ce-3],msg:Z[ce]},{type:"activeEnd",signalType:se.LINETYPE.ACTIVE_END,actor:Z[ce-4].actor}];break;case 67:this.$=[Z[ce-3],Z[ce-1],{type:"addMessage",from:Z[ce-3].actor,to:Z[ce-1].actor,signalType:Z[ce-2],msg:Z[ce]}];break;case 68:this.$={type:"addParticipant",actor:Z[ce]};break;case 69:this.$=se.LINETYPE.SOLID_OPEN;break;case 70:this.$=se.LINETYPE.DOTTED_OPEN;break;case 71:this.$=se.LINETYPE.SOLID;break;case 72:this.$=se.LINETYPE.BIDIRECTIONAL_SOLID;break;case 73:this.$=se.LINETYPE.DOTTED;break;case 74:this.$=se.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 75:this.$=se.LINETYPE.SOLID_CROSS;break;case 76:this.$=se.LINETYPE.DOTTED_CROSS;break;case 77:this.$=se.LINETYPE.SOLID_POINT;break;case 78:this.$=se.LINETYPE.DOTTED_POINT;break;case 79:this.$=se.parseMessage(Z[ce].trim().substring(1));break}},"anonymous"),table:[{3:1,4:e,5:r,6:n},{1:[3]},{3:5,4:e,5:r,6:n},{3:6,4:e,5:r,6:n},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:s,8:8,9:10,12:12,13:l,14:u,17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},t(F,[2,5]),{9:47,12:12,13:l,14:u,17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},t(F,[2,7]),t(F,[2,8]),t(F,[2,14]),{12:48,50:_,52:I,53:D},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:B},{22:55,70:B},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(F,[2,29]),t(F,[2,30]),{32:[1,61]},{34:[1,62]},t(F,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:B},{22:72,70:B},{22:73,70:B},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82],79:[1,83],80:[1,84]},{55:85,57:[1,86],65:[1,87],66:[1,88]},{22:89,70:B},{22:90,70:B},{22:91,70:B},{22:92,70:B},t([5,51,64,71,72,73,74,75,76,77,78,79,80,81],[2,68]),t(F,[2,6]),t(F,[2,15]),t(P,[2,9],{10:93}),t(F,[2,17]),{5:[1,95],19:[1,94]},{5:[1,96]},t(F,[2,21]),{5:[1,97]},{5:[1,98]},t(F,[2,24]),t(F,[2,25]),t(F,[2,26]),t(F,[2,27]),t(F,[2,28]),t(F,[2,31]),t(F,[2,32]),t(z,i,{7:99}),t(z,i,{7:100}),t(z,i,{7:101}),t($,i,{40:102,7:103}),t(H,i,{42:104,7:105}),t(H,i,{7:105,42:106}),t(Q,i,{45:107,7:108}),t(z,i,{7:109}),{5:[1,111],51:[1,110]},{5:[1,113],51:[1,112]},{5:[1,114]},{22:117,68:[1,115],69:[1,116],70:B},t(j,[2,69]),t(j,[2,70]),t(j,[2,71]),t(j,[2,72]),t(j,[2,73]),t(j,[2,74]),t(j,[2,75]),t(j,[2,76]),t(j,[2,77]),t(j,[2,78]),{22:118,70:B},{22:120,58:119,70:B},{70:[2,63]},{70:[2,64]},{56:121,81:ie},{56:123,81:ie},{56:124,81:ie},{56:125,81:ie},{4:[1,128],5:[1,130],11:127,12:129,16:[1,126],50:_,52:I,53:D},{5:[1,131]},t(F,[2,19]),t(F,[2,20]),t(F,[2,22]),t(F,[2,23]),{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,132],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,133],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,134],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{16:[1,135]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,46],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,49:[1,136],50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{16:[1,137]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,44],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,48:[1,138],50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{16:[1,139]},{16:[1,140]},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[2,42],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,47:[1,141],50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{4:a,5:s,8:8,9:10,12:12,13:l,14:u,16:[1,142],17:15,18:h,21:f,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:m,31:g,33:y,35:v,36:x,37:b,38:w,39:C,41:T,43:E,44:A,46:S,50:_,52:I,53:D,54:k,59:L,60:R,61:O,62:M,70:B},{15:[1,143]},t(F,[2,49]),{15:[1,144]},t(F,[2,51]),t(F,[2,52]),{22:145,70:B},{22:146,70:B},{56:147,81:ie},{56:148,81:ie},{56:149,81:ie},{64:[1,150],81:[2,62]},{5:[2,55]},{5:[2,79]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(F,[2,16]),t(P,[2,10]),{12:151,50:_,52:I,53:D},t(P,[2,12]),t(P,[2,13]),t(F,[2,18]),t(F,[2,34]),t(F,[2,35]),t(F,[2,36]),t(F,[2,37]),{15:[1,152]},t(F,[2,38]),{15:[1,153]},t(F,[2,39]),t(F,[2,40]),{15:[1,154]},t(F,[2,41]),{5:[1,155]},{5:[1,156]},{56:157,81:ie},{56:158,81:ie},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:159,70:B},t(P,[2,11]),t($,i,{7:103,40:160}),t(H,i,{7:105,42:161}),t(Q,i,{7:108,45:162}),t(F,[2,48]),t(F,[2,50]),{5:[2,65]},{5:[2,66]},{81:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],87:[2,63],88:[2,64],121:[2,55],122:[2,79],123:[2,56],124:[2,57],125:[2,58],147:[2,67],148:[2,53],149:[2,54],157:[2,65],158:[2,66],159:[2,61],160:[2,47],161:[2,45],162:[2,43]},parseError:o(function(X,te){if(te.recoverable)this.trace(X);else{var J=new Error(X);throw J.hash=te,J}},"parseError"),parse:o(function(X){var te=this,J=[0],se=[],ue=[null],Z=[],Se=this.table,ce="",ae=0,Oe=0,ge=0,ze=2,He=1,$e=Z.slice.call(arguments,1),Re=Object.create(this.lexer),Ie={yy:{}};for(var be in this.yy)Object.prototype.hasOwnProperty.call(this.yy,be)&&(Ie.yy[be]=this.yy[be]);Re.setInput(X,Ie.yy),Ie.yy.lexer=Re,Ie.yy.parser=this,typeof Re.yylloc>"u"&&(Re.yylloc={});var W=Re.yylloc;Z.push(W);var de=Re.options&&Re.options.ranges;typeof Ie.yy.parseError=="function"?this.parseError=Ie.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function re(Rt){J.length=J.length-2*Rt,ue.length=ue.length-Rt,Z.length=Z.length-Rt}o(re,"popStack");function oe(){var Rt;return Rt=se.pop()||Re.lex()||He,typeof Rt!="number"&&(Rt instanceof Array&&(se=Rt,Rt=se.pop()),Rt=te.symbols_[Rt]||Rt),Rt}o(oe,"lex");for(var V,xe,q,pe,ve,Pe,_e={},we,Ve,De,qe;;){if(q=J[J.length-1],this.defaultActions[q]?pe=this.defaultActions[q]:((V===null||typeof V>"u")&&(V=oe()),pe=Se[q]&&Se[q][V]),typeof pe>"u"||!pe.length||!pe[0]){var at="";qe=[];for(we in Se[q])this.terminals_[we]&&we>ze&&qe.push("'"+this.terminals_[we]+"'");Re.showPosition?at="Parse error on line "+(ae+1)+`:
+`+Re.showPosition()+`
+Expecting `+qe.join(", ")+", got '"+(this.terminals_[V]||V)+"'":at="Parse error on line "+(ae+1)+": Unexpected "+(V==He?"end of input":"'"+(this.terminals_[V]||V)+"'"),this.parseError(at,{text:Re.match,token:this.terminals_[V]||V,line:Re.yylineno,loc:W,expected:qe})}if(pe[0]instanceof Array&&pe.length>1)throw new Error("Parse Error: multiple actions possible at state: "+q+", token: "+V);switch(pe[0]){case 1:J.push(V),ue.push(Re.yytext),Z.push(Re.yylloc),J.push(pe[1]),V=null,xe?(V=xe,xe=null):(Oe=Re.yyleng,ce=Re.yytext,ae=Re.yylineno,W=Re.yylloc,ge>0&&ge--);break;case 2:if(Ve=this.productions_[pe[1]][1],_e.$=ue[ue.length-Ve],_e._$={first_line:Z[Z.length-(Ve||1)].first_line,last_line:Z[Z.length-1].last_line,first_column:Z[Z.length-(Ve||1)].first_column,last_column:Z[Z.length-1].last_column},de&&(_e._$.range=[Z[Z.length-(Ve||1)].range[0],Z[Z.length-1].range[1]]),Pe=this.performAction.apply(_e,[ce,Oe,ae,Ie.yy,pe[1],ue,Z].concat($e)),typeof Pe<"u")return Pe;Ve&&(J=J.slice(0,-1*Ve*2),ue=ue.slice(0,-1*Ve),Z=Z.slice(0,-1*Ve)),J.push(this.productions_[pe[1]][0]),ue.push(_e.$),Z.push(_e._$),De=Se[J[J.length-2]][J[J.length-1]],J.push(De);break;case 3:return!0}}return!0},"parse")},le=function(){var K={EOF:1,parseError:o(function(te,J){if(this.yy.parser)this.yy.parser.parseError(te,J);else throw new Error(te)},"parseError"),setInput:o(function(X,te){return this.yy=te||this.yy||{},this._input=X,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var X=this._input[0];this.yytext+=X,this.yyleng++,this.offset++,this.match+=X,this.matched+=X;var te=X.match(/(?:\r\n?|\n).*/g);return te?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),X},"input"),unput:o(function(X){var te=X.length,J=X.split(/(?:\r\n?|\n)/g);this._input=X+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-te),this.offset-=te;var se=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),J.length-1&&(this.yylineno-=J.length-1);var ue=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:J?(J.length===se.length?this.yylloc.first_column:0)+se[se.length-J.length].length-J[0].length:this.yylloc.first_column-te},this.options.ranges&&(this.yylloc.range=[ue[0],ue[0]+this.yyleng-te]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(X){this.unput(this.match.slice(X))},"less"),pastInput:o(function(){var X=this.matched.substr(0,this.matched.length-this.match.length);return(X.length>20?"...":"")+X.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var X=this.match;return X.length<20&&(X+=this._input.substr(0,20-X.length)),(X.substr(0,20)+(X.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var X=this.pastInput(),te=new Array(X.length+1).join("-");return X+this.upcomingInput()+`
+`+te+"^"},"showPosition"),test_match:o(function(X,te){var J,se,ue;if(this.options.backtrack_lexer&&(ue={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(ue.yylloc.range=this.yylloc.range.slice(0))),se=X[0].match(/(?:\r\n?|\n).*/g),se&&(this.yylineno+=se.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:se?se[se.length-1].length-se[se.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+X[0].length},this.yytext+=X[0],this.match+=X[0],this.matches=X,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(X[0].length),this.matched+=X[0],J=this.performAction.call(this,this.yy,this,te,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),J)return J;if(this._backtrack){for(var Z in ue)this[Z]=ue[Z];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var X,te,J,se;this._more||(this.yytext="",this.match="");for(var ue=this._currentRules(),Z=0;Z<ue.length;Z++)if(J=this._input.match(this.rules[ue[Z]]),J&&(!te||J[0].length>te[0].length)){if(te=J,se=Z,this.options.backtrack_lexer){if(X=this.test_match(J,ue[Z]),X!==!1)return X;if(this._backtrack){te=!1;continue}else return!1}else if(!this.options.flex)break}return te?(X=this.test_match(te,ue[se]),X!==!1?X:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var te=this.next();return te||this.lex()},"lex"),begin:o(function(te){this.conditionStack.push(te)},"begin"),popState:o(function(){var te=this.conditionStack.length-1;return te>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(te){return te=this.conditionStack.length-1-Math.abs(te||0),te>=0?this.conditionStack[te]:"INITIAL"},"topState"),pushState:o(function(te){this.begin(te)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(te,J,se,ue){var Z=ue;switch(se){case 0:return 5;case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;break;case 8:return this.begin("ID"),50;break;case 9:return this.begin("ID"),52;break;case 10:return 13;case 11:return this.begin("ID"),53;break;case 12:return J.yytext=J.yytext.trim(),this.begin("ALIAS"),70;break;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;break;case 14:return this.popState(),this.popState(),5;break;case 15:return this.begin("LINE"),36;break;case 16:return this.begin("LINE"),37;break;case 17:return this.begin("LINE"),38;break;case 18:return this.begin("LINE"),39;break;case 19:return this.begin("LINE"),49;break;case 20:return this.begin("LINE"),41;break;case 21:return this.begin("LINE"),43;break;case 22:return this.begin("LINE"),48;break;case 23:return this.begin("LINE"),44;break;case 24:return this.begin("LINE"),47;break;case 25:return this.begin("LINE"),46;break;case 26:return this.popState(),15;break;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;break;case 37:return this.begin("ID"),23;break;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;break;case 41:return this.popState(),"acc_title_value";break;case 42:return this.begin("acc_descr"),33;break;case 43:return this.popState(),"acc_descr_value";break;case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 51:return 5;case 52:return J.yytext=J.yytext.trim(),70;break;case 53:return 73;case 54:return 74;case 55:return 75;case 56:return 76;case 57:return 71;case 58:return 72;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 80;case 63:return 81;case 64:return 68;case 65:return 69;case 66:return 5;case 67:return"INVALID"}},"anonymous"),rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\<->\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\<->\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:<<->>)/i,/^(?:-->>)/i,/^(?:<<-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67],inclusive:!0}}};return K}();ne.lexer=le;function he(){this.yy={}}return o(he,"Parser"),he.prototype=ne,ne.Parser=he,new he}();CO.parser=CO;lfe=CO});var iVe,aVe,sVe,_6,ufe=N(()=>{"use strict";zt();vt();s6();gr();mi();iVe={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32,BIDIRECTIONAL_SOLID:33,BIDIRECTIONAL_DOTTED:34},aVe={FILLED:0,OPEN:1},sVe={LEFTOF:0,RIGHTOF:1,OVER:2},_6=class{constructor(){this.state=new pf(()=>({prevActor:void 0,actors:new Map,createdActors:new Map,destroyedActors:new Map,boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0}));this.setAccTitle=Lr;this.setAccDescription=Nr;this.setDiagramTitle=$r;this.getAccTitle=Rr;this.getAccDescription=Mr;this.getDiagramTitle=Ir;this.apply=this.apply.bind(this),this.parseBoxData=this.parseBoxData.bind(this),this.parseMessage=this.parseMessage.bind(this),this.clear(),this.setWrap(me().wrap),this.LINETYPE=iVe,this.ARROWTYPE=aVe,this.PLACEMENT=sVe}static{o(this,"SequenceDB")}addBox(e){this.state.records.boxes.push({name:e.text,wrap:e.wrap??this.autoWrap(),fill:e.color,actorKeys:[]}),this.state.records.currentBox=this.state.records.boxes.slice(-1)[0]}addActor(e,r,n,i){let a=this.state.records.currentBox,s=this.state.records.actors.get(e);if(s){if(this.state.records.currentBox&&s.box&&this.state.records.currentBox!==s.box)throw new Error(`A same participant should only be defined in one Box: ${s.name} can't be in '${s.box.name}' and in '${this.state.records.currentBox.name}' at the same time.`);if(a=s.box?s.box:this.state.records.currentBox,s.box=a,s&&r===s.name&&n==null)return}if(n?.text==null&&(n={text:r,type:i}),(i==null||n.text==null)&&(n={text:r,type:i}),this.state.records.actors.set(e,{box:a,name:r,description:n.text,wrap:n.wrap??this.autoWrap(),prevActor:this.state.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:i??"participant"}),this.state.records.prevActor){let l=this.state.records.actors.get(this.state.records.prevActor);l&&(l.nextActor=e)}this.state.records.currentBox&&this.state.records.currentBox.actorKeys.push(e),this.state.records.prevActor=e}activationCount(e){let r,n=0;if(!e)return 0;for(r=0;r<this.state.records.messages.length;r++)this.state.records.messages[r].type===this.LINETYPE.ACTIVE_START&&this.state.records.messages[r].from===e&&n++,this.state.records.messages[r].type===this.LINETYPE.ACTIVE_END&&this.state.records.messages[r].from===e&&n--;return n}addMessage(e,r,n,i){this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:e,to:r,message:n.text,wrap:n.wrap??this.autoWrap(),answer:i})}addSignal(e,r,n,i,a=!1){if(i===this.LINETYPE.ACTIVE_END&&this.activationCount(e??"")<1){let l=new Error("Trying to inactivate an inactive participant ("+e+")");throw l.hash={text:"->>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},l}return this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:e,to:r,message:n?.text??"",wrap:n?.wrap??this.autoWrap(),type:i,activate:a}),!0}hasAtLeastOneBox(){return this.state.records.boxes.length>0}hasAtLeastOneBoxWithTitle(){return this.state.records.boxes.some(e=>e.name)}getMessages(){return this.state.records.messages}getBoxes(){return this.state.records.boxes}getActors(){return this.state.records.actors}getCreatedActors(){return this.state.records.createdActors}getDestroyedActors(){return this.state.records.destroyedActors}getActor(e){return this.state.records.actors.get(e)}getActorKeys(){return[...this.state.records.actors.keys()]}enableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!0}disableSequenceNumbers(){this.state.records.sequenceNumbersEnabled=!1}showSequenceNumbers(){return this.state.records.sequenceNumbersEnabled}setWrap(e){this.state.records.wrapEnabled=e}extractWrap(e){if(e===void 0)return{};e=e.trim();let r=/^:?wrap:/.exec(e)!==null?!0:/^:?nowrap:/.exec(e)!==null?!1:void 0;return{cleanedText:(r===void 0?e:e.replace(/^:?(?:no)?wrap:/,"")).trim(),wrap:r}}autoWrap(){return this.state.records.wrapEnabled!==void 0?this.state.records.wrapEnabled:me().sequence?.wrap??!1}clear(){this.state.reset(),Ar()}parseMessage(e){let r=e.trim(),{wrap:n,cleanedText:i}=this.extractWrap(r),a={text:i,wrap:n};return Y.debug(`parseMessage: ${JSON.stringify(a)}`),a}parseBoxData(e){let r=/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(e),n=r?.[1]?r[1].trim():"transparent",i=r?.[2]?r[2].trim():void 0;if(window?.CSS)window.CSS.supports("color",n)||(n="transparent",i=e.trim());else{let l=new Option().style;l.color=n,l.color!==n&&(n="transparent",i=e.trim())}let{wrap:a,cleanedText:s}=this.extractWrap(i);return{text:s?Tr(s,me()):void 0,color:n,wrap:a}}addNote(e,r,n){let i={actor:e,placement:r,message:n.text,wrap:n.wrap??this.autoWrap()},a=[].concat(e,e);this.state.records.notes.push(i),this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:a[0],to:a[1],message:n.text,wrap:n.wrap??this.autoWrap(),type:this.LINETYPE.NOTE,placement:r})}addLinks(e,r){let n=this.getActor(e);try{let i=Tr(r.text,me());i=i.replace(/&equals;/g,"="),i=i.replace(/&amp;/g,"&");let a=JSON.parse(i);this.insertLinks(n,a)}catch(i){Y.error("error while parsing actor link text",i)}}addALink(e,r){let n=this.getActor(e);try{let i={},a=Tr(r.text,me()),s=a.indexOf("@");a=a.replace(/&equals;/g,"="),a=a.replace(/&amp;/g,"&");let l=a.slice(0,s-1).trim(),u=a.slice(s+1).trim();i[l]=u,this.insertLinks(n,i)}catch(i){Y.error("error while parsing actor link text",i)}}insertLinks(e,r){if(e.links==null)e.links=r;else for(let n in r)e.links[n]=r[n]}addProperties(e,r){let n=this.getActor(e);try{let i=Tr(r.text,me()),a=JSON.parse(i);this.insertProperties(n,a)}catch(i){Y.error("error while parsing actor properties text",i)}}insertProperties(e,r){if(e.properties==null)e.properties=r;else for(let n in r)e.properties[n]=r[n]}boxEnd(){this.state.records.currentBox=void 0}addDetails(e,r){let n=this.getActor(e),i=document.getElementById(r.text);try{let a=i.innerHTML,s=JSON.parse(a);s.properties&&this.insertProperties(n,s.properties),s.links&&this.insertLinks(n,s.links)}catch(a){Y.error("error while parsing actor details text",a)}}getActorProperty(e,r){if(e?.properties!==void 0)return e.properties[r]}apply(e){if(Array.isArray(e))e.forEach(r=>{this.apply(r)});else switch(e.type){case"sequenceIndex":this.state.records.messages.push({id:this.state.records.messages.length.toString(),from:void 0,to:void 0,message:{start:e.sequenceIndex,step:e.sequenceIndexStep,visible:e.sequenceVisible},wrap:!1,type:e.signalType});break;case"addParticipant":this.addActor(e.actor,e.actor,e.description,e.draw);break;case"createParticipant":if(this.state.records.actors.has(e.actor))throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");this.state.records.lastCreated=e.actor,this.addActor(e.actor,e.actor,e.description,e.draw),this.state.records.createdActors.set(e.actor,this.state.records.messages.length);break;case"destroyParticipant":this.state.records.lastDestroyed=e.actor,this.state.records.destroyedActors.set(e.actor,this.state.records.messages.length);break;case"activeStart":this.addSignal(e.actor,void 0,void 0,e.signalType);break;case"activeEnd":this.addSignal(e.actor,void 0,void 0,e.signalType);break;case"addNote":this.addNote(e.actor,e.placement,e.text);break;case"addLinks":this.addLinks(e.actor,e.text);break;case"addALink":this.addALink(e.actor,e.text);break;case"addProperties":this.addProperties(e.actor,e.text);break;case"addDetails":this.addDetails(e.actor,e.text);break;case"addMessage":if(this.state.records.lastCreated){if(e.to!==this.state.records.lastCreated)throw new Error("The created participant "+this.state.records.lastCreated.name+" does not have an associated creating message after its declaration. Please check the sequence diagram.");this.state.records.lastCreated=void 0}else if(this.state.records.lastDestroyed){if(e.to!==this.state.records.lastDestroyed&&e.from!==this.state.records.lastDestroyed)throw new Error("The destroyed participant "+this.state.records.lastDestroyed.name+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");this.state.records.lastDestroyed=void 0}this.addSignal(e.from,e.to,e.msg,e.signalType,e.activate);break;case"boxStart":this.addBox(e.boxData);break;case"boxEnd":this.boxEnd();break;case"loopStart":this.addSignal(void 0,void 0,e.loopText,e.signalType);break;case"loopEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"rectStart":this.addSignal(void 0,void 0,e.color,e.signalType);break;case"rectEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"optStart":this.addSignal(void 0,void 0,e.optText,e.signalType);break;case"optEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"altStart":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"else":this.addSignal(void 0,void 0,e.altText,e.signalType);break;case"altEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"setAccTitle":Lr(e.text);break;case"parStart":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"and":this.addSignal(void 0,void 0,e.parText,e.signalType);break;case"parEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"criticalStart":this.addSignal(void 0,void 0,e.criticalText,e.signalType);break;case"option":this.addSignal(void 0,void 0,e.optionText,e.signalType);break;case"criticalEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break;case"breakStart":this.addSignal(void 0,void 0,e.breakText,e.signalType);break;case"breakEnd":this.addSignal(void 0,void 0,void 0,e.signalType);break}}getConfig(){return me().sequence}}});var oVe,hfe,ffe=N(()=>{"use strict";oVe=o(t=>`.actor {
+ stroke: ${t.actorBorder};
+ fill: ${t.actorBkg};
+ }
+
+ text.actor > tspan {
+ fill: ${t.actorTextColor};
+ stroke: none;
+ }
+
+ .actor-line {
+ stroke: ${t.actorLineColor};
+ }
+
+ .messageLine0 {
+ stroke-width: 1.5;
+ stroke-dasharray: none;
+ stroke: ${t.signalColor};
+ }
+
+ .messageLine1 {
+ stroke-width: 1.5;
+ stroke-dasharray: 2, 2;
+ stroke: ${t.signalColor};
+ }
+
+ #arrowhead path {
+ fill: ${t.signalColor};
+ stroke: ${t.signalColor};
+ }
+
+ .sequenceNumber {
+ fill: ${t.sequenceNumberColor};
+ }
+
+ #sequencenumber {
+ fill: ${t.signalColor};
+ }
+
+ #crosshead path {
+ fill: ${t.signalColor};
+ stroke: ${t.signalColor};
+ }
+
+ .messageText {
+ fill: ${t.signalTextColor};
+ stroke: none;
+ }
+
+ .labelBox {
+ stroke: ${t.labelBoxBorderColor};
+ fill: ${t.labelBoxBkgColor};
+ }
+
+ .labelText, .labelText > tspan {
+ fill: ${t.labelTextColor};
+ stroke: none;
+ }
+
+ .loopText, .loopText > tspan {
+ fill: ${t.loopTextColor};
+ stroke: none;
+ }
+
+ .loopLine {
+ stroke-width: 2px;
+ stroke-dasharray: 2, 2;
+ stroke: ${t.labelBoxBorderColor};
+ fill: ${t.labelBoxBorderColor};
+ }
+
+ .note {
+ //stroke: #decc93;
+ stroke: ${t.noteBorderColor};
+ fill: ${t.noteBkgColor};
+ }
+
+ .noteText, .noteText > tspan {
+ fill: ${t.noteTextColor};
+ stroke: none;
+ }
+
+ .activation0 {
+ fill: ${t.activationBkgColor};
+ stroke: ${t.activationBorderColor};
+ }
+
+ .activation1 {
+ fill: ${t.activationBkgColor};
+ stroke: ${t.activationBorderColor};
+ }
+
+ .activation2 {
+ fill: ${t.activationBkgColor};
+ stroke: ${t.activationBorderColor};
+ }
+
+ .actorPopupMenu {
+ position: absolute;
+ }
+
+ .actorPopupMenuPanel {
+ position: absolute;
+ fill: ${t.actorBkg};
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+ filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));
+}
+ .actor-man line {
+ stroke: ${t.actorBorder};
+ fill: ${t.actorBkg};
+ }
+ .actor-man circle, line {
+ stroke: ${t.actorBorder};
+ fill: ${t.actorBkg};
+ stroke-width: 2px;
+ }
+`,"getStyles"),hfe=oVe});var AO,vf,pfe,mfe,lVe,dfe,_O,cVe,uVe,Tb,_p,gfe,Uc,DO,hVe,fVe,dVe,pVe,mVe,gVe,yVe,yfe,vVe,xVe,bVe,wVe,TVe,kVe,EVe,vfe,SVe,LO,CVe,hi,xfe=N(()=>{"use strict";gr();Wv();ir();AO=Sa(z0(),1);ji();vf=18*2,pfe="actor-top",mfe="actor-bottom",lVe="actor-box",dfe="actor-man",_O=o(function(t,e){return kd(t,e)},"drawRect"),cVe=o(function(t,e,r,n,i){if(e.links===void 0||e.links===null||Object.keys(e.links).length===0)return{height:0,width:0};let a=e.links,s=e.actorCnt,l=e.rectData;var u="none";i&&(u="block !important");let h=t.append("g");h.attr("id","actor"+s+"_popup"),h.attr("class","actorPopupMenu"),h.attr("display",u);var f="";l.class!==void 0&&(f=" "+l.class);let d=l.width>r?l.width:r,p=h.append("rect");if(p.attr("class","actorPopupMenuPanel"+f),p.attr("x",l.x),p.attr("y",l.height),p.attr("fill",l.fill),p.attr("stroke",l.stroke),p.attr("width",d),p.attr("height",l.height),p.attr("rx",l.rx),p.attr("ry",l.ry),a!=null){var m=20;for(let v in a){var g=h.append("a"),y=(0,AO.sanitizeUrl)(a[v]);g.attr("xlink:href",y),g.attr("target","_blank"),CVe(n)(v,g,l.x+10,l.height+m,d,20,{class:"actor"},n),m+=30}}return p.attr("height",m),{height:l.height+m,width:d}},"drawPopup"),uVe=o(function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"},"popupMenuToggle"),Tb=o(async function(t,e,r=null){let n=t.append("foreignObject"),i=await mh(e.text,cr()),s=n.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(i).node().getBoundingClientRect();if(n.attr("height",Math.round(s.height)).attr("width",Math.round(s.width)),e.class==="noteText"){let l=t.node().firstChild;l.setAttribute("height",s.height+2*e.textMargin);let u=l.getBBox();n.attr("x",Math.round(u.x+u.width/2-s.width/2)).attr("y",Math.round(u.y+u.height/2-s.height/2))}else if(r){let{startx:l,stopx:u,starty:h}=r;if(l>u){let f=l;l=u,u=f}n.attr("x",Math.round(l+Math.abs(l-u)/2-s.width/2)),e.class==="loopText"?n.attr("y",Math.round(h)):n.attr("y",Math.round(h-s.height))}return[n]},"drawKatex"),_p=o(function(t,e){let r=0,n=0,i=e.text.split(Ze.lineBreakRegex),[a,s]=Bo(e.fontSize),l=[],u=0,h=o(()=>e.y,"yfunc");if(e.valign!==void 0&&e.textMargin!==void 0&&e.textMargin>0)switch(e.valign){case"top":case"start":h=o(()=>Math.round(e.y+e.textMargin),"yfunc");break;case"middle":case"center":h=o(()=>Math.round(e.y+(r+n+e.textMargin)/2),"yfunc");break;case"bottom":case"end":h=o(()=>Math.round(e.y+(r+n+2*e.textMargin)-e.textMargin),"yfunc");break}if(e.anchor!==void 0&&e.textMargin!==void 0&&e.width!==void 0)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle";break}for(let[f,d]of i.entries()){e.textMargin!==void 0&&e.textMargin===0&&a!==void 0&&(u=f*a);let p=t.append("text");p.attr("x",e.x),p.attr("y",h()),e.anchor!==void 0&&p.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),e.fontFamily!==void 0&&p.style("font-family",e.fontFamily),s!==void 0&&p.style("font-size",s),e.fontWeight!==void 0&&p.style("font-weight",e.fontWeight),e.fill!==void 0&&p.attr("fill",e.fill),e.class!==void 0&&p.attr("class",e.class),e.dy!==void 0?p.attr("dy",e.dy):u!==0&&p.attr("dy",u);let m=d||H9;if(e.tspan){let g=p.append("tspan");g.attr("x",e.x),e.fill!==void 0&&g.attr("fill",e.fill),g.text(m)}else p.text(m);e.valign!==void 0&&e.textMargin!==void 0&&e.textMargin>0&&(n+=(p._groups||p)[0][0].getBBox().height,r=n),l.push(p)}return l},"drawText"),gfe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");return n.attr("points",r(e.x,e.y,e.width,e.height,7)),n.attr("class","labelBox"),e.y=e.y+e.height/2,_p(t,e),n},"drawLabel"),Uc=-1,DO=o((t,e,r,n)=>{t.select&&r.forEach(i=>{let a=e.get(i),s=t.select("#actor"+a.actorCnt);!n.mirrorActors&&a.stopy?s.attr("y2",a.stopy+a.height/2):n.mirrorActors&&s.attr("y2",a.stopy)})},"fixLifeLineHeights"),hVe=o(function(t,e,r,n){let i=n?e.stopy:e.starty,a=e.x+e.width/2,s=i+e.height,l=t.append("g").lower();var u=l;n||(Uc++,Object.keys(e.links||{}).length&&!r.forceMenus&&u.attr("onclick",uVe(`actor${Uc}_popup`)).attr("cursor","pointer"),u.append("line").attr("id","actor"+Uc).attr("x1",a).attr("y1",s).attr("x2",a).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),u=l.append("g"),e.actorCnt=Uc,e.links!=null&&u.attr("id","root-"+Uc));let h=Tl();var f="actor";e.properties?.class?f=e.properties.class:h.fill="#eaeaea",n?f+=` ${mfe}`:f+=` ${pfe}`,h.x=e.x,h.y=i,h.width=e.width,h.height=e.height,h.class=f,h.rx=3,h.ry=3,h.name=e.name;let d=_O(u,h);if(e.rectData=h,e.properties?.icon){let m=e.properties.icon.trim();m.charAt(0)==="@"?Iq(u,h.x+h.width-20,h.y+10,m.substr(1)):Mq(u,h.x+h.width-20,h.y+10,m)}LO(r,pi(e.description))(e.description,u,h.x,h.y,h.width,h.height,{class:`actor ${lVe}`},r);let p=e.height;if(d.node){let m=d.node().getBBox();e.height=m.height,p=m.height}return p},"drawActorTypeParticipant"),fVe=o(function(t,e,r,n){let i=n?e.stopy:e.starty,a=e.x+e.width/2,s=i+80,l=t.append("g").lower();n||(Uc++,l.append("line").attr("id","actor"+Uc).attr("x1",a).attr("y1",s).attr("x2",a).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=Uc);let u=t.append("g"),h=dfe;n?h+=` ${mfe}`:h+=` ${pfe}`,u.attr("class",h),u.attr("name",e.name);let f=Tl();f.x=e.x,f.y=i,f.fill="#eaeaea",f.width=e.width,f.height=e.height,f.class="actor",f.rx=3,f.ry=3,u.append("line").attr("id","actor-man-torso"+Uc).attr("x1",a).attr("y1",i+25).attr("x2",a).attr("y2",i+45),u.append("line").attr("id","actor-man-arms"+Uc).attr("x1",a-vf/2).attr("y1",i+33).attr("x2",a+vf/2).attr("y2",i+33),u.append("line").attr("x1",a-vf/2).attr("y1",i+60).attr("x2",a).attr("y2",i+45),u.append("line").attr("x1",a).attr("y1",i+45).attr("x2",a+vf/2-2).attr("y2",i+60);let d=u.append("circle");d.attr("cx",e.x+e.width/2),d.attr("cy",i+10),d.attr("r",15),d.attr("width",e.width),d.attr("height",e.height);let p=u.node().getBBox();return e.height=p.height,LO(r,pi(e.description))(e.description,u,f.x,f.y+35,f.width,f.height,{class:`actor ${dfe}`},r),e.height},"drawActorTypeActor"),dVe=o(async function(t,e,r,n){switch(e.type){case"actor":return await fVe(t,e,r,n);case"participant":return await hVe(t,e,r,n)}},"drawActor"),pVe=o(function(t,e,r){let i=t.append("g");yfe(i,e),e.name&&LO(r)(e.name,i,e.x,e.y+(e.textMaxHeight||0)/2,e.width,0,{class:"text"},r),i.lower()},"drawBox"),mVe=o(function(t){return t.append("g")},"anchorElement"),gVe=o(function(t,e,r,n,i){let a=Tl(),s=e.anchored;a.x=e.startx,a.y=e.starty,a.class="activation"+i%3,a.width=e.stopx-e.startx,a.height=r-e.starty,_O(s,a)},"drawActivation"),yVe=o(async function(t,e,r,n){let{boxMargin:i,boxTextMargin:a,labelBoxHeight:s,labelBoxWidth:l,messageFontFamily:u,messageFontSize:h,messageFontWeight:f}=n,d=t.append("g"),p=o(function(y,v,x,b){return d.append("line").attr("x1",y).attr("y1",v).attr("x2",x).attr("y2",b).attr("class","loopLine")},"drawLoopLine");p(e.startx,e.starty,e.stopx,e.starty),p(e.stopx,e.starty,e.stopx,e.stopy),p(e.startx,e.stopy,e.stopx,e.stopy),p(e.startx,e.starty,e.startx,e.stopy),e.sections!==void 0&&e.sections.forEach(function(y){p(e.startx,y.y,e.stopx,y.y).style("stroke-dasharray","3, 3")});let m=Hv();m.text=r,m.x=e.startx,m.y=e.starty,m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.anchor="middle",m.valign="middle",m.tspan=!1,m.width=l||50,m.height=s||20,m.textMargin=a,m.class="labelText",gfe(d,m),m=vfe(),m.text=e.title,m.x=e.startx+l/2+(e.stopx-e.startx)/2,m.y=e.starty+i+a,m.anchor="middle",m.valign="middle",m.textMargin=a,m.class="loopText",m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.wrap=!0;let g=pi(m.text)?await Tb(d,m,e):_p(d,m);if(e.sectionTitles!==void 0){for(let[y,v]of Object.entries(e.sectionTitles))if(v.message){m.text=v.message,m.x=e.startx+(e.stopx-e.startx)/2,m.y=e.sections[y].y+i+a,m.class="loopText",m.anchor="middle",m.valign="middle",m.tspan=!1,m.fontFamily=u,m.fontSize=h,m.fontWeight=f,m.wrap=e.wrap,pi(m.text)?(e.starty=e.sections[y].y,await Tb(d,m,e)):_p(d,m);let x=Math.round(g.map(b=>(b._groups||b)[0][0].getBBox().height).reduce((b,w)=>b+w));e.sections[y].height+=x-(i+a)}}return e.height=Math.round(e.stopy-e.starty),d},"drawLoop"),yfe=o(function(t,e){q5(t,e)},"drawBackgroundRect"),vVe=o(function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},"insertDatabaseIcon"),xVe=o(function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},"insertComputerIcon"),bVe=o(function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},"insertClockIcon"),wVe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto-start-reverse").append("path").attr("d","M -1 0 L 10 5 L 0 10 z")},"insertArrowHead"),TVe=o(function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"insertArrowFilledHead"),kVe=o(function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},"insertSequenceNumber"),EVe=o(function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},"insertArrowCrossHead"),vfe=o(function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},"getTextObj"),SVe=o(function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),LO=function(){function t(a,s,l,u,h,f,d){let p=s.append("text").attr("x",l+h/2).attr("y",u+f/2+5).style("text-anchor","middle").text(a);i(p,d)}o(t,"byText");function e(a,s,l,u,h,f,d,p){let{actorFontSize:m,actorFontFamily:g,actorFontWeight:y}=p,[v,x]=Bo(m),b=a.split(Ze.lineBreakRegex);for(let w=0;w<b.length;w++){let C=w*v-v*(b.length-1)/2,T=s.append("text").attr("x",l+h/2).attr("y",u).style("text-anchor","middle").style("font-size",x).style("font-weight",y).style("font-family",g);T.append("tspan").attr("x",l+h/2).attr("dy",C).text(b[w]),T.attr("y",u+f/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(T,d)}}o(e,"byTspan");function r(a,s,l,u,h,f,d,p){let m=s.append("switch"),y=m.append("foreignObject").attr("x",l).attr("y",u).attr("width",h).attr("height",f).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");y.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(a),e(a,m,l,u,h,f,d,p),i(y,d)}o(r,"byFo");async function n(a,s,l,u,h,f,d,p){let m=await id(a,cr()),g=s.append("switch"),v=g.append("foreignObject").attr("x",l+h/2-m.width/2).attr("y",u+f/2-m.height/2).attr("width",m.width).attr("height",m.height).append("xhtml:div").style("height","100%").style("width","100%");v.append("div").style("text-align","center").style("vertical-align","middle").html(await mh(a,cr())),e(a,g,l,u,h,f,d,p),i(v,d)}o(n,"byKatex");function i(a,s){for(let l in s)s.hasOwnProperty(l)&&a.attr(l,s[l])}return o(i,"_setTextAttrs"),function(a,s=!1){return s?n:a.textPlacement==="fo"?r:a.textPlacement==="old"?t:e}}(),CVe=function(){function t(i,a,s,l,u,h,f){let d=a.append("text").attr("x",s).attr("y",l).style("text-anchor","start").text(i);n(d,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d){let{actorFontSize:p,actorFontFamily:m,actorFontWeight:g}=d,y=i.split(Ze.lineBreakRegex);for(let v=0;v<y.length;v++){let x=v*p-p*(y.length-1)/2,b=a.append("text").attr("x",s).attr("y",l).style("text-anchor","start").style("font-size",p).style("font-weight",g).style("font-family",m);b.append("tspan").attr("x",s).attr("dy",x).text(y[v]),b.attr("y",l+h/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),n(b,f)}}o(e,"byTspan");function r(i,a,s,l,u,h,f,d){let p=a.append("switch"),g=p.append("foreignObject").attr("x",s).attr("y",l).attr("width",u).attr("height",h).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");g.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(i),e(i,p,s,l,u,h,f,d),n(g,f)}o(r,"byFo");function n(i,a){for(let s in a)a.hasOwnProperty(s)&&i.attr(s,a[s])}return o(n,"_setTextAttrs"),function(i){return i.textPlacement==="fo"?r:i.textPlacement==="old"?t:e}}(),hi={drawRect:_O,drawText:_p,drawLabel:gfe,drawActor:dVe,drawBox:pVe,drawPopup:cVe,anchorElement:mVe,drawActivation:gVe,drawLoop:yVe,drawBackgroundRect:yfe,insertArrowHead:wVe,insertArrowFilledHead:TVe,insertSequenceNumber:kVe,insertArrowCrossHead:EVe,insertDatabaseIcon:vVe,insertComputerIcon:xVe,insertClockIcon:bVe,getTextObj:vfe,getNoteRect:SVe,fixLifeLineHeights:DO,sanitizeUrl:AO.sanitizeUrl}});async function _Ve(t,e){rt.bumpVerticalPos(10);let{startx:r,stopx:n,message:i}=e,a=Ze.splitBreaks(i).length,s=pi(i),l=s?await id(i,me()):Gt.calculateTextDimensions(i,Dp(Ne));if(!s){let d=l.height/a;e.height+=d,rt.bumpVerticalPos(d)}let u,h=l.height-10,f=l.width;if(r===n){u=rt.getVerticalPos()+h,Ne.rightAngles||(h+=Ne.boxMargin,u=rt.getVerticalPos()+h),h+=30;let d=Ze.getMax(f/2,Ne.width/2);rt.insert(r-d,rt.getVerticalPos()-10+h,n+d,rt.getVerticalPos()+30+h)}else h+=Ne.boxMargin,u=rt.getVerticalPos()+h,rt.insert(r,u-10,n,u);return rt.bumpVerticalPos(h),e.height+=h,e.stopy=e.starty+e.height,rt.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),u}function Hc(t,e,r,n,i){rt.bumpVerticalPos(r);let a=n;if(e.id&&e.message&&t[e.id]){let s=t[e.id].width,l=Dp(Ne);e.message=Gt.wrapLabel(`[${e.message}]`,s-2*Ne.wrapPadding,l),e.width=s,e.wrap=!0;let u=Gt.calculateTextDimensions(e.message,l),h=Ze.getMax(u.height,Ne.labelBoxHeight);a=n+h,Y.debug(`${h} - ${e.message}`)}i(e),rt.bumpVerticalPos(a)}function RVe(t,e,r,n,i,a,s){function l(h,f){h.x<i.get(t.from).x?(rt.insert(e.stopx-f,e.starty,e.startx,e.stopy+h.height/2+Ne.noteMargin),e.stopx=e.stopx+f):(rt.insert(e.startx,e.starty,e.stopx+f,e.stopy+h.height/2+Ne.noteMargin),e.stopx=e.stopx-f)}o(l,"receiverAdjustment");function u(h,f){h.x<i.get(t.to).x?(rt.insert(e.startx-f,e.starty,e.stopx,e.stopy+h.height/2+Ne.noteMargin),e.startx=e.startx+f):(rt.insert(e.stopx,e.starty,e.startx+f,e.stopy+h.height/2+Ne.noteMargin),e.startx=e.startx-f)}if(o(u,"senderAdjustment"),a.get(t.to)==n){let h=i.get(t.to),f=h.type=="actor"?vf/2+3:h.width/2+3;l(h,f),h.starty=r-h.height/2,rt.bumpVerticalPos(h.height/2)}else if(s.get(t.from)==n){let h=i.get(t.from);if(Ne.mirrorActors){let f=h.type=="actor"?vf/2:h.width/2;u(h,f)}h.stopy=r-h.height/2,rt.bumpVerticalPos(h.height/2)}else if(s.get(t.to)==n){let h=i.get(t.to);if(Ne.mirrorActors){let f=h.type=="actor"?vf/2+3:h.width/2+3;l(h,f)}h.stopy=r-h.height/2,rt.bumpVerticalPos(h.height/2)}}async function MVe(t,e,r){let n={};for(let i of e)if(t.get(i.to)&&t.get(i.from)){let a=t.get(i.to);if(i.placement===r.db.PLACEMENT.LEFTOF&&!a.prevActor||i.placement===r.db.PLACEMENT.RIGHTOF&&!a.nextActor)continue;let s=i.placement!==void 0,l=!s,u=s?_1(Ne):Dp(Ne),h=i.wrap?Gt.wrapLabel(i.message,Ne.width-2*Ne.wrapPadding,u):i.message,d=(pi(h)?await id(i.message,me()):Gt.calculateTextDimensions(h,u)).width+2*Ne.wrapPadding;l&&i.from===a.nextActor?n[i.to]=Ze.getMax(n[i.to]||0,d):l&&i.from===a.prevActor?n[i.from]=Ze.getMax(n[i.from]||0,d):l&&i.from===i.to?(n[i.from]=Ze.getMax(n[i.from]||0,d/2),n[i.to]=Ze.getMax(n[i.to]||0,d/2)):i.placement===r.db.PLACEMENT.RIGHTOF?n[i.from]=Ze.getMax(n[i.from]||0,d):i.placement===r.db.PLACEMENT.LEFTOF?n[a.prevActor]=Ze.getMax(n[a.prevActor]||0,d):i.placement===r.db.PLACEMENT.OVER&&(a.prevActor&&(n[a.prevActor]=Ze.getMax(n[a.prevActor]||0,d/2)),a.nextActor&&(n[i.from]=Ze.getMax(n[i.from]||0,d/2)))}return Y.debug("maxMessageWidthPerActor:",n),n}async function OVe(t,e,r){let n=0;for(let a of t.keys()){let s=t.get(a);s.wrap&&(s.description=Gt.wrapLabel(s.description,Ne.width-2*Ne.wrapPadding,RO(Ne)));let l=pi(s.description)?await id(s.description,me()):Gt.calculateTextDimensions(s.description,RO(Ne));s.width=s.wrap?Ne.width:Ze.getMax(Ne.width,l.width+2*Ne.wrapPadding),s.height=s.wrap?Ze.getMax(l.height,Ne.height):Ne.height,n=Ze.getMax(n,s.height)}for(let a in e){let s=t.get(a);if(!s)continue;let l=t.get(s.nextActor);if(!l){let d=e[a]+Ne.actorMargin-s.width/2;s.margin=Ze.getMax(d,Ne.actorMargin);continue}let h=e[a]+Ne.actorMargin-s.width/2-l.width/2;s.margin=Ze.getMax(h,Ne.actorMargin)}let i=0;return r.forEach(a=>{let s=Dp(Ne),l=a.actorKeys.reduce((f,d)=>f+=t.get(d).width+(t.get(d).margin||0),0);l-=2*Ne.boxTextMargin,a.wrap&&(a.name=Gt.wrapLabel(a.name,l-2*Ne.wrapPadding,s));let u=Gt.calculateTextDimensions(a.name,s);i=Ze.getMax(u.height,i);let h=Ze.getMax(l,u.width+2*Ne.wrapPadding);if(a.margin=Ne.boxTextMargin,l<h){let f=(h-l)/2;a.margin+=f}}),r.forEach(a=>a.textMaxHeight=i),Ze.getMax(n,Ne.height)}var Ne,rt,AVe,Dp,_1,RO,DVe,LVe,NO,wfe,Tfe,D6,bfe,NVe,IVe,PVe,BVe,FVe,kfe,Efe=N(()=>{"use strict";dr();xfe();vt();gr();Wv();zt();s0();ir();Ei();Ne={},rt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:o(function(){return Math.max.apply(null,this.actors.length===0?[0]:this.actors.map(t=>t.height||0))+(this.loops.length===0?0:this.loops.map(t=>t.height||0).reduce((t,e)=>t+e))+(this.messages.length===0?0:this.messages.map(t=>t.height||0).reduce((t,e)=>t+e))+(this.notes.length===0?0:this.notes.map(t=>t.height||0).reduce((t,e)=>t+e))},"getHeight"),clear:o(function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},"clear"),addBox:o(function(t){this.boxes.push(t)},"addBox"),addActor:o(function(t){this.actors.push(t)},"addActor"),addLoop:o(function(t){this.loops.push(t)},"addLoop"),addMessage:o(function(t){this.messages.push(t)},"addMessage"),addNote:o(function(t){this.notes.push(t)},"addNote"),lastActor:o(function(){return this.actors[this.actors.length-1]},"lastActor"),lastLoop:o(function(){return this.loops[this.loops.length-1]},"lastLoop"),lastMessage:o(function(){return this.messages[this.messages.length-1]},"lastMessage"),lastNote:o(function(){return this.notes[this.notes.length-1]},"lastNote"),actors:[],boxes:[],loops:[],messages:[],notes:[]},init:o(function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,Tfe(me())},"init"),updateVal:o(function(t,e,r,n){t[e]===void 0?t[e]=r:t[e]=n(r,t[e])},"updateVal"),updateBounds:o(function(t,e,r,n){let i=this,a=0;function s(l){return o(function(h){a++;let f=i.sequenceItems.length-a+1;i.updateVal(h,"starty",e-f*Ne.boxMargin,Math.min),i.updateVal(h,"stopy",n+f*Ne.boxMargin,Math.max),i.updateVal(rt.data,"startx",t-f*Ne.boxMargin,Math.min),i.updateVal(rt.data,"stopx",r+f*Ne.boxMargin,Math.max),l!=="activation"&&(i.updateVal(h,"startx",t-f*Ne.boxMargin,Math.min),i.updateVal(h,"stopx",r+f*Ne.boxMargin,Math.max),i.updateVal(rt.data,"starty",e-f*Ne.boxMargin,Math.min),i.updateVal(rt.data,"stopy",n+f*Ne.boxMargin,Math.max))},"updateItemBounds")}o(s,"updateFn"),this.sequenceItems.forEach(s()),this.activations.forEach(s("activation"))},"updateBounds"),insert:o(function(t,e,r,n){let i=Ze.getMin(t,r),a=Ze.getMax(t,r),s=Ze.getMin(e,n),l=Ze.getMax(e,n);this.updateVal(rt.data,"startx",i,Math.min),this.updateVal(rt.data,"starty",s,Math.min),this.updateVal(rt.data,"stopx",a,Math.max),this.updateVal(rt.data,"stopy",l,Math.max),this.updateBounds(i,s,a,l)},"insert"),newActivation:o(function(t,e,r){let n=r.get(t.from),i=D6(t.from).length||0,a=n.x+n.width/2+(i-1)*Ne.activationWidth/2;this.activations.push({startx:a,starty:this.verticalPos+2,stopx:a+Ne.activationWidth,stopy:void 0,actor:t.from,anchored:hi.anchorElement(e)})},"newActivation"),endActivation:o(function(t){let e=this.activations.map(function(r){return r.actor}).lastIndexOf(t.from);return this.activations.splice(e,1)[0]},"endActivation"),createLoop:o(function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},"createLoop"),newLoop:o(function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},"newLoop"),endLoop:o(function(){return this.sequenceItems.pop()},"endLoop"),isLoopOverlap:o(function(){return this.sequenceItems.length?this.sequenceItems[this.sequenceItems.length-1].overlap:!1},"isLoopOverlap"),addSectionToLoop:o(function(t){let e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:rt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},"addSectionToLoop"),saveVerticalPos:o(function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},"saveVerticalPos"),resetVerticalPos:o(function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},"resetVerticalPos"),bumpVerticalPos:o(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=Ze.getMax(this.data.stopy,this.verticalPos)},"bumpVerticalPos"),getVerticalPos:o(function(){return this.verticalPos},"getVerticalPos"),getBounds:o(function(){return{bounds:this.data,models:this.models}},"getBounds")},AVe=o(async function(t,e){rt.bumpVerticalPos(Ne.boxMargin),e.height=Ne.boxMargin,e.starty=rt.getVerticalPos();let r=Tl();r.x=e.startx,r.y=e.starty,r.width=e.width||Ne.width,r.class="note";let n=t.append("g"),i=hi.drawRect(n,r),a=Hv();a.x=e.startx,a.y=e.starty,a.width=r.width,a.dy="1em",a.text=e.message,a.class="noteText",a.fontFamily=Ne.noteFontFamily,a.fontSize=Ne.noteFontSize,a.fontWeight=Ne.noteFontWeight,a.anchor=Ne.noteAlign,a.textMargin=Ne.noteMargin,a.valign="center";let s=pi(a.text)?await Tb(n,a):_p(n,a),l=Math.round(s.map(u=>(u._groups||u)[0][0].getBBox().height).reduce((u,h)=>u+h));i.attr("height",l+2*Ne.noteMargin),e.height+=l+2*Ne.noteMargin,rt.bumpVerticalPos(l+2*Ne.noteMargin),e.stopy=e.starty+l+2*Ne.noteMargin,e.stopx=e.startx+r.width,rt.insert(e.startx,e.starty,e.stopx,e.stopy),rt.models.addNote(e)},"drawNote"),Dp=o(t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),"messageFont"),_1=o(t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),"noteFont"),RO=o(t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight}),"actorFont");o(_Ve,"boundMessage");DVe=o(async function(t,e,r,n){let{startx:i,stopx:a,starty:s,message:l,type:u,sequenceIndex:h,sequenceVisible:f}=e,d=Gt.calculateTextDimensions(l,Dp(Ne)),p=Hv();p.x=i,p.y=s+10,p.width=a-i,p.class="messageText",p.dy="1em",p.text=l,p.fontFamily=Ne.messageFontFamily,p.fontSize=Ne.messageFontSize,p.fontWeight=Ne.messageFontWeight,p.anchor=Ne.messageAlign,p.valign="center",p.textMargin=Ne.wrapPadding,p.tspan=!1,pi(p.text)?await Tb(t,p,{startx:i,stopx:a,starty:r}):_p(t,p);let m=d.width,g;i===a?Ne.rightAngles?g=t.append("path").attr("d",`M ${i},${r} H ${i+Ze.getMax(Ne.width/2,m/2)} V ${r+25} H ${i}`):g=t.append("path").attr("d","M "+i+","+r+" C "+(i+60)+","+(r-10)+" "+(i+60)+","+(r+30)+" "+i+","+(r+20)):(g=t.append("line"),g.attr("x1",i),g.attr("y1",r),g.attr("x2",a),g.attr("y2",r)),u===n.db.LINETYPE.DOTTED||u===n.db.LINETYPE.DOTTED_CROSS||u===n.db.LINETYPE.DOTTED_POINT||u===n.db.LINETYPE.DOTTED_OPEN||u===n.db.LINETYPE.BIDIRECTIONAL_DOTTED?(g.style("stroke-dasharray","3, 3"),g.attr("class","messageLine1")):g.attr("class","messageLine0");let y="";Ne.arrowMarkerAbsolute&&(y=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,y=y.replace(/\(/g,"\\("),y=y.replace(/\)/g,"\\)")),g.attr("stroke-width",2),g.attr("stroke","none"),g.style("fill","none"),(u===n.db.LINETYPE.SOLID||u===n.db.LINETYPE.DOTTED)&&g.attr("marker-end","url("+y+"#arrowhead)"),(u===n.db.LINETYPE.BIDIRECTIONAL_SOLID||u===n.db.LINETYPE.BIDIRECTIONAL_DOTTED)&&(g.attr("marker-start","url("+y+"#arrowhead)"),g.attr("marker-end","url("+y+"#arrowhead)")),(u===n.db.LINETYPE.SOLID_POINT||u===n.db.LINETYPE.DOTTED_POINT)&&g.attr("marker-end","url("+y+"#filled-head)"),(u===n.db.LINETYPE.SOLID_CROSS||u===n.db.LINETYPE.DOTTED_CROSS)&&g.attr("marker-end","url("+y+"#crosshead)"),(f||Ne.showSequenceNumbers)&&(g.attr("marker-start","url("+y+"#sequencenumber)"),t.append("text").attr("x",i).attr("y",r+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(h))},"drawMessage"),LVe=o(function(t,e,r,n,i,a,s){let l=0,u=0,h,f=0;for(let d of n){let p=e.get(d),m=p.box;h&&h!=m&&(s||rt.models.addBox(h),u+=Ne.boxMargin+h.margin),m&&m!=h&&(s||(m.x=l+u,m.y=i),u+=m.margin),p.width=p.width||Ne.width,p.height=Ze.getMax(p.height||Ne.height,Ne.height),p.margin=p.margin||Ne.actorMargin,f=Ze.getMax(f,p.height),r.get(p.name)&&(u+=p.width/2),p.x=l+u,p.starty=rt.getVerticalPos(),rt.insert(p.x,i,p.x+p.width,p.height),l+=p.width+u,p.box&&(p.box.width=l+m.margin-p.box.x),u=p.margin,h=p.box,rt.models.addActor(p)}h&&!s&&rt.models.addBox(h),rt.bumpVerticalPos(f)},"addActorRenderingData"),NO=o(async function(t,e,r,n){if(n){let i=0;rt.bumpVerticalPos(Ne.boxMargin*2);for(let a of r){let s=e.get(a);s.stopy||(s.stopy=rt.getVerticalPos());let l=await hi.drawActor(t,s,Ne,!0);i=Ze.getMax(i,l)}rt.bumpVerticalPos(i+Ne.boxMargin)}else for(let i of r){let a=e.get(i);await hi.drawActor(t,a,Ne,!1)}},"drawActors"),wfe=o(function(t,e,r,n){let i=0,a=0;for(let s of r){let l=e.get(s),u=IVe(l),h=hi.drawPopup(t,l,u,Ne,Ne.forceMenus,n);h.height>i&&(i=h.height),h.width+l.x>a&&(a=h.width+l.x)}return{maxHeight:i,maxWidth:a}},"drawActorsPopup"),Tfe=o(function(t){Gn(Ne,t),t.fontFamily&&(Ne.actorFontFamily=Ne.noteFontFamily=Ne.messageFontFamily=t.fontFamily),t.fontSize&&(Ne.actorFontSize=Ne.noteFontSize=Ne.messageFontSize=t.fontSize),t.fontWeight&&(Ne.actorFontWeight=Ne.noteFontWeight=Ne.messageFontWeight=t.fontWeight)},"setConf"),D6=o(function(t){return rt.activations.filter(function(e){return e.actor===t})},"actorActivations"),bfe=o(function(t,e){let r=e.get(t),n=D6(t),i=n.reduce(function(s,l){return Ze.getMin(s,l.startx)},r.x+r.width/2-1),a=n.reduce(function(s,l){return Ze.getMax(s,l.stopx)},r.x+r.width/2+1);return[i,a]},"activationBounds");o(Hc,"adjustLoopHeightForWrap");o(RVe,"adjustCreatedDestroyedData");NVe=o(async function(t,e,r,n){let{securityLevel:i,sequence:a}=me();Ne=a;let s;i==="sandbox"&&(s=Ge("#i"+e));let l=i==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body"),u=i==="sandbox"?s.nodes()[0].contentDocument:document;rt.init(),Y.debug(n.db);let h=i==="sandbox"?l.select(`[id="${e}"]`):Ge(`[id="${e}"]`),f=n.db.getActors(),d=n.db.getCreatedActors(),p=n.db.getDestroyedActors(),m=n.db.getBoxes(),g=n.db.getActorKeys(),y=n.db.getMessages(),v=n.db.getDiagramTitle(),x=n.db.hasAtLeastOneBox(),b=n.db.hasAtLeastOneBoxWithTitle(),w=await MVe(f,y,n);if(Ne.height=await OVe(f,w,m),hi.insertComputerIcon(h),hi.insertDatabaseIcon(h),hi.insertClockIcon(h),x&&(rt.bumpVerticalPos(Ne.boxMargin),b&&rt.bumpVerticalPos(m[0].textMaxHeight)),Ne.hideUnusedParticipants===!0){let F=new Set;y.forEach(P=>{F.add(P.from),F.add(P.to)}),g=g.filter(P=>F.has(P))}LVe(h,f,d,g,0,y,!1);let C=await FVe(y,f,w,n);hi.insertArrowHead(h),hi.insertArrowCrossHead(h),hi.insertArrowFilledHead(h),hi.insertSequenceNumber(h);function T(F,P){let z=rt.endActivation(F);z.starty+18>P&&(z.starty=P-6,P+=12),hi.drawActivation(h,z,P,Ne,D6(F.from).length),rt.insert(z.startx,P-10,z.stopx,P)}o(T,"activeEnd");let E=1,A=1,S=[],_=[],I=0;for(let F of y){let P,z,$;switch(F.type){case n.db.LINETYPE.NOTE:rt.resetVerticalPos(),z=F.noteModel,await AVe(h,z);break;case n.db.LINETYPE.ACTIVE_START:rt.newActivation(F,h,f);break;case n.db.LINETYPE.ACTIVE_END:T(F,rt.getVerticalPos());break;case n.db.LINETYPE.LOOP_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,H=>rt.newLoop(H));break;case n.db.LINETYPE.LOOP_END:P=rt.endLoop(),await hi.drawLoop(h,P,"loop",Ne),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos()),rt.models.addLoop(P);break;case n.db.LINETYPE.RECT_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin,H=>rt.newLoop(void 0,H.message));break;case n.db.LINETYPE.RECT_END:P=rt.endLoop(),_.push(P),rt.models.addLoop(P),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos());break;case n.db.LINETYPE.OPT_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,H=>rt.newLoop(H));break;case n.db.LINETYPE.OPT_END:P=rt.endLoop(),await hi.drawLoop(h,P,"opt",Ne),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos()),rt.models.addLoop(P);break;case n.db.LINETYPE.ALT_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,H=>rt.newLoop(H));break;case n.db.LINETYPE.ALT_ELSE:Hc(C,F,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,H=>rt.addSectionToLoop(H));break;case n.db.LINETYPE.ALT_END:P=rt.endLoop(),await hi.drawLoop(h,P,"alt",Ne),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos()),rt.models.addLoop(P);break;case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,H=>rt.newLoop(H)),rt.saveVerticalPos();break;case n.db.LINETYPE.PAR_AND:Hc(C,F,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,H=>rt.addSectionToLoop(H));break;case n.db.LINETYPE.PAR_END:P=rt.endLoop(),await hi.drawLoop(h,P,"par",Ne),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos()),rt.models.addLoop(P);break;case n.db.LINETYPE.AUTONUMBER:E=F.message.start||E,A=F.message.step||A,F.message.visible?n.db.enableSequenceNumbers():n.db.disableSequenceNumbers();break;case n.db.LINETYPE.CRITICAL_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,H=>rt.newLoop(H));break;case n.db.LINETYPE.CRITICAL_OPTION:Hc(C,F,Ne.boxMargin+Ne.boxTextMargin,Ne.boxMargin,H=>rt.addSectionToLoop(H));break;case n.db.LINETYPE.CRITICAL_END:P=rt.endLoop(),await hi.drawLoop(h,P,"critical",Ne),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos()),rt.models.addLoop(P);break;case n.db.LINETYPE.BREAK_START:Hc(C,F,Ne.boxMargin,Ne.boxMargin+Ne.boxTextMargin,H=>rt.newLoop(H));break;case n.db.LINETYPE.BREAK_END:P=rt.endLoop(),await hi.drawLoop(h,P,"break",Ne),rt.bumpVerticalPos(P.stopy-rt.getVerticalPos()),rt.models.addLoop(P);break;default:try{$=F.msgModel,$.starty=rt.getVerticalPos(),$.sequenceIndex=E,$.sequenceVisible=n.db.showSequenceNumbers();let H=await _Ve(h,$);RVe(F,$,H,I,f,d,p),S.push({messageModel:$,lineStartY:H}),rt.models.addMessage($)}catch(H){Y.error("error while drawing message",H)}}[n.db.LINETYPE.SOLID_OPEN,n.db.LINETYPE.DOTTED_OPEN,n.db.LINETYPE.SOLID,n.db.LINETYPE.DOTTED,n.db.LINETYPE.SOLID_CROSS,n.db.LINETYPE.DOTTED_CROSS,n.db.LINETYPE.SOLID_POINT,n.db.LINETYPE.DOTTED_POINT,n.db.LINETYPE.BIDIRECTIONAL_SOLID,n.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(F.type)&&(E=E+A),I++}Y.debug("createdActors",d),Y.debug("destroyedActors",p),await NO(h,f,g,!1);for(let F of S)await DVe(h,F.messageModel,F.lineStartY,n);Ne.mirrorActors&&await NO(h,f,g,!0),_.forEach(F=>hi.drawBackgroundRect(h,F)),DO(h,f,g,Ne);for(let F of rt.models.boxes)F.height=rt.getVerticalPos()-F.y,rt.insert(F.x,F.y,F.x+F.width,F.height),F.startx=F.x,F.starty=F.y,F.stopx=F.startx+F.width,F.stopy=F.starty+F.height,F.stroke="rgb(0,0,0, 0.5)",hi.drawBox(h,F,Ne);x&&rt.bumpVerticalPos(Ne.boxMargin);let D=wfe(h,f,g,u),{bounds:k}=rt.getBounds();k.startx===void 0&&(k.startx=0),k.starty===void 0&&(k.starty=0),k.stopx===void 0&&(k.stopx=0),k.stopy===void 0&&(k.stopy=0);let L=k.stopy-k.starty;L<D.maxHeight&&(L=D.maxHeight);let R=L+2*Ne.diagramMarginY;Ne.mirrorActors&&(R=R-Ne.boxMargin+Ne.bottomMarginAdj);let O=k.stopx-k.startx;O<D.maxWidth&&(O=D.maxWidth);let M=O+2*Ne.diagramMarginX;v&&h.append("text").text(v).attr("x",(k.stopx-k.startx)/2-2*Ne.diagramMarginX).attr("y",-25),vn(h,R,M,Ne.useMaxWidth);let B=v?40:0;h.attr("viewBox",k.startx-Ne.diagramMarginX+" -"+(Ne.diagramMarginY+B)+" "+M+" "+(R+B)),Y.debug("models:",rt.models)},"draw");o(MVe,"getMaxMessageWidthPerActor");IVe=o(function(t){let e=0,r=RO(Ne);for(let n in t.links){let a=Gt.calculateTextDimensions(n,r).width+2*Ne.wrapPadding+2*Ne.boxMargin;e<a&&(e=a)}return e},"getRequiredPopupWidth");o(OVe,"calculateActorMargins");PVe=o(async function(t,e,r){let n=e.get(t.from),i=e.get(t.to),a=n.x,s=i.x,l=t.wrap&&t.message,u=pi(t.message)?await id(t.message,me()):Gt.calculateTextDimensions(l?Gt.wrapLabel(t.message,Ne.width,_1(Ne)):t.message,_1(Ne)),h={width:l?Ne.width:Ze.getMax(Ne.width,u.width+2*Ne.noteMargin),height:0,startx:n.x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===r.db.PLACEMENT.RIGHTOF?(h.width=l?Ze.getMax(Ne.width,u.width):Ze.getMax(n.width/2+i.width/2,u.width+2*Ne.noteMargin),h.startx=a+(n.width+Ne.actorMargin)/2):t.placement===r.db.PLACEMENT.LEFTOF?(h.width=l?Ze.getMax(Ne.width,u.width+2*Ne.noteMargin):Ze.getMax(n.width/2+i.width/2,u.width+2*Ne.noteMargin),h.startx=a-h.width+(n.width-Ne.actorMargin)/2):t.to===t.from?(u=Gt.calculateTextDimensions(l?Gt.wrapLabel(t.message,Ze.getMax(Ne.width,n.width),_1(Ne)):t.message,_1(Ne)),h.width=l?Ze.getMax(Ne.width,n.width):Ze.getMax(n.width,Ne.width,u.width+2*Ne.noteMargin),h.startx=a+(n.width-h.width)/2):(h.width=Math.abs(a+n.width/2-(s+i.width/2))+Ne.actorMargin,h.startx=a<s?a+n.width/2-Ne.actorMargin/2:s+i.width/2-Ne.actorMargin/2),l&&(h.message=Gt.wrapLabel(t.message,h.width-2*Ne.wrapPadding,_1(Ne))),Y.debug(`NM:[${h.startx},${h.stopx},${h.starty},${h.stopy}:${h.width},${h.height}=${t.message}]`),h},"buildNoteModel"),BVe=o(function(t,e,r){if(![r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN,r.db.LINETYPE.SOLID,r.db.LINETYPE.DOTTED,r.db.LINETYPE.SOLID_CROSS,r.db.LINETYPE.DOTTED_CROSS,r.db.LINETYPE.SOLID_POINT,r.db.LINETYPE.DOTTED_POINT,r.db.LINETYPE.BIDIRECTIONAL_SOLID,r.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type))return{};let[n,i]=bfe(t.from,e),[a,s]=bfe(t.to,e),l=n<=a,u=l?i:n,h=l?a:s,f=Math.abs(a-s)>2,d=o(y=>l?-y:y,"adjustValue");t.from===t.to?h=u:(t.activate&&!f&&(h+=d(Ne.activationWidth/2-1)),[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(h+=d(3)),[r.db.LINETYPE.BIDIRECTIONAL_SOLID,r.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type)&&(u-=d(3)));let p=[n,i,a,s],m=Math.abs(u-h);t.wrap&&t.message&&(t.message=Gt.wrapLabel(t.message,Ze.getMax(m+2*Ne.wrapPadding,Ne.width),Dp(Ne)));let g=Gt.calculateTextDimensions(t.message,Dp(Ne));return{width:Ze.getMax(t.wrap?0:g.width+2*Ne.wrapPadding,m+2*Ne.wrapPadding,Ne.width),height:0,startx:u,stopx:h,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,p),toBounds:Math.max.apply(null,p)}},"buildMessageModel"),FVe=o(async function(t,e,r,n){let i={},a=[],s,l,u;for(let h of t){switch(h.type){case n.db.LINETYPE.LOOP_START:case n.db.LINETYPE.ALT_START:case n.db.LINETYPE.OPT_START:case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:case n.db.LINETYPE.CRITICAL_START:case n.db.LINETYPE.BREAK_START:a.push({id:h.id,msg:h.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case n.db.LINETYPE.ALT_ELSE:case n.db.LINETYPE.PAR_AND:case n.db.LINETYPE.CRITICAL_OPTION:h.message&&(s=a.pop(),i[s.id]=s,i[h.id]=s,a.push(s));break;case n.db.LINETYPE.LOOP_END:case n.db.LINETYPE.ALT_END:case n.db.LINETYPE.OPT_END:case n.db.LINETYPE.PAR_END:case n.db.LINETYPE.CRITICAL_END:case n.db.LINETYPE.BREAK_END:s=a.pop(),i[s.id]=s;break;case n.db.LINETYPE.ACTIVE_START:{let d=e.get(h.from?h.from:h.to.actor),p=D6(h.from?h.from:h.to.actor).length,m=d.x+d.width/2+(p-1)*Ne.activationWidth/2,g={startx:m,stopx:m+Ne.activationWidth,actor:h.from,enabled:!0};rt.activations.push(g)}break;case n.db.LINETYPE.ACTIVE_END:{let d=rt.activations.map(p=>p.actor).lastIndexOf(h.from);rt.activations.splice(d,1).splice(0,1)}break}h.placement!==void 0?(l=await PVe(h,e,n),h.noteModel=l,a.forEach(d=>{s=d,s.from=Ze.getMin(s.from,l.startx),s.to=Ze.getMax(s.to,l.startx+l.width),s.width=Ze.getMax(s.width,Math.abs(s.from-s.to))-Ne.labelBoxWidth})):(u=BVe(h,e,n),h.msgModel=u,u.startx&&u.stopx&&a.length>0&&a.forEach(d=>{if(s=d,u.startx===u.stopx){let p=e.get(h.from),m=e.get(h.to);s.from=Ze.getMin(p.x-u.width/2,p.x-p.width/2,s.from),s.to=Ze.getMax(m.x+u.width/2,m.x+p.width/2,s.to),s.width=Ze.getMax(s.width,Math.abs(s.to-s.from))-Ne.labelBoxWidth}else s.from=Ze.getMin(u.startx,s.from),s.to=Ze.getMax(u.stopx,s.to),s.width=Ze.getMax(s.width,u.width)-Ne.labelBoxWidth}))}return rt.activations=[],Y.debug("Loop type widths:",i),i},"calculateLoopBounds"),kfe={bounds:rt,drawActors:NO,drawActorsPopup:wfe,setConf:Tfe,draw:NVe}});var Sfe={};hr(Sfe,{diagram:()=>$Ve});var $Ve,Cfe=N(()=>{"use strict";cfe();ufe();ffe();zt();Efe();$Ve={parser:lfe,get db(){return new _6},renderer:kfe,styles:hfe,init:o(t=>{t.sequence||(t.sequence={}),t.wrap&&(t.sequence.wrap=t.wrap,Yy({sequence:{wrap:t.wrap}}))},"init")}});var MO,L6,IO=N(()=>{"use strict";MO=function(){var t=o(function(Ie,be,W,de){for(W=W||{},de=Ie.length;de--;W[Ie[de]]=be);return W},"o"),e=[1,18],r=[1,19],n=[1,20],i=[1,41],a=[1,42],s=[1,26],l=[1,24],u=[1,25],h=[1,32],f=[1,33],d=[1,34],p=[1,45],m=[1,35],g=[1,36],y=[1,37],v=[1,38],x=[1,27],b=[1,28],w=[1,29],C=[1,30],T=[1,31],E=[1,44],A=[1,46],S=[1,43],_=[1,47],I=[1,9],D=[1,8,9],k=[1,58],L=[1,59],R=[1,60],O=[1,61],M=[1,62],B=[1,63],F=[1,64],P=[1,8,9,41],z=[1,76],$=[1,8,9,12,13,22,39,41,44,66,67,68,69,70,71,72,77,79],H=[1,8,9,12,13,17,20,22,39,41,44,48,58,66,67,68,69,70,71,72,77,79,84,99,101,102],Q=[13,58,84,99,101,102],j=[13,58,71,72,84,99,101,102],ie=[13,58,66,67,68,69,70,84,99,101,102],ne=[1,98],le=[1,115],he=[1,107],K=[1,113],X=[1,108],te=[1,109],J=[1,110],se=[1,111],ue=[1,112],Z=[1,114],Se=[22,58,59,80,84,85,86,87,88,89],ce=[1,8,9,39,41,44],ae=[1,8,9,22],Oe=[1,143],ge=[1,8,9,59],ze=[1,8,9,22,58,59,80,84,85,86,87,88,89],He={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,DOT:17,className:18,classLiteralName:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,CLASS:46,ANNOTATION_START:47,ANNOTATION_END:48,MEMBER:49,SEPARATOR:50,relation:51,NOTE_FOR:52,noteText:53,NOTE:54,CLASSDEF:55,classList:56,stylesOpt:57,ALPHA:58,COMMA:59,direction_tb:60,direction_bt:61,direction_rl:62,direction_lr:63,relationType:64,lineType:65,AGGREGATION:66,EXTENSION:67,COMPOSITION:68,DEPENDENCY:69,LOLLIPOP:70,LINE:71,DOTTED_LINE:72,CALLBACK:73,LINK:74,LINK_TARGET:75,CLICK:76,CALLBACK_NAME:77,CALLBACK_ARGS:78,HREF:79,STYLE:80,CSSCLASS:81,style:82,styleComponent:83,NUM:84,COLON:85,UNIT:86,SPACE:87,BRKT:88,PCT:89,commentToken:90,textToken:91,graphCodeTokens:92,textNoTagsToken:93,TAGSTART:94,TAGEND:95,"==":96,"--":97,DEFAULT:98,MINUS:99,keywords:100,UNICODE_TEXT:101,BQUOTE_STR:102,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",17:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"CLASS",47:"ANNOTATION_START",48:"ANNOTATION_END",49:"MEMBER",50:"SEPARATOR",52:"NOTE_FOR",54:"NOTE",55:"CLASSDEF",58:"ALPHA",59:"COMMA",60:"direction_tb",61:"direction_bt",62:"direction_rl",63:"direction_lr",66:"AGGREGATION",67:"EXTENSION",68:"COMPOSITION",69:"DEPENDENCY",70:"LOLLIPOP",71:"LINE",72:"DOTTED_LINE",73:"CALLBACK",74:"LINK",75:"LINK_TARGET",76:"CLICK",77:"CALLBACK_NAME",78:"CALLBACK_ARGS",79:"HREF",80:"STYLE",81:"CSSCLASS",84:"NUM",85:"COLON",86:"UNIT",87:"SPACE",88:"BRKT",89:"PCT",92:"graphCodeTokens",94:"TAGSTART",95:"TAGEND",96:"==",97:"--",98:"DEFAULT",99:"MINUS",100:"keywords",101:"UNICODE_TEXT",102:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,3],[15,2],[18,1],[18,3],[18,1],[18,2],[18,2],[18,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,6],[43,2],[43,3],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[56,1],[56,3],[32,1],[32,1],[32,1],[32,1],[51,3],[51,2],[51,2],[51,1],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[57,1],[57,3],[82,1],[82,2],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[90,1],[90,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[93,1],[93,1],[93,1],[93,1],[16,1],[16,1],[16,1],[16,1],[19,1],[53,1]],performAction:o(function(be,W,de,re,oe,V,xe){var q=V.length-1;switch(oe){case 8:this.$=V[q-1];break;case 9:case 12:case 14:this.$=V[q];break;case 10:case 13:this.$=V[q-2]+"."+V[q];break;case 11:case 15:this.$=V[q-1]+V[q];break;case 16:case 17:this.$=V[q-1]+"~"+V[q]+"~";break;case 18:re.addRelation(V[q]);break;case 19:V[q-1].title=re.cleanupLabel(V[q]),re.addRelation(V[q-1]);break;case 30:this.$=V[q].trim(),re.setAccTitle(this.$);break;case 31:case 32:this.$=V[q].trim(),re.setAccDescription(this.$);break;case 33:re.addClassesToNamespace(V[q-3],V[q-1]);break;case 34:re.addClassesToNamespace(V[q-4],V[q-1]);break;case 35:this.$=V[q],re.addNamespace(V[q]);break;case 36:this.$=[V[q]];break;case 37:this.$=[V[q-1]];break;case 38:V[q].unshift(V[q-2]),this.$=V[q];break;case 40:re.setCssClass(V[q-2],V[q]);break;case 41:re.addMembers(V[q-3],V[q-1]);break;case 42:re.setCssClass(V[q-5],V[q-3]),re.addMembers(V[q-5],V[q-1]);break;case 43:this.$=V[q],re.addClass(V[q]);break;case 44:this.$=V[q-1],re.addClass(V[q-1]),re.setClassLabel(V[q-1],V[q]);break;case 45:re.addAnnotation(V[q],V[q-2]);break;case 46:case 59:this.$=[V[q]];break;case 47:V[q].push(V[q-1]),this.$=V[q];break;case 48:break;case 49:re.addMember(V[q-1],re.cleanupLabel(V[q]));break;case 50:break;case 51:break;case 52:this.$={id1:V[q-2],id2:V[q],relation:V[q-1],relationTitle1:"none",relationTitle2:"none"};break;case 53:this.$={id1:V[q-3],id2:V[q],relation:V[q-1],relationTitle1:V[q-2],relationTitle2:"none"};break;case 54:this.$={id1:V[q-3],id2:V[q],relation:V[q-2],relationTitle1:"none",relationTitle2:V[q-1]};break;case 55:this.$={id1:V[q-4],id2:V[q],relation:V[q-2],relationTitle1:V[q-3],relationTitle2:V[q-1]};break;case 56:re.addNote(V[q],V[q-1]);break;case 57:re.addNote(V[q]);break;case 58:this.$=V[q-2],re.defineClass(V[q-1],V[q]);break;case 60:this.$=V[q-2].concat([V[q]]);break;case 61:re.setDirection("TB");break;case 62:re.setDirection("BT");break;case 63:re.setDirection("RL");break;case 64:re.setDirection("LR");break;case 65:this.$={type1:V[q-2],type2:V[q],lineType:V[q-1]};break;case 66:this.$={type1:"none",type2:V[q],lineType:V[q-1]};break;case 67:this.$={type1:V[q-1],type2:"none",lineType:V[q]};break;case 68:this.$={type1:"none",type2:"none",lineType:V[q]};break;case 69:this.$=re.relationType.AGGREGATION;break;case 70:this.$=re.relationType.EXTENSION;break;case 71:this.$=re.relationType.COMPOSITION;break;case 72:this.$=re.relationType.DEPENDENCY;break;case 73:this.$=re.relationType.LOLLIPOP;break;case 74:this.$=re.lineType.LINE;break;case 75:this.$=re.lineType.DOTTED_LINE;break;case 76:case 82:this.$=V[q-2],re.setClickEvent(V[q-1],V[q]);break;case 77:case 83:this.$=V[q-3],re.setClickEvent(V[q-2],V[q-1]),re.setTooltip(V[q-2],V[q]);break;case 78:this.$=V[q-2],re.setLink(V[q-1],V[q]);break;case 79:this.$=V[q-3],re.setLink(V[q-2],V[q-1],V[q]);break;case 80:this.$=V[q-3],re.setLink(V[q-2],V[q-1]),re.setTooltip(V[q-2],V[q]);break;case 81:this.$=V[q-4],re.setLink(V[q-3],V[q-2],V[q]),re.setTooltip(V[q-3],V[q-1]);break;case 84:this.$=V[q-3],re.setClickEvent(V[q-2],V[q-1],V[q]);break;case 85:this.$=V[q-4],re.setClickEvent(V[q-3],V[q-2],V[q-1]),re.setTooltip(V[q-3],V[q]);break;case 86:this.$=V[q-3],re.setLink(V[q-2],V[q]);break;case 87:this.$=V[q-4],re.setLink(V[q-3],V[q-1],V[q]);break;case 88:this.$=V[q-4],re.setLink(V[q-3],V[q-1]),re.setTooltip(V[q-3],V[q]);break;case 89:this.$=V[q-5],re.setLink(V[q-4],V[q-2],V[q]),re.setTooltip(V[q-4],V[q-1]);break;case 90:this.$=V[q-2],re.setCssStyle(V[q-1],V[q]);break;case 91:re.setCssClass(V[q-1],V[q]);break;case 92:this.$=[V[q]];break;case 93:V[q-2].push(V[q]),this.$=V[q-2];break;case 95:this.$=V[q-1]+V[q];break}},"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:r,37:n,38:22,42:i,43:23,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:w,80:C,81:T,84:E,99:A,101:S,102:_},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(I,[2,5],{8:[1,48]}),{8:[1,49]},t(D,[2,18],{22:[1,50]}),t(D,[2,20]),t(D,[2,21]),t(D,[2,22]),t(D,[2,23]),t(D,[2,24]),t(D,[2,25]),t(D,[2,26]),t(D,[2,27]),t(D,[2,28]),t(D,[2,29]),{34:[1,51]},{36:[1,52]},t(D,[2,32]),t(D,[2,48],{51:53,64:56,65:57,13:[1,54],22:[1,55],66:k,67:L,68:R,69:O,70:M,71:B,72:F}),{39:[1,65]},t(P,[2,39],{39:[1,67],44:[1,66]}),t(D,[2,50]),t(D,[2,51]),{16:68,58:p,84:E,99:A,101:S},{16:39,18:69,19:40,58:p,84:E,99:A,101:S,102:_},{16:39,18:70,19:40,58:p,84:E,99:A,101:S,102:_},{16:39,18:71,19:40,58:p,84:E,99:A,101:S,102:_},{58:[1,72]},{13:[1,73]},{16:39,18:74,19:40,58:p,84:E,99:A,101:S,102:_},{13:z,53:75},{56:77,58:[1,78]},t(D,[2,61]),t(D,[2,62]),t(D,[2,63]),t(D,[2,64]),t($,[2,12],{16:39,19:40,18:80,17:[1,79],20:[1,81],58:p,84:E,99:A,101:S,102:_}),t($,[2,14],{20:[1,82]}),{15:83,16:84,58:p,84:E,99:A,101:S},{16:39,18:85,19:40,58:p,84:E,99:A,101:S,102:_},t(H,[2,118]),t(H,[2,119]),t(H,[2,120]),t(H,[2,121]),t([1,8,9,12,13,20,22,39,41,44,66,67,68,69,70,71,72,77,79],[2,122]),t(I,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,18:21,38:22,43:23,16:39,19:40,5:86,33:e,35:r,37:n,42:i,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:w,80:C,81:T,84:E,99:A,101:S,102:_}),{5:87,10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:r,37:n,38:22,42:i,43:23,46:a,47:s,49:l,50:u,52:h,54:f,55:d,58:p,60:m,61:g,62:y,63:v,73:x,74:b,76:w,80:C,81:T,84:E,99:A,101:S,102:_},t(D,[2,19]),t(D,[2,30]),t(D,[2,31]),{13:[1,89],16:39,18:88,19:40,58:p,84:E,99:A,101:S,102:_},{51:90,64:56,65:57,66:k,67:L,68:R,69:O,70:M,71:B,72:F},t(D,[2,49]),{65:91,71:B,72:F},t(Q,[2,68],{64:92,66:k,67:L,68:R,69:O,70:M}),t(j,[2,69]),t(j,[2,70]),t(j,[2,71]),t(j,[2,72]),t(j,[2,73]),t(ie,[2,74]),t(ie,[2,75]),{8:[1,94],24:95,40:93,43:23,46:a},{16:96,58:p,84:E,99:A,101:S},{45:97,49:ne},{48:[1,99]},{13:[1,100]},{13:[1,101]},{77:[1,102],79:[1,103]},{22:le,57:104,58:he,80:K,82:105,83:106,84:X,85:te,86:J,87:se,88:ue,89:Z},{58:[1,116]},{13:z,53:117},t(D,[2,57]),t(D,[2,123]),{22:le,57:118,58:he,59:[1,119],80:K,82:105,83:106,84:X,85:te,86:J,87:se,88:ue,89:Z},t(Se,[2,59]),{16:39,18:120,19:40,58:p,84:E,99:A,101:S,102:_},t($,[2,15]),t($,[2,16]),t($,[2,17]),{39:[2,35]},{15:122,16:84,17:[1,121],39:[2,9],58:p,84:E,99:A,101:S},t(ce,[2,43],{11:123,12:[1,124]}),t(I,[2,7]),{9:[1,125]},t(ae,[2,52]),{16:39,18:126,19:40,58:p,84:E,99:A,101:S,102:_},{13:[1,128],16:39,18:127,19:40,58:p,84:E,99:A,101:S,102:_},t(Q,[2,67],{64:129,66:k,67:L,68:R,69:O,70:M}),t(Q,[2,66]),{41:[1,130]},{24:95,40:131,43:23,46:a},{8:[1,132],41:[2,36]},t(P,[2,40],{39:[1,133]}),{41:[1,134]},{41:[2,46],45:135,49:ne},{16:39,18:136,19:40,58:p,84:E,99:A,101:S,102:_},t(D,[2,76],{13:[1,137]}),t(D,[2,78],{13:[1,139],75:[1,138]}),t(D,[2,82],{13:[1,140],78:[1,141]}),{13:[1,142]},t(D,[2,90],{59:Oe}),t(ge,[2,92],{83:144,22:le,58:he,80:K,84:X,85:te,86:J,87:se,88:ue,89:Z}),t(ze,[2,94]),t(ze,[2,96]),t(ze,[2,97]),t(ze,[2,98]),t(ze,[2,99]),t(ze,[2,100]),t(ze,[2,101]),t(ze,[2,102]),t(ze,[2,103]),t(ze,[2,104]),t(D,[2,91]),t(D,[2,56]),t(D,[2,58],{59:Oe}),{58:[1,145]},t($,[2,13]),{15:146,16:84,58:p,84:E,99:A,101:S},{39:[2,11]},t(ce,[2,44]),{13:[1,147]},{1:[2,4]},t(ae,[2,54]),t(ae,[2,53]),{16:39,18:148,19:40,58:p,84:E,99:A,101:S,102:_},t(Q,[2,65]),t(D,[2,33]),{41:[1,149]},{24:95,40:150,41:[2,37],43:23,46:a},{45:151,49:ne},t(P,[2,41]),{41:[2,47]},t(D,[2,45]),t(D,[2,77]),t(D,[2,79]),t(D,[2,80],{75:[1,152]}),t(D,[2,83]),t(D,[2,84],{13:[1,153]}),t(D,[2,86],{13:[1,155],75:[1,154]}),{22:le,58:he,80:K,82:156,83:106,84:X,85:te,86:J,87:se,88:ue,89:Z},t(ze,[2,95]),t(Se,[2,60]),{39:[2,10]},{14:[1,157]},t(ae,[2,55]),t(D,[2,34]),{41:[2,38]},{41:[1,158]},t(D,[2,81]),t(D,[2,85]),t(D,[2,87]),t(D,[2,88],{75:[1,159]}),t(ge,[2,93],{83:144,22:le,58:he,80:K,84:X,85:te,86:J,87:se,88:ue,89:Z}),t(ce,[2,8]),t(P,[2,42]),t(D,[2,89])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],83:[2,35],122:[2,11],125:[2,4],135:[2,47],146:[2,10],150:[2,38]},parseError:o(function(be,W){if(W.recoverable)this.trace(be);else{var de=new Error(be);throw de.hash=W,de}},"parseError"),parse:o(function(be){var W=this,de=[0],re=[],oe=[null],V=[],xe=this.table,q="",pe=0,ve=0,Pe=0,_e=2,we=1,Ve=V.slice.call(arguments,1),De=Object.create(this.lexer),qe={yy:{}};for(var at in this.yy)Object.prototype.hasOwnProperty.call(this.yy,at)&&(qe.yy[at]=this.yy[at]);De.setInput(be,qe.yy),qe.yy.lexer=De,qe.yy.parser=this,typeof De.yylloc>"u"&&(De.yylloc={});var Rt=De.yylloc;V.push(Rt);var st=De.options&&De.options.ranges;typeof qe.yy.parseError=="function"?this.parseError=qe.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ue(Tt){de.length=de.length-2*Tt,oe.length=oe.length-Tt,V.length=V.length-Tt}o(Ue,"popStack");function ct(){var Tt;return Tt=re.pop()||De.lex()||we,typeof Tt!="number"&&(Tt instanceof Array&&(re=Tt,Tt=re.pop()),Tt=W.symbols_[Tt]||Tt),Tt}o(ct,"lex");for(var We,ot,Yt,bt,Mt,xt,ut={},Et,ft,yt,nt;;){if(Yt=de[de.length-1],this.defaultActions[Yt]?bt=this.defaultActions[Yt]:((We===null||typeof We>"u")&&(We=ct()),bt=xe[Yt]&&xe[Yt][We]),typeof bt>"u"||!bt.length||!bt[0]){var dn="";nt=[];for(Et in xe[Yt])this.terminals_[Et]&&Et>_e&&nt.push("'"+this.terminals_[Et]+"'");De.showPosition?dn="Parse error on line "+(pe+1)+`:
+`+De.showPosition()+`
+Expecting `+nt.join(", ")+", got '"+(this.terminals_[We]||We)+"'":dn="Parse error on line "+(pe+1)+": Unexpected "+(We==we?"end of input":"'"+(this.terminals_[We]||We)+"'"),this.parseError(dn,{text:De.match,token:this.terminals_[We]||We,line:De.yylineno,loc:Rt,expected:nt})}if(bt[0]instanceof Array&&bt.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Yt+", token: "+We);switch(bt[0]){case 1:de.push(We),oe.push(De.yytext),V.push(De.yylloc),de.push(bt[1]),We=null,ot?(We=ot,ot=null):(ve=De.yyleng,q=De.yytext,pe=De.yylineno,Rt=De.yylloc,Pe>0&&Pe--);break;case 2:if(ft=this.productions_[bt[1]][1],ut.$=oe[oe.length-ft],ut._$={first_line:V[V.length-(ft||1)].first_line,last_line:V[V.length-1].last_line,first_column:V[V.length-(ft||1)].first_column,last_column:V[V.length-1].last_column},st&&(ut._$.range=[V[V.length-(ft||1)].range[0],V[V.length-1].range[1]]),xt=this.performAction.apply(ut,[q,ve,pe,qe.yy,bt[1],oe,V].concat(Ve)),typeof xt<"u")return xt;ft&&(de=de.slice(0,-1*ft*2),oe=oe.slice(0,-1*ft),V=V.slice(0,-1*ft)),de.push(this.productions_[bt[1]][0]),oe.push(ut.$),V.push(ut._$),yt=xe[de[de.length-2]][de[de.length-1]],de.push(yt);break;case 3:return!0}}return!0},"parse")},$e=function(){var Ie={EOF:1,parseError:o(function(W,de){if(this.yy.parser)this.yy.parser.parseError(W,de);else throw new Error(W)},"parseError"),setInput:o(function(be,W){return this.yy=W||this.yy||{},this._input=be,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var be=this._input[0];this.yytext+=be,this.yyleng++,this.offset++,this.match+=be,this.matched+=be;var W=be.match(/(?:\r\n?|\n).*/g);return W?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),be},"input"),unput:o(function(be){var W=be.length,de=be.split(/(?:\r\n?|\n)/g);this._input=be+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-W),this.offset-=W;var re=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),de.length-1&&(this.yylineno-=de.length-1);var oe=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:de?(de.length===re.length?this.yylloc.first_column:0)+re[re.length-de.length].length-de[0].length:this.yylloc.first_column-W},this.options.ranges&&(this.yylloc.range=[oe[0],oe[0]+this.yyleng-W]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(be){this.unput(this.match.slice(be))},"less"),pastInput:o(function(){var be=this.matched.substr(0,this.matched.length-this.match.length);return(be.length>20?"...":"")+be.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var be=this.match;return be.length<20&&(be+=this._input.substr(0,20-be.length)),(be.substr(0,20)+(be.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var be=this.pastInput(),W=new Array(be.length+1).join("-");return be+this.upcomingInput()+`
+`+W+"^"},"showPosition"),test_match:o(function(be,W){var de,re,oe;if(this.options.backtrack_lexer&&(oe={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(oe.yylloc.range=this.yylloc.range.slice(0))),re=be[0].match(/(?:\r\n?|\n).*/g),re&&(this.yylineno+=re.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:re?re[re.length-1].length-re[re.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+be[0].length},this.yytext+=be[0],this.match+=be[0],this.matches=be,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(be[0].length),this.matched+=be[0],de=this.performAction.call(this,this.yy,this,W,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),de)return de;if(this._backtrack){for(var V in oe)this[V]=oe[V];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var be,W,de,re;this._more||(this.yytext="",this.match="");for(var oe=this._currentRules(),V=0;V<oe.length;V++)if(de=this._input.match(this.rules[oe[V]]),de&&(!W||de[0].length>W[0].length)){if(W=de,re=V,this.options.backtrack_lexer){if(be=this.test_match(de,oe[V]),be!==!1)return be;if(this._backtrack){W=!1;continue}else return!1}else if(!this.options.flex)break}return W?(be=this.test_match(W,oe[re]),be!==!1?be:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var W=this.next();return W||this.lex()},"lex"),begin:o(function(W){this.conditionStack.push(W)},"begin"),popState:o(function(){var W=this.conditionStack.length-1;return W>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(W){return W=this.conditionStack.length-1-Math.abs(W||0),W>=0?this.conditionStack[W]:"INITIAL"},"topState"),pushState:o(function(W){this.begin(W)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(W,de,re,oe){var V=oe;switch(re){case 0:return 60;case 1:return 61;case 2:return 62;case 3:return 63;case 4:break;case 5:break;case 6:return this.begin("acc_title"),33;break;case 7:return this.popState(),"acc_title_value";break;case 8:return this.begin("acc_descr"),35;break;case 9:return this.popState(),"acc_descr_value";break;case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 8;case 14:break;case 15:return 7;case 16:return 7;case 17:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 19:this.popState();break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 77;case 22:this.popState();break;case 23:return 78;case 24:this.popState();break;case 25:return"STR";case 26:this.begin("string");break;case 27:return 80;case 28:return 55;case 29:return this.begin("namespace"),42;break;case 30:return this.popState(),8;break;case 31:break;case 32:return this.begin("namespace-body"),39;break;case 33:return this.popState(),41;break;case 34:return"EOF_IN_STRUCT";case 35:return 8;case 36:break;case 37:return"EDGE_STATE";case 38:return this.begin("class"),46;break;case 39:return this.popState(),8;break;case 40:break;case 41:return this.popState(),this.popState(),41;break;case 42:return this.begin("class-body"),39;break;case 43:return this.popState(),41;break;case 44:return"EOF_IN_STRUCT";case 45:return"EDGE_STATE";case 46:return"OPEN_IN_STRUCT";case 47:break;case 48:return"MEMBER";case 49:return 81;case 50:return 73;case 51:return 74;case 52:return 76;case 53:return 52;case 54:return 54;case 55:return 47;case 56:return 48;case 57:return 79;case 58:this.popState();break;case 59:return"GENERICTYPE";case 60:this.begin("generic");break;case 61:this.popState();break;case 62:return"BQUOTE_STR";case 63:this.begin("bqstring");break;case 64:return 75;case 65:return 75;case 66:return 75;case 67:return 75;case 68:return 67;case 69:return 67;case 70:return 69;case 71:return 69;case 72:return 68;case 73:return 66;case 74:return 70;case 75:return 71;case 76:return 72;case 77:return 22;case 78:return 44;case 79:return 99;case 80:return 17;case 81:return"PLUS";case 82:return 85;case 83:return 59;case 84:return 88;case 85:return 88;case 86:return 89;case 87:return"EQUALS";case 88:return"EQUALS";case 89:return 58;case 90:return 12;case 91:return 14;case 92:return"PUNCTUATION";case 93:return 84;case 94:return 101;case 95:return 87;case 96:return 87;case 97:return 9}},"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:classDef\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,33,34,35,36,37,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},namespace:{rules:[26,29,30,31,32,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},"class-body":{rules:[26,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},class:{rules:[26,39,40,41,42,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr:{rules:[9,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_title:{rules:[7,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_args:{rules:[22,23,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_name:{rules:[19,20,21,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},href:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},struct:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},generic:{rules:[26,49,50,51,52,53,54,55,56,57,58,59,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},bqstring:{rules:[26,49,50,51,52,53,54,55,56,57,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},string:{rules:[24,25,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,29,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}};return Ie}();He.lexer=$e;function Re(){this.yy={}}return o(Re,"Parser"),Re.prototype=He,He.Parser=Re,new Re}();MO.parser=MO;L6=MO});var Dfe,kb,Lfe=N(()=>{"use strict";zt();gr();Dfe=["#","+","~","-",""],kb=class{static{o(this,"ClassMember")}constructor(e,r){this.memberType=r,this.visibility="",this.classifier="",this.text="";let n=Tr(e,me());this.parseMember(n)}getDisplayDetails(){let e=this.visibility+ec(this.id);this.memberType==="method"&&(e+=`(${ec(this.parameters.trim())})`,this.returnType&&(e+=" : "+ec(this.returnType))),e=e.trim();let r=this.parseClassifier();return{displayText:e,cssStyle:r}}parseMember(e){let r="";if(this.memberType==="method"){let a=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/.exec(e);if(a){let s=a[1]?a[1].trim():"";if(Dfe.includes(s)&&(this.visibility=s),this.id=a[2],this.parameters=a[3]?a[3].trim():"",r=a[4]?a[4].trim():"",this.returnType=a[5]?a[5].trim():"",r===""){let l=this.returnType.substring(this.returnType.length-1);/[$*]/.exec(l)&&(r=l,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{let i=e.length,a=e.substring(0,1),s=e.substring(i-1);Dfe.includes(a)&&(this.visibility=a),/[$*]/.exec(s)&&(r=s),this.id=e.substring(this.visibility===""?0:1,r===""?i:i-1)}this.classifier=r,this.id=this.id.startsWith(" ")?" "+this.id.trim():this.id.trim();let n=`${this.visibility?"\\"+this.visibility:""}${ec(this.id)}${this.memberType==="method"?`(${ec(this.parameters)})${this.returnType?" : "+ec(this.returnType):""}`:""}`;this.text=n.replaceAll("<","&lt;").replaceAll(">","&gt;"),this.text.startsWith("\\&lt;")&&(this.text=this.text.replace("\\&lt;","~"))}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}});var R6,Rfe,Lp,D1,OO=N(()=>{"use strict";dr();vt();zt();gr();ir();mi();Lfe();R6="classId-",Rfe=0,Lp=o(t=>Ze.sanitizeText(t,me()),"sanitizeText"),D1=class{constructor(){this.relations=[];this.classes=new Map;this.styleClasses=new Map;this.notes=[];this.interfaces=[];this.namespaces=new Map;this.namespaceCounter=0;this.functions=[];this.lineType={LINE:0,DOTTED_LINE:1};this.relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4};this.setupToolTips=o(e=>{let r=Ge(".mermaidTooltip");(r._groups||r)[0][0]===null&&(r=Ge("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),Ge(e).select("svg").selectAll("g.node").on("mouseover",a=>{let s=Ge(a.currentTarget);if(s.attr("title")===null)return;let u=this.getBoundingClientRect();r.transition().duration(200).style("opacity",".9"),r.text(s.attr("title")).style("left",window.scrollX+u.left+(u.right-u.left)/2+"px").style("top",window.scrollY+u.top-14+document.body.scrollTop+"px"),r.html(r.html().replace(/&lt;br\/&gt;/g,"<br/>")),s.classed("hover",!0)}).on("mouseout",a=>{r.transition().duration(500).style("opacity",0),Ge(a.currentTarget).classed("hover",!1)})},"setupToolTips");this.direction="TB";this.setAccTitle=Lr;this.getAccTitle=Rr;this.setAccDescription=Nr;this.getAccDescription=Mr;this.setDiagramTitle=$r;this.getDiagramTitle=Ir;this.getConfig=o(()=>me().class,"getConfig");this.functions.push(this.setupToolTips.bind(this)),this.clear(),this.addRelation=this.addRelation.bind(this),this.addClassesToNamespace=this.addClassesToNamespace.bind(this),this.addNamespace=this.addNamespace.bind(this),this.setCssClass=this.setCssClass.bind(this),this.addMembers=this.addMembers.bind(this),this.addClass=this.addClass.bind(this),this.setClassLabel=this.setClassLabel.bind(this),this.addAnnotation=this.addAnnotation.bind(this),this.addMember=this.addMember.bind(this),this.cleanupLabel=this.cleanupLabel.bind(this),this.addNote=this.addNote.bind(this),this.defineClass=this.defineClass.bind(this),this.setDirection=this.setDirection.bind(this),this.setLink=this.setLink.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.clear=this.clear.bind(this),this.setTooltip=this.setTooltip.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setCssStyle=this.setCssStyle.bind(this)}static{o(this,"ClassDB")}splitClassNameAndType(e){let r=Ze.sanitizeText(e,me()),n="",i=r;if(r.indexOf("~")>0){let a=r.split("~");i=Lp(a[0]),n=Lp(a[1])}return{className:i,type:n}}setClassLabel(e,r){let n=Ze.sanitizeText(e,me());r&&(r=Lp(r));let{className:i}=this.splitClassNameAndType(n);this.classes.get(i).label=r,this.classes.get(i).text=`${r}${this.classes.get(i).type?`<${this.classes.get(i).type}>`:""}`}addClass(e){let r=Ze.sanitizeText(e,me()),{className:n,type:i}=this.splitClassNameAndType(r);if(this.classes.has(n))return;let a=Ze.sanitizeText(n,me());this.classes.set(a,{id:a,type:i,label:a,text:`${a}${i?`&lt;${i}&gt;`:""}`,shape:"classBox",cssClasses:"default",methods:[],members:[],annotations:[],styles:[],domId:R6+a+"-"+Rfe}),Rfe++}addInterface(e,r){let n={id:`interface${this.interfaces.length}`,label:e,classId:r};this.interfaces.push(n)}lookUpDomId(e){let r=Ze.sanitizeText(e,me());if(this.classes.has(r))return this.classes.get(r).domId;throw new Error("Class not found: "+r)}clear(){this.relations=[],this.classes=new Map,this.notes=[],this.interfaces=[],this.functions=[],this.functions.push(this.setupToolTips.bind(this)),this.namespaces=new Map,this.namespaceCounter=0,this.direction="TB",Ar()}getClass(e){return this.classes.get(e)}getClasses(){return this.classes}getRelations(){return this.relations}getNotes(){return this.notes}addRelation(e){Y.debug("Adding relation: "+JSON.stringify(e));let r=[this.relationType.LOLLIPOP,this.relationType.AGGREGATION,this.relationType.COMPOSITION,this.relationType.DEPENDENCY,this.relationType.EXTENSION];e.relation.type1===this.relationType.LOLLIPOP&&!r.includes(e.relation.type2)?(this.addClass(e.id2),this.addInterface(e.id1,e.id2),e.id1=`interface${this.interfaces.length-1}`):e.relation.type2===this.relationType.LOLLIPOP&&!r.includes(e.relation.type1)?(this.addClass(e.id1),this.addInterface(e.id2,e.id1),e.id2=`interface${this.interfaces.length-1}`):(this.addClass(e.id1),this.addClass(e.id2)),e.id1=this.splitClassNameAndType(e.id1).className,e.id2=this.splitClassNameAndType(e.id2).className,e.relationTitle1=Ze.sanitizeText(e.relationTitle1.trim(),me()),e.relationTitle2=Ze.sanitizeText(e.relationTitle2.trim(),me()),this.relations.push(e)}addAnnotation(e,r){let n=this.splitClassNameAndType(e).className;this.classes.get(n).annotations.push(r)}addMember(e,r){this.addClass(e);let n=this.splitClassNameAndType(e).className,i=this.classes.get(n);if(typeof r=="string"){let a=r.trim();a.startsWith("<<")&&a.endsWith(">>")?i.annotations.push(Lp(a.substring(2,a.length-2))):a.indexOf(")")>0?i.methods.push(new kb(a,"method")):a&&i.members.push(new kb(a,"attribute"))}}addMembers(e,r){Array.isArray(r)&&(r.reverse(),r.forEach(n=>this.addMember(e,n)))}addNote(e,r){let n={id:`note${this.notes.length}`,class:r,text:e};this.notes.push(n)}cleanupLabel(e){return e.startsWith(":")&&(e=e.substring(1)),Lp(e.trim())}setCssClass(e,r){e.split(",").forEach(n=>{let i=n;/\d/.exec(n[0])&&(i=R6+i);let a=this.classes.get(i);a&&(a.cssClasses+=" "+r)})}defineClass(e,r){for(let n of e){let i=this.styleClasses.get(n);i===void 0&&(i={id:n,styles:[],textStyles:[]},this.styleClasses.set(n,i)),r&&r.forEach(a=>{if(/color/.exec(a)){let s=a.replace("fill","bgFill");i.textStyles.push(s)}i.styles.push(a)}),this.classes.forEach(a=>{a.cssClasses.includes(n)&&a.styles.push(...r.flatMap(s=>s.split(",")))})}}setTooltip(e,r){e.split(",").forEach(n=>{r!==void 0&&(this.classes.get(n).tooltip=Lp(r))})}getTooltip(e,r){return r&&this.namespaces.has(r)?this.namespaces.get(r).classes.get(e).tooltip:this.classes.get(e).tooltip}setLink(e,r,n){let i=me();e.split(",").forEach(a=>{let s=a;/\d/.exec(a[0])&&(s=R6+s);let l=this.classes.get(s);l&&(l.link=Gt.formatUrl(r,i),i.securityLevel==="sandbox"?l.linkTarget="_top":typeof n=="string"?l.linkTarget=Lp(n):l.linkTarget="_blank")}),this.setCssClass(e,"clickable")}setClickEvent(e,r,n){e.split(",").forEach(i=>{this.setClickFunc(i,r,n),this.classes.get(i).haveCallback=!0}),this.setCssClass(e,"clickable")}setClickFunc(e,r,n){let i=Ze.sanitizeText(e,me());if(me().securityLevel!=="loose"||r===void 0)return;let s=i;if(this.classes.has(s)){let l=this.lookUpDomId(s),u=[];if(typeof n=="string"){u=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let h=0;h<u.length;h++){let f=u[h].trim();f.startsWith('"')&&f.endsWith('"')&&(f=f.substr(1,f.length-2)),u[h]=f}}u.length===0&&u.push(l),this.functions.push(()=>{let h=document.querySelector(`[id="${l}"]`);h!==null&&h.addEventListener("click",()=>{Gt.runFunc(r,...u)},!1)})}}bindFunctions(e){this.functions.forEach(r=>{r(e)})}getDirection(){return this.direction}setDirection(e){this.direction=e}addNamespace(e){this.namespaces.has(e)||(this.namespaces.set(e,{id:e,classes:new Map,children:{},domId:R6+e+"-"+this.namespaceCounter}),this.namespaceCounter++)}getNamespace(e){return this.namespaces.get(e)}getNamespaces(){return this.namespaces}addClassesToNamespace(e,r){if(this.namespaces.has(e))for(let n of r){let{className:i}=this.splitClassNameAndType(n);this.classes.get(i).parent=e,this.namespaces.get(e).classes.set(i,this.classes.get(i))}}setCssStyle(e,r){let n=this.classes.get(e);if(!(!r||!n))for(let i of r)i.includes(",")?n.styles.push(...i.split(",")):n.styles.push(i)}getArrowMarker(e){let r;switch(e){case 0:r="aggregation";break;case 1:r="extension";break;case 2:r="composition";break;case 3:r="dependency";break;case 4:r="lollipop";break;default:r="none"}return r}getData(){let e=[],r=[],n=me();for(let a of this.namespaces.keys()){let s=this.namespaces.get(a);if(s){let l={id:s.id,label:s.id,isGroup:!0,padding:n.class.padding??16,shape:"rect",cssStyles:["fill: none","stroke: black"],look:n.look};e.push(l)}}for(let a of this.classes.keys()){let s=this.classes.get(a);if(s){let l=s;l.parentId=s.parent,l.look=n.look,e.push(l)}}let i=0;for(let a of this.notes){i++;let s={id:a.id,label:a.text,isGroup:!1,shape:"note",padding:n.class.padding??6,cssStyles:["text-align: left","white-space: nowrap",`fill: ${n.themeVariables.noteBkgColor}`,`stroke: ${n.themeVariables.noteBorderColor}`],look:n.look};e.push(s);let l=this.classes.get(a.class)?.id??"";if(l){let u={id:`edgeNote${i}`,start:a.id,end:l,type:"normal",thickness:"normal",classes:"relation",arrowTypeStart:"none",arrowTypeEnd:"none",arrowheadStyle:"",labelStyle:[""],style:["fill: none"],pattern:"dotted",look:n.look};r.push(u)}}for(let a of this.interfaces){let s={id:a.id,label:a.label,isGroup:!1,shape:"rect",cssStyles:["opacity: 0;"],look:n.look};e.push(s)}i=0;for(let a of this.relations){i++;let s={id:$h(a.id1,a.id2,{prefix:"id",counter:i}),start:a.id1,end:a.id2,type:"normal",label:a.title,labelpos:"c",thickness:"normal",classes:"relation",arrowTypeStart:this.getArrowMarker(a.relation.type1),arrowTypeEnd:this.getArrowMarker(a.relation.type2),startLabelRight:a.relationTitle1==="none"?"":a.relationTitle1,endLabelLeft:a.relationTitle2==="none"?"":a.relationTitle2,arrowheadStyle:"",labelStyle:["display: inline-block"],style:a.style||"",pattern:a.relation.lineType==1?"dashed":"solid",look:n.look};r.push(s)}return{nodes:e,edges:r,other:{},config:n,direction:this.getDirection()}}}});var UVe,N6,PO=N(()=>{"use strict";UVe=o(t=>`g.classGroup text {
+ fill: ${t.nodeBorder||t.classText};
+ stroke: none;
+ font-family: ${t.fontFamily};
+ font-size: 10px;
+
+ .title {
+ font-weight: bolder;
+ }
+
+}
+
+.nodeLabel, .edgeLabel {
+ color: ${t.classText};
+}
+.edgeLabel .label rect {
+ fill: ${t.mainBkg};
+}
+.label text {
+ fill: ${t.classText};
+}
+
+.labelBkg {
+ background: ${t.mainBkg};
+}
+.edgeLabel .label span {
+ background: ${t.mainBkg};
+}
+
+.classTitle {
+ font-weight: bolder;
+}
+.node rect,
+ .node circle,
+ .node ellipse,
+ .node polygon,
+ .node path {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+ stroke-width: 1px;
+ }
+
+
+.divider {
+ stroke: ${t.nodeBorder};
+ stroke-width: 1;
+}
+
+g.clickable {
+ cursor: pointer;
+}
+
+g.classGroup rect {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+}
+
+g.classGroup line {
+ stroke: ${t.nodeBorder};
+ stroke-width: 1;
+}
+
+.classLabel .box {
+ stroke: none;
+ stroke-width: 0;
+ fill: ${t.mainBkg};
+ opacity: 0.5;
+}
+
+.classLabel .label {
+ fill: ${t.nodeBorder};
+ font-size: 10px;
+}
+
+.relation {
+ stroke: ${t.lineColor};
+ stroke-width: 1;
+ fill: none;
+}
+
+.dashed-line{
+ stroke-dasharray: 3;
+}
+
+.dotted-line{
+ stroke-dasharray: 1 2;
+}
+
+#compositionStart, .composition {
+ fill: ${t.lineColor} !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#compositionEnd, .composition {
+ fill: ${t.lineColor} !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#dependencyStart, .dependency {
+ fill: ${t.lineColor} !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#dependencyStart, .dependency {
+ fill: ${t.lineColor} !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#extensionStart, .extension {
+ fill: transparent !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#extensionEnd, .extension {
+ fill: transparent !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#aggregationStart, .aggregation {
+ fill: transparent !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#aggregationEnd, .aggregation {
+ fill: transparent !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#lollipopStart, .lollipop {
+ fill: ${t.mainBkg} !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+#lollipopEnd, .lollipop {
+ fill: ${t.mainBkg} !important;
+ stroke: ${t.lineColor} !important;
+ stroke-width: 1;
+}
+
+.edgeTerminals {
+ font-size: 11px;
+ line-height: initial;
+}
+
+.classTitleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: ${t.textColor};
+}
+`,"getStyles"),N6=UVe});var HVe,WVe,qVe,M6,BO=N(()=>{"use strict";zt();vt();gm();Yd();$m();ir();HVe=o((t,e="TB")=>{if(!t.doc)return e;let r=e;for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir"),WVe=o(function(t,e){return e.db.getClasses()},"getClasses"),qVe=o(async function(t,e,r,n){Y.info("REF0:"),Y.info("Drawing class diagram (v3)",e);let{securityLevel:i,state:a,layout:s}=me(),l=n.db.getData(),u=yc(e,i);l.type=n.type,l.layoutAlgorithm=nf(s),l.nodeSpacing=a?.nodeSpacing||50,l.rankSpacing=a?.rankSpacing||50,l.markers=["aggregation","extension","composition","dependency","lollipop"],l.diagramId=e,await Cc(l,u);let h=8;Gt.insertTitle(u,"classDiagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Ac(u,h,"classDiagram",a?.useMaxWidth??!0)},"draw"),M6={getClasses:WVe,draw:qVe,getDir:HVe}});var Nfe={};hr(Nfe,{diagram:()=>YVe});var YVe,Mfe=N(()=>{"use strict";IO();OO();PO();BO();YVe={parser:L6,get db(){return new D1},renderer:M6,styles:N6,init:o(t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var Pfe={};hr(Pfe,{diagram:()=>QVe});var QVe,Bfe=N(()=>{"use strict";IO();OO();PO();BO();QVe={parser:L6,get db(){return new D1},renderer:M6,styles:N6,init:o(t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var FO,I6,$O=N(()=>{"use strict";FO=function(){var t=o(function(F,P,z,$){for(z=z||{},$=F.length;$--;z[F[$]]=P);return z},"o"),e=[1,2],r=[1,3],n=[1,4],i=[2,4],a=[1,9],s=[1,11],l=[1,16],u=[1,17],h=[1,18],f=[1,19],d=[1,32],p=[1,20],m=[1,21],g=[1,22],y=[1,23],v=[1,24],x=[1,26],b=[1,27],w=[1,28],C=[1,29],T=[1,30],E=[1,31],A=[1,34],S=[1,35],_=[1,36],I=[1,37],D=[1,33],k=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],L=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],R=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],O={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"-->":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,classDef:38,CLASSDEF_ID:39,CLASSDEF_STYLEOPTS:40,DEFAULT:41,style:42,STYLE_IDS:43,STYLEDEF_STYLEOPTS:44,class:45,CLASSENTITY_IDS:46,STYLECLASS:47,direction_tb:48,direction_bt:49,direction_rl:50,direction_lr:51,eol:52,";":53,EDGE_STATE:54,STYLE_SEPARATOR:55,left_of:56,right_of:57,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"-->",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"classDef",39:"CLASSDEF_ID",40:"CLASSDEF_STYLEOPTS",41:"DEFAULT",42:"style",43:"STYLE_IDS",44:"STYLEDEF_STYLEOPTS",45:"class",46:"CLASSENTITY_IDS",47:"STYLECLASS",48:"direction_tb",49:"direction_bt",50:"direction_rl",51:"direction_lr",53:";",54:"EDGE_STATE",55:"STYLE_SEPARATOR",56:"left_of",57:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[52,1],[52,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:o(function(P,z,$,H,Q,j,ie){var ne=j.length-1;switch(Q){case 3:return H.setRootDoc(j[ne]),j[ne];break;case 4:this.$=[];break;case 5:j[ne]!="nl"&&(j[ne-1].push(j[ne]),this.$=j[ne-1]);break;case 6:case 7:this.$=j[ne];break;case 8:this.$="nl";break;case 12:this.$=j[ne];break;case 13:let X=j[ne-1];X.description=H.trimColon(j[ne]),this.$=X;break;case 14:this.$={stmt:"relation",state1:j[ne-2],state2:j[ne]};break;case 15:let te=H.trimColon(j[ne]);this.$={stmt:"relation",state1:j[ne-3],state2:j[ne-1],description:te};break;case 19:this.$={stmt:"state",id:j[ne-3],type:"default",description:"",doc:j[ne-1]};break;case 20:var le=j[ne],he=j[ne-2].trim();if(j[ne].match(":")){var K=j[ne].split(":");le=K[0],he=[he,K[1]]}this.$={stmt:"state",id:le,type:"default",description:he};break;case 21:this.$={stmt:"state",id:j[ne-3],type:"default",description:j[ne-5],doc:j[ne-1]};break;case 22:this.$={stmt:"state",id:j[ne],type:"fork"};break;case 23:this.$={stmt:"state",id:j[ne],type:"join"};break;case 24:this.$={stmt:"state",id:j[ne],type:"choice"};break;case 25:this.$={stmt:"state",id:H.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:j[ne-1].trim(),note:{position:j[ne-2].trim(),text:j[ne].trim()}};break;case 29:this.$=j[ne].trim(),H.setAccTitle(this.$);break;case 30:case 31:this.$=j[ne].trim(),H.setAccDescription(this.$);break;case 32:case 33:this.$={stmt:"classDef",id:j[ne-1].trim(),classes:j[ne].trim()};break;case 34:this.$={stmt:"style",id:j[ne-1].trim(),styleClass:j[ne].trim()};break;case 35:this.$={stmt:"applyClass",id:j[ne-1].trim(),styleClass:j[ne].trim()};break;case 36:H.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 37:H.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 38:H.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 39:H.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 42:case 43:this.$={stmt:"state",id:j[ne].trim(),type:"default",description:""};break;case 44:this.$={stmt:"state",id:j[ne-2].trim(),classes:[j[ne].trim()],type:"default",description:""};break;case 45:this.$={stmt:"state",id:j[ne-2].trim(),classes:[j[ne].trim()],type:"default",description:""};break}},"anonymous"),table:[{3:1,4:e,5:r,6:n},{1:[3]},{3:5,4:e,5:r,6:n},{3:6,4:e,5:r,6:n},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:w,38:C,42:T,45:E,48:A,49:S,50:_,51:I,54:D},t(k,[2,5]),{9:38,10:12,11:13,12:14,13:15,16:l,17:u,19:h,22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:w,38:C,42:T,45:E,48:A,49:S,50:_,51:I,54:D},t(k,[2,7]),t(k,[2,8]),t(k,[2,9]),t(k,[2,10]),t(k,[2,11]),t(k,[2,12],{14:[1,39],15:[1,40]}),t(k,[2,16]),{18:[1,41]},t(k,[2,18],{20:[1,42]}),{23:[1,43]},t(k,[2,22]),t(k,[2,23]),t(k,[2,24]),t(k,[2,25]),{30:44,31:[1,45],56:[1,46],57:[1,47]},t(k,[2,28]),{34:[1,48]},{36:[1,49]},t(k,[2,31]),{39:[1,50],41:[1,51]},{43:[1,52]},{46:[1,53]},t(L,[2,42],{55:[1,54]}),t(L,[2,43],{55:[1,55]}),t(k,[2,36]),t(k,[2,37]),t(k,[2,38]),t(k,[2,39]),t(k,[2,6]),t(k,[2,13]),{13:56,24:d,54:D},t(k,[2,17]),t(R,i,{7:57}),{24:[1,58]},{24:[1,59]},{23:[1,60]},{24:[2,46]},{24:[2,47]},t(k,[2,29]),t(k,[2,30]),{40:[1,61]},{40:[1,62]},{44:[1,63]},{47:[1,64]},{24:[1,65]},{24:[1,66]},t(k,[2,14],{14:[1,67]}),{4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,21:[1,68],22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:w,38:C,42:T,45:E,48:A,49:S,50:_,51:I,54:D},t(k,[2,20],{20:[1,69]}),{31:[1,70]},{24:[1,71]},t(k,[2,32]),t(k,[2,33]),t(k,[2,34]),t(k,[2,35]),t(L,[2,44]),t(L,[2,45]),t(k,[2,15]),t(k,[2,19]),t(R,i,{7:72}),t(k,[2,26]),t(k,[2,27]),{4:a,5:s,8:8,9:10,10:12,11:13,12:14,13:15,16:l,17:u,19:h,21:[1,73],22:f,24:d,25:p,26:m,27:g,28:y,29:v,32:25,33:x,35:b,37:w,38:C,42:T,45:E,48:A,49:S,50:_,51:I,54:D},t(k,[2,21])],defaultActions:{5:[2,1],6:[2,2],46:[2,46],47:[2,47]},parseError:o(function(P,z){if(z.recoverable)this.trace(P);else{var $=new Error(P);throw $.hash=z,$}},"parseError"),parse:o(function(P){var z=this,$=[0],H=[],Q=[null],j=[],ie=this.table,ne="",le=0,he=0,K=0,X=2,te=1,J=j.slice.call(arguments,1),se=Object.create(this.lexer),ue={yy:{}};for(var Z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Z)&&(ue.yy[Z]=this.yy[Z]);se.setInput(P,ue.yy),ue.yy.lexer=se,ue.yy.parser=this,typeof se.yylloc>"u"&&(se.yylloc={});var Se=se.yylloc;j.push(Se);var ce=se.options&&se.options.ranges;typeof ue.yy.parseError=="function"?this.parseError=ue.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ae(xe){$.length=$.length-2*xe,Q.length=Q.length-xe,j.length=j.length-xe}o(ae,"popStack");function Oe(){var xe;return xe=H.pop()||se.lex()||te,typeof xe!="number"&&(xe instanceof Array&&(H=xe,xe=H.pop()),xe=z.symbols_[xe]||xe),xe}o(Oe,"lex");for(var ge,ze,He,$e,Re,Ie,be={},W,de,re,oe;;){if(He=$[$.length-1],this.defaultActions[He]?$e=this.defaultActions[He]:((ge===null||typeof ge>"u")&&(ge=Oe()),$e=ie[He]&&ie[He][ge]),typeof $e>"u"||!$e.length||!$e[0]){var V="";oe=[];for(W in ie[He])this.terminals_[W]&&W>X&&oe.push("'"+this.terminals_[W]+"'");se.showPosition?V="Parse error on line "+(le+1)+`:
+`+se.showPosition()+`
+Expecting `+oe.join(", ")+", got '"+(this.terminals_[ge]||ge)+"'":V="Parse error on line "+(le+1)+": Unexpected "+(ge==te?"end of input":"'"+(this.terminals_[ge]||ge)+"'"),this.parseError(V,{text:se.match,token:this.terminals_[ge]||ge,line:se.yylineno,loc:Se,expected:oe})}if($e[0]instanceof Array&&$e.length>1)throw new Error("Parse Error: multiple actions possible at state: "+He+", token: "+ge);switch($e[0]){case 1:$.push(ge),Q.push(se.yytext),j.push(se.yylloc),$.push($e[1]),ge=null,ze?(ge=ze,ze=null):(he=se.yyleng,ne=se.yytext,le=se.yylineno,Se=se.yylloc,K>0&&K--);break;case 2:if(de=this.productions_[$e[1]][1],be.$=Q[Q.length-de],be._$={first_line:j[j.length-(de||1)].first_line,last_line:j[j.length-1].last_line,first_column:j[j.length-(de||1)].first_column,last_column:j[j.length-1].last_column},ce&&(be._$.range=[j[j.length-(de||1)].range[0],j[j.length-1].range[1]]),Ie=this.performAction.apply(be,[ne,he,le,ue.yy,$e[1],Q,j].concat(J)),typeof Ie<"u")return Ie;de&&($=$.slice(0,-1*de*2),Q=Q.slice(0,-1*de),j=j.slice(0,-1*de)),$.push(this.productions_[$e[1]][0]),Q.push(be.$),j.push(be._$),re=ie[$[$.length-2]][$[$.length-1]],$.push(re);break;case 3:return!0}}return!0},"parse")},M=function(){var F={EOF:1,parseError:o(function(z,$){if(this.yy.parser)this.yy.parser.parseError(z,$);else throw new Error(z)},"parseError"),setInput:o(function(P,z){return this.yy=z||this.yy||{},this._input=P,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var P=this._input[0];this.yytext+=P,this.yyleng++,this.offset++,this.match+=P,this.matched+=P;var z=P.match(/(?:\r\n?|\n).*/g);return z?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),P},"input"),unput:o(function(P){var z=P.length,$=P.split(/(?:\r\n?|\n)/g);this._input=P+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-z),this.offset-=z;var H=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),$.length-1&&(this.yylineno-=$.length-1);var Q=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:$?($.length===H.length?this.yylloc.first_column:0)+H[H.length-$.length].length-$[0].length:this.yylloc.first_column-z},this.options.ranges&&(this.yylloc.range=[Q[0],Q[0]+this.yyleng-z]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(P){this.unput(this.match.slice(P))},"less"),pastInput:o(function(){var P=this.matched.substr(0,this.matched.length-this.match.length);return(P.length>20?"...":"")+P.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var P=this.match;return P.length<20&&(P+=this._input.substr(0,20-P.length)),(P.substr(0,20)+(P.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var P=this.pastInput(),z=new Array(P.length+1).join("-");return P+this.upcomingInput()+`
+`+z+"^"},"showPosition"),test_match:o(function(P,z){var $,H,Q;if(this.options.backtrack_lexer&&(Q={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(Q.yylloc.range=this.yylloc.range.slice(0))),H=P[0].match(/(?:\r\n?|\n).*/g),H&&(this.yylineno+=H.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:H?H[H.length-1].length-H[H.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+P[0].length},this.yytext+=P[0],this.match+=P[0],this.matches=P,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(P[0].length),this.matched+=P[0],$=this.performAction.call(this,this.yy,this,z,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),$)return $;if(this._backtrack){for(var j in Q)this[j]=Q[j];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var P,z,$,H;this._more||(this.yytext="",this.match="");for(var Q=this._currentRules(),j=0;j<Q.length;j++)if($=this._input.match(this.rules[Q[j]]),$&&(!z||$[0].length>z[0].length)){if(z=$,H=j,this.options.backtrack_lexer){if(P=this.test_match($,Q[j]),P!==!1)return P;if(this._backtrack){z=!1;continue}else return!1}else if(!this.options.flex)break}return z?(P=this.test_match(z,Q[H]),P!==!1?P:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var z=this.next();return z||this.lex()},"lex"),begin:o(function(z){this.conditionStack.push(z)},"begin"),popState:o(function(){var z=this.conditionStack.length-1;return z>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(z){return z=this.conditionStack.length-1-Math.abs(z||0),z>=0?this.conditionStack[z]:"INITIAL"},"topState"),pushState:o(function(z){this.begin(z)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(z,$,H,Q){var j=Q;switch(H){case 0:return 41;case 1:return 48;case 2:return 49;case 3:return 50;case 4:return 51;case 5:break;case 6:break;case 7:return 5;case 8:break;case 9:break;case 10:break;case 11:break;case 12:return this.pushState("SCALE"),17;break;case 13:return 18;case 14:this.popState();break;case 15:return this.begin("acc_title"),33;break;case 16:return this.popState(),"acc_title_value";break;case 17:return this.begin("acc_descr"),35;break;case 18:return this.popState(),"acc_descr_value";break;case 19:this.begin("acc_descr_multiline");break;case 20:this.popState();break;case 21:return"acc_descr_multiline_value";case 22:return this.pushState("CLASSDEF"),38;break;case 23:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";break;case 24:return this.popState(),this.pushState("CLASSDEFID"),39;break;case 25:return this.popState(),40;break;case 26:return this.pushState("CLASS"),45;break;case 27:return this.popState(),this.pushState("CLASS_STYLE"),46;break;case 28:return this.popState(),47;break;case 29:return this.pushState("STYLE"),42;break;case 30:return this.popState(),this.pushState("STYLEDEF_STYLES"),43;break;case 31:return this.popState(),44;break;case 32:return this.pushState("SCALE"),17;break;case 33:return 18;case 34:this.popState();break;case 35:this.pushState("STATE");break;case 36:return this.popState(),$.yytext=$.yytext.slice(0,-8).trim(),25;break;case 37:return this.popState(),$.yytext=$.yytext.slice(0,-8).trim(),26;break;case 38:return this.popState(),$.yytext=$.yytext.slice(0,-10).trim(),27;break;case 39:return this.popState(),$.yytext=$.yytext.slice(0,-8).trim(),25;break;case 40:return this.popState(),$.yytext=$.yytext.slice(0,-8).trim(),26;break;case 41:return this.popState(),$.yytext=$.yytext.slice(0,-10).trim(),27;break;case 42:return 48;case 43:return 49;case 44:return 50;case 45:return 51;case 46:this.pushState("STATE_STRING");break;case 47:return this.pushState("STATE_ID"),"AS";break;case 48:return this.popState(),"ID";break;case 49:this.popState();break;case 50:return"STATE_DESCR";case 51:return 19;case 52:this.popState();break;case 53:return this.popState(),this.pushState("struct"),20;break;case 54:break;case 55:return this.popState(),21;break;case 56:break;case 57:return this.begin("NOTE"),29;break;case 58:return this.popState(),this.pushState("NOTE_ID"),56;break;case 59:return this.popState(),this.pushState("NOTE_ID"),57;break;case 60:this.popState(),this.pushState("FLOATING_NOTE");break;case 61:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";break;case 62:break;case 63:return"NOTE_TEXT";case 64:return this.popState(),"ID";break;case 65:return this.popState(),this.pushState("NOTE_TEXT"),24;break;case 66:return this.popState(),$.yytext=$.yytext.substr(2).trim(),31;break;case 67:return this.popState(),$.yytext=$.yytext.slice(0,-8).trim(),31;break;case 68:return 6;case 69:return 6;case 70:return 16;case 71:return 54;case 72:return 24;case 73:return $.yytext=$.yytext.trim(),14;break;case 74:return 15;case 75:return 28;case 76:return 55;case 77:return 5;case 78:return"INVALID"}},"anonymous"),rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:style\s+)/i,/^(?:[\w,]+\s+)/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<<fork>>)/i,/^(?:.*<<join>>)/i,/^(?:.*<<choice>>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[9,10],inclusive:!1},struct:{rules:[9,10,22,26,29,35,42,43,44,45,54,55,56,57,71,72,73,74,75],inclusive:!1},FLOATING_NOTE_ID:{rules:[64],inclusive:!1},FLOATING_NOTE:{rules:[61,62,63],inclusive:!1},NOTE_TEXT:{rules:[66,67],inclusive:!1},NOTE_ID:{rules:[65],inclusive:!1},NOTE:{rules:[58,59,60],inclusive:!1},STYLEDEF_STYLEOPTS:{rules:[],inclusive:!1},STYLEDEF_STYLES:{rules:[31],inclusive:!1},STYLE_IDS:{rules:[],inclusive:!1},STYLE:{rules:[30],inclusive:!1},CLASS_STYLE:{rules:[28],inclusive:!1},CLASS:{rules:[27],inclusive:!1},CLASSDEFID:{rules:[25],inclusive:!1},CLASSDEF:{rules:[23,24],inclusive:!1},acc_descr_multiline:{rules:[20,21],inclusive:!1},acc_descr:{rules:[18],inclusive:!1},acc_title:{rules:[16],inclusive:!1},SCALE:{rules:[13,14,33,34],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[48],inclusive:!1},STATE_STRING:{rules:[49,50],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,36,37,38,39,40,41,46,47,51,52,53],inclusive:!1},ID:{rules:[9,10],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,10,11,12,15,17,19,22,26,29,32,35,53,57,68,69,70,71,72,73,74,76,77,78],inclusive:!0}}};return F}();O.lexer=M;function B(){this.yy={}}return o(B,"Parser"),B.prototype=O,O.Parser=B,new B}();FO.parser=FO;I6=FO});var zfe,O6,zO,L1,Eb,Gfe,Vfe,Ufe,Rp,P6,GO,VO,UO,HO,WO,B6,F6,Hfe,Wfe,qO,YO,qfe,Yfe,R1,tUe,Xfe,XO,rUe,nUe,jfe,Kfe,iUe,Qfe,aUe,Zfe,jO,KO,Jfe,$6,ede,QO,z6=N(()=>{"use strict";zfe="TB",O6="TB",zO="dir",L1="state",Eb="relation",Gfe="classDef",Vfe="style",Ufe="applyClass",Rp="default",P6="divider",GO="fill:none",VO="fill: #333",UO="c",HO="text",WO="normal",B6="rect",F6="rectWithTitle",Hfe="stateStart",Wfe="stateEnd",qO="divider",YO="roundedWithTitle",qfe="note",Yfe="noteGroup",R1="statediagram",tUe="state",Xfe=`${R1}-${tUe}`,XO="transition",rUe="note",nUe="note-edge",jfe=`${XO} ${nUe}`,Kfe=`${R1}-${rUe}`,iUe="cluster",Qfe=`${R1}-${iUe}`,aUe="cluster-alt",Zfe=`${R1}-${aUe}`,jO="parent",KO="note",Jfe="state",$6="----",ede=`${$6}${KO}`,QO=`${$6}${jO}`});function ZO(t="",e=0,r="",n=$6){let i=r!==null&&r.length>0?`${n}${r}`:"";return`${Jfe}-${t}${i}-${e}`}function G6(t,e,r){if(!e.id||e.id==="</join></fork>"||e.id==="</choice>")return;e.cssClasses&&(Array.isArray(e.cssCompiledStyles)||(e.cssCompiledStyles=[]),e.cssClasses.split(" ").forEach(i=>{if(r.get(i)){let a=r.get(i);e.cssCompiledStyles=[...e.cssCompiledStyles,...a.styles]}}));let n=t.find(i=>i.id===e.id);n?Object.assign(n,e):t.push(e)}function oUe(t){return t?.classes?.join(" ")??""}function lUe(t){return t?.styles??[]}var V6,xf,sUe,tde,N1,rde,nde=N(()=>{"use strict";zt();vt();gr();z6();V6=new Map,xf=0;o(ZO,"stateDomId");sUe=o((t,e,r,n,i,a,s,l)=>{Y.trace("items",e),e.forEach(u=>{switch(u.stmt){case L1:N1(t,u,r,n,i,a,s,l);break;case Rp:N1(t,u,r,n,i,a,s,l);break;case Eb:{N1(t,u.state1,r,n,i,a,s,l),N1(t,u.state2,r,n,i,a,s,l);let h={id:"edge"+xf,start:u.state1.id,end:u.state2.id,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:GO,labelStyle:"",label:Ze.sanitizeText(u.description,me()),arrowheadStyle:VO,labelpos:UO,labelType:HO,thickness:WO,classes:XO,look:s};i.push(h),xf++}break}})},"setupDoc"),tde=o((t,e=O6)=>{let r=e;if(t.doc)for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir");o(G6,"insertOrUpdateNode");o(oUe,"getClassesFromDbInfo");o(lUe,"getStylesFromDbInfo");N1=o((t,e,r,n,i,a,s,l)=>{let u=e.id,h=r.get(u),f=oUe(h),d=lUe(h);if(Y.info("dataFetcher parsedItem",e,h,d),u!=="root"){let p=B6;e.start===!0?p=Hfe:e.start===!1&&(p=Wfe),e.type!==Rp&&(p=e.type),V6.get(u)||V6.set(u,{id:u,shape:p,description:Ze.sanitizeText(u,me()),cssClasses:`${f} ${Xfe}`,cssStyles:d});let m=V6.get(u);e.description&&(Array.isArray(m.description)?(m.shape=F6,m.description.push(e.description)):m.description?.length>0?(m.shape=F6,m.description===u?m.description=[e.description]:m.description=[m.description,e.description]):(m.shape=B6,m.description=e.description),m.description=Ze.sanitizeTextOrArray(m.description,me())),m.description?.length===1&&m.shape===F6&&(m.type==="group"?m.shape=YO:m.shape=B6),!m.type&&e.doc&&(Y.info("Setting cluster for XCX",u,tde(e)),m.type="group",m.isGroup=!0,m.dir=tde(e),m.shape=e.type===P6?qO:YO,m.cssClasses=`${m.cssClasses} ${Qfe} ${a?Zfe:""}`);let g={labelStyle:"",shape:m.shape,label:m.description,cssClasses:m.cssClasses,cssCompiledStyles:[],cssStyles:m.cssStyles,id:u,dir:m.dir,domId:ZO(u,xf),type:m.type,isGroup:m.type==="group",padding:8,rx:10,ry:10,look:s};if(g.shape===qO&&(g.label=""),t&&t.id!=="root"&&(Y.trace("Setting node ",u," to be child of its parent ",t.id),g.parentId=t.id),g.centerLabel=!0,e.note){let y={labelStyle:"",shape:qfe,label:e.note.text,cssClasses:Kfe,cssStyles:[],cssCompilesStyles:[],id:u+ede+"-"+xf,domId:ZO(u,xf,KO),type:m.type,isGroup:m.type==="group",padding:me().flowchart.padding,look:s,position:e.note.position},v=u+QO,x={labelStyle:"",shape:Yfe,label:e.note.text,cssClasses:m.cssClasses,cssStyles:[],id:u+QO,domId:ZO(u,xf,jO),type:"group",isGroup:!0,padding:16,look:s,position:e.note.position};xf++,x.id=v,y.parentId=v,G6(n,x,l),G6(n,y,l),G6(n,g,l);let b=u,w=y.id;e.note.position==="left of"&&(b=y.id,w=u),i.push({id:b+"-"+w,start:b,end:w,arrowhead:"none",arrowTypeEnd:"",style:GO,labelStyle:"",classes:jfe,arrowheadStyle:VO,labelpos:UO,labelType:HO,thickness:WO,look:s})}else G6(n,g,l)}e.doc&&(Y.trace("Adding nodes children "),sUe(e,e.doc,r,n,i,!a,s,l))},"dataFetcher"),rde=o(()=>{V6.clear(),xf=0},"reset")});var JO,cUe,uUe,ide,eP=N(()=>{"use strict";zt();vt();gm();Yd();$m();ir();z6();JO=o((t,e=O6)=>{if(!t.doc)return e;let r=e;for(let n of t.doc)n.stmt==="dir"&&(r=n.value);return r},"getDir"),cUe=o(function(t,e){return e.db.getClasses()},"getClasses"),uUe=o(async function(t,e,r,n){Y.info("REF0:"),Y.info("Drawing state diagram (v2)",e);let{securityLevel:i,state:a,layout:s}=me();n.db.extract(n.db.getRootDocV2());let l=n.db.getData(),u=yc(e,i);l.type=n.type,l.layoutAlgorithm=s,l.nodeSpacing=a?.nodeSpacing||50,l.rankSpacing=a?.rankSpacing||50,l.markers=["barb"],l.diagramId=e,await Cc(l,u);let h=8;Gt.insertTitle(u,"statediagramTitleText",a?.titleTopMargin??25,n.db.getDiagramTitle()),Ac(u,h,R1,a?.useMaxWidth??!0)},"draw"),ide={getClasses:cUe,draw:uUe,getDir:JO}});function ude(){return new Map}var tP,ade,sde,ode,lde,cde,hUe,fUe,hde,U6,Qo,H6=N(()=>{"use strict";zt();vt();ir();gr();mi();nde();eP();z6();tP="[*]",ade="start",sde=tP,ode="end",lde="color",cde="fill",hUe="bgFill",fUe=",";o(ude,"newClassesList");hde=o(()=>({relations:[],states:new Map,documents:{}}),"newDoc"),U6=o(t=>JSON.parse(JSON.stringify(t)),"clone"),Qo=class{static{o(this,"StateDB")}constructor(e){this.clear(),this.version=e,this.setRootDoc=this.setRootDoc.bind(this),this.getDividerId=this.getDividerId.bind(this),this.setDirection=this.setDirection.bind(this),this.trimColon=this.trimColon.bind(this)}version;nodes=[];edges=[];rootDoc=[];classes=ude();documents={root:hde()};currentDocument=this.documents.root;startEndCount=0;dividerCnt=0;static relationType={AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3};setRootDoc(e){Y.info("Setting root doc",e),this.rootDoc=e,this.version===1?this.extract(e):this.extract(this.getRootDocV2())}getRootDoc(){return this.rootDoc}docTranslator(e,r,n){if(r.stmt===Eb)this.docTranslator(e,r.state1,!0),this.docTranslator(e,r.state2,!1);else if(r.stmt===L1&&(r.id==="[*]"?(r.id=n?e.id+"_start":e.id+"_end",r.start=n):r.id=r.id.trim()),r.doc){let i=[],a=[],s;for(s=0;s<r.doc.length;s++)if(r.doc[s].type===P6){let l=U6(r.doc[s]);l.doc=U6(a),i.push(l),a=[]}else a.push(r.doc[s]);if(i.length>0&&a.length>0){let l={stmt:L1,id:X9(),type:"divider",doc:U6(a)};i.push(U6(l)),r.doc=i}r.doc.forEach(l=>this.docTranslator(r,l,!0))}}getRootDocV2(){return this.docTranslator({id:"root"},{id:"root",doc:this.rootDoc},!0),{id:"root",doc:this.rootDoc}}extract(e){let r;e.doc?r=e.doc:r=e,Y.info(r),this.clear(!0),Y.info("Extract initial document:",r),r.forEach(s=>{switch(Y.warn("Statement",s.stmt),s.stmt){case L1:this.addState(s.id.trim(),s.type,s.doc,s.description,s.note,s.classes,s.styles,s.textStyles);break;case Eb:this.addRelation(s.state1,s.state2,s.description);break;case Gfe:this.addStyleClass(s.id.trim(),s.classes);break;case Vfe:{let l=s.id.trim().split(","),u=s.styleClass.split(",");l.forEach(h=>{let f=this.getState(h);if(f===void 0){let d=h.trim();this.addState(d),f=this.getState(d)}f.styles=u.map(d=>d.replace(/;/g,"")?.trim())})}break;case Ufe:this.setCssClass(s.id.trim(),s.styleClass);break}});let n=this.getStates(),a=me().look;rde(),N1(void 0,this.getRootDocV2(),n,this.nodes,this.edges,!0,a,this.classes),this.nodes.forEach(s=>{if(Array.isArray(s.label)){if(s.description=s.label.slice(1),s.isGroup&&s.description.length>0)throw new Error("Group nodes can only have label. Remove the additional description for node ["+s.id+"]");s.label=s.label[0]}})}addState(e,r=Rp,n=null,i=null,a=null,s=null,l=null,u=null){let h=e?.trim();if(this.currentDocument.states.has(h)?(this.currentDocument.states.get(h).doc||(this.currentDocument.states.get(h).doc=n),this.currentDocument.states.get(h).type||(this.currentDocument.states.get(h).type=r)):(Y.info("Adding state ",h,i),this.currentDocument.states.set(h,{id:h,descriptions:[],type:r,doc:n,note:a,classes:[],styles:[],textStyles:[]})),i&&(Y.info("Setting state description",h,i),typeof i=="string"&&this.addDescription(h,i.trim()),typeof i=="object"&&i.forEach(f=>this.addDescription(h,f.trim()))),a){let f=this.currentDocument.states.get(h);f.note=a,f.note.text=Ze.sanitizeText(f.note.text,me())}s&&(Y.info("Setting state classes",h,s),(typeof s=="string"?[s]:s).forEach(d=>this.setCssClass(h,d.trim()))),l&&(Y.info("Setting state styles",h,l),(typeof l=="string"?[l]:l).forEach(d=>this.setStyle(h,d.trim()))),u&&(Y.info("Setting state styles",h,l),(typeof u=="string"?[u]:u).forEach(d=>this.setTextStyle(h,d.trim())))}clear(e){this.nodes=[],this.edges=[],this.documents={root:hde()},this.currentDocument=this.documents.root,this.startEndCount=0,this.classes=ude(),e||Ar()}getState(e){return this.currentDocument.states.get(e)}getStates(){return this.currentDocument.states}logDocuments(){Y.info("Documents = ",this.documents)}getRelations(){return this.currentDocument.relations}startIdIfNeeded(e=""){let r=e;return e===tP&&(this.startEndCount++,r=`${ade}${this.startEndCount}`),r}startTypeIfNeeded(e="",r=Rp){return e===tP?ade:r}endIdIfNeeded(e=""){let r=e;return e===sde&&(this.startEndCount++,r=`${ode}${this.startEndCount}`),r}endTypeIfNeeded(e="",r=Rp){return e===sde?ode:r}addRelationObjs(e,r,n){let i=this.startIdIfNeeded(e.id.trim()),a=this.startTypeIfNeeded(e.id.trim(),e.type),s=this.startIdIfNeeded(r.id.trim()),l=this.startTypeIfNeeded(r.id.trim(),r.type);this.addState(i,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),this.addState(s,l,r.doc,r.description,r.note,r.classes,r.styles,r.textStyles),this.currentDocument.relations.push({id1:i,id2:s,relationTitle:Ze.sanitizeText(n,me())})}addRelation(e,r,n){if(typeof e=="object")this.addRelationObjs(e,r,n);else{let i=this.startIdIfNeeded(e.trim()),a=this.startTypeIfNeeded(e),s=this.endIdIfNeeded(r.trim()),l=this.endTypeIfNeeded(r);this.addState(i,a),this.addState(s,l),this.currentDocument.relations.push({id1:i,id2:s,title:Ze.sanitizeText(n,me())})}}addDescription(e,r){let n=this.currentDocument.states.get(e),i=r.startsWith(":")?r.replace(":","").trim():r;n.descriptions.push(Ze.sanitizeText(i,me()))}cleanupLabel(e){return e.substring(0,1)===":"?e.substr(2).trim():e.trim()}getDividerId(){return this.dividerCnt++,"divider-id-"+this.dividerCnt}addStyleClass(e,r=""){this.classes.has(e)||this.classes.set(e,{id:e,styles:[],textStyles:[]});let n=this.classes.get(e);r?.split(fUe).forEach(i=>{let a=i.replace(/([^;]*);/,"$1").trim();if(RegExp(lde).exec(i)){let l=a.replace(cde,hUe).replace(lde,cde);n.textStyles.push(l)}n.styles.push(a)})}getClasses(){return this.classes}setCssClass(e,r){e.split(",").forEach(n=>{let i=this.getState(n);if(i===void 0){let a=n.trim();this.addState(a),i=this.getState(a)}i.classes.push(r)})}setStyle(e,r){let n=this.getState(e);n!==void 0&&n.styles.push(r)}setTextStyle(e,r){let n=this.getState(e);n!==void 0&&n.textStyles.push(r)}getDirectionStatement(){return this.rootDoc.find(e=>e.stmt===zO)}getDirection(){return this.getDirectionStatement()?.value??zfe}setDirection(e){let r=this.getDirectionStatement();r?r.value=e:this.rootDoc.unshift({stmt:zO,value:e})}trimColon(e){return e&&e[0]===":"?e.substr(1).trim():e.trim()}getData(){let e=me();return{nodes:this.nodes,edges:this.edges,other:{},config:e,direction:JO(this.getRootDocV2())}}getConfig(){return me().state}getAccTitle=Rr;setAccTitle=Lr;getAccDescription=Mr;setAccDescription=Nr;setDiagramTitle=$r;getDiagramTitle=Ir}});var dUe,W6,rP=N(()=>{"use strict";dUe=o(t=>`
+defs #statediagram-barbEnd {
+ fill: ${t.transitionColor};
+ stroke: ${t.transitionColor};
+ }
+g.stateGroup text {
+ fill: ${t.nodeBorder};
+ stroke: none;
+ font-size: 10px;
+}
+g.stateGroup text {
+ fill: ${t.textColor};
+ stroke: none;
+ font-size: 10px;
+
+}
+g.stateGroup .state-title {
+ font-weight: bolder;
+ fill: ${t.stateLabelColor};
+}
+
+g.stateGroup rect {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+}
+
+g.stateGroup line {
+ stroke: ${t.lineColor};
+ stroke-width: 1;
+}
+
+.transition {
+ stroke: ${t.transitionColor};
+ stroke-width: 1;
+ fill: none;
+}
+
+.stateGroup .composit {
+ fill: ${t.background};
+ border-bottom: 1px
+}
+
+.stateGroup .alt-composit {
+ fill: #e0e0e0;
+ border-bottom: 1px
+}
+
+.state-note {
+ stroke: ${t.noteBorderColor};
+ fill: ${t.noteBkgColor};
+
+ text {
+ fill: ${t.noteTextColor};
+ stroke: none;
+ font-size: 10px;
+ }
+}
+
+.stateLabel .box {
+ stroke: none;
+ stroke-width: 0;
+ fill: ${t.mainBkg};
+ opacity: 0.5;
+}
+
+.edgeLabel .label rect {
+ fill: ${t.labelBackgroundColor};
+ opacity: 0.5;
+}
+.edgeLabel {
+ background-color: ${t.edgeLabelBackground};
+ p {
+ background-color: ${t.edgeLabelBackground};
+ }
+ rect {
+ opacity: 0.5;
+ background-color: ${t.edgeLabelBackground};
+ fill: ${t.edgeLabelBackground};
+ }
+ text-align: center;
+}
+.edgeLabel .label text {
+ fill: ${t.transitionLabelColor||t.tertiaryTextColor};
+}
+.label div .edgeLabel {
+ color: ${t.transitionLabelColor||t.tertiaryTextColor};
+}
+
+.stateLabel text {
+ fill: ${t.stateLabelColor};
+ font-size: 10px;
+ font-weight: bold;
+}
+
+.node circle.state-start {
+ fill: ${t.specialStateColor};
+ stroke: ${t.specialStateColor};
+}
+
+.node .fork-join {
+ fill: ${t.specialStateColor};
+ stroke: ${t.specialStateColor};
+}
+
+.node circle.state-end {
+ fill: ${t.innerEndBackground};
+ stroke: ${t.background};
+ stroke-width: 1.5
+}
+.end-state-inner {
+ fill: ${t.compositeBackground||t.background};
+ // stroke: ${t.background};
+ stroke-width: 1.5
+}
+
+.node rect {
+ fill: ${t.stateBkg||t.mainBkg};
+ stroke: ${t.stateBorder||t.nodeBorder};
+ stroke-width: 1px;
+}
+.node polygon {
+ fill: ${t.mainBkg};
+ stroke: ${t.stateBorder||t.nodeBorder};;
+ stroke-width: 1px;
+}
+#statediagram-barbEnd {
+ fill: ${t.lineColor};
+}
+
+.statediagram-cluster rect {
+ fill: ${t.compositeTitleBackground};
+ stroke: ${t.stateBorder||t.nodeBorder};
+ stroke-width: 1px;
+}
+
+.cluster-label, .nodeLabel {
+ color: ${t.stateLabelColor};
+ // line-height: 1;
+}
+
+.statediagram-cluster rect.outer {
+ rx: 5px;
+ ry: 5px;
+}
+.statediagram-state .divider {
+ stroke: ${t.stateBorder||t.nodeBorder};
+}
+
+.statediagram-state .title-state {
+ rx: 5px;
+ ry: 5px;
+}
+.statediagram-cluster.statediagram-cluster .inner {
+ fill: ${t.compositeBackground||t.background};
+}
+.statediagram-cluster.statediagram-cluster-alt .inner {
+ fill: ${t.altBackground?t.altBackground:"#efefef"};
+}
+
+.statediagram-cluster .inner {
+ rx:0;
+ ry:0;
+}
+
+.statediagram-state rect.basic {
+ rx: 5px;
+ ry: 5px;
+}
+.statediagram-state rect.divider {
+ stroke-dasharray: 10,10;
+ fill: ${t.altBackground?t.altBackground:"#efefef"};
+}
+
+.note-edge {
+ stroke-dasharray: 5;
+}
+
+.statediagram-note rect {
+ fill: ${t.noteBkgColor};
+ stroke: ${t.noteBorderColor};
+ stroke-width: 1px;
+ rx: 0;
+ ry: 0;
+}
+.statediagram-note rect {
+ fill: ${t.noteBkgColor};
+ stroke: ${t.noteBorderColor};
+ stroke-width: 1px;
+ rx: 0;
+ ry: 0;
+}
+
+.statediagram-note text {
+ fill: ${t.noteTextColor};
+}
+
+.statediagram-note .nodeLabel {
+ color: ${t.noteTextColor};
+}
+.statediagram .edgeLabel {
+ color: red; // ${t.noteTextColor};
+}
+
+#dependencyStart, #dependencyEnd {
+ fill: ${t.lineColor};
+ stroke: ${t.lineColor};
+ stroke-width: 1;
+}
+
+.statediagramTitleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: ${t.textColor};
+}
+`,"getStyles"),W6=dUe});var nP,pUe,mUe,fde,gUe,dde,pde=N(()=>{"use strict";nP={},pUe=o((t,e)=>{nP[t]=e},"set"),mUe=o(t=>nP[t],"get"),fde=o(()=>Object.keys(nP),"keys"),gUe=o(()=>fde().length,"size"),dde={get:mUe,set:pUe,keys:fde,size:gUe}});var yUe,vUe,xUe,bUe,gde,wUe,TUe,kUe,EUe,iP,mde,yde,vde=N(()=>{"use strict";dr();pde();H6();ir();gr();zt();vt();yUe=o(t=>t.append("circle").attr("class","start-state").attr("r",me().state.sizeUnit).attr("cx",me().state.padding+me().state.sizeUnit).attr("cy",me().state.padding+me().state.sizeUnit),"drawStartState"),vUe=o(t=>t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",me().state.textHeight).attr("class","divider").attr("x2",me().state.textHeight*2).attr("y1",0).attr("y2",0),"drawDivider"),xUe=o((t,e)=>{let r=t.append("text").attr("x",2*me().state.padding).attr("y",me().state.textHeight+2*me().state.padding).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.id),n=r.node().getBBox();return t.insert("rect",":first-child").attr("x",me().state.padding).attr("y",me().state.padding).attr("width",n.width+2*me().state.padding).attr("height",n.height+2*me().state.padding).attr("rx",me().state.radius),r},"drawSimpleState"),bUe=o((t,e)=>{let r=o(function(p,m,g){let y=p.append("tspan").attr("x",2*me().state.padding).text(m);g||y.attr("dy",me().state.textHeight)},"addTspan"),i=t.append("text").attr("x",2*me().state.padding).attr("y",me().state.textHeight+1.3*me().state.padding).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),a=i.height,s=t.append("text").attr("x",me().state.padding).attr("y",a+me().state.padding*.4+me().state.dividerMargin+me().state.textHeight).attr("class","state-description"),l=!0,u=!0;e.descriptions.forEach(function(p){l||(r(s,p,u),u=!1),l=!1});let h=t.append("line").attr("x1",me().state.padding).attr("y1",me().state.padding+a+me().state.dividerMargin/2).attr("y2",me().state.padding+a+me().state.dividerMargin/2).attr("class","descr-divider"),f=s.node().getBBox(),d=Math.max(f.width,i.width);return h.attr("x2",d+3*me().state.padding),t.insert("rect",":first-child").attr("x",me().state.padding).attr("y",me().state.padding).attr("width",d+2*me().state.padding).attr("height",f.height+a+2*me().state.padding).attr("rx",me().state.radius),t},"drawDescrState"),gde=o((t,e,r)=>{let n=me().state.padding,i=2*me().state.padding,a=t.node().getBBox(),s=a.width,l=a.x,u=t.append("text").attr("x",0).attr("y",me().state.titleShift).attr("font-size",me().state.fontSize).attr("class","state-title").text(e.id),f=u.node().getBBox().width+i,d=Math.max(f,s);d===s&&(d=d+i);let p,m=t.node().getBBox();e.doc,p=l-n,f>s&&(p=(s-d)/2+n),Math.abs(l-m.x)<n&&f>s&&(p=l-(f-s)/2);let g=1-me().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",g).attr("class",r?"alt-composit":"composit").attr("width",d).attr("height",m.height+me().state.textHeight+me().state.titleShift+1).attr("rx","0"),u.attr("x",p+n),f<=s&&u.attr("x",l+(d-i)/2-f/2+n),t.insert("rect",":first-child").attr("x",p).attr("y",me().state.titleShift-me().state.textHeight-me().state.padding).attr("width",d).attr("height",me().state.textHeight*3).attr("rx",me().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",me().state.titleShift-me().state.textHeight-me().state.padding).attr("width",d).attr("height",m.height+3+2*me().state.textHeight).attr("rx",me().state.radius),t},"addTitleAndBox"),wUe=o(t=>(t.append("circle").attr("class","end-state-outer").attr("r",me().state.sizeUnit+me().state.miniPadding).attr("cx",me().state.padding+me().state.sizeUnit+me().state.miniPadding).attr("cy",me().state.padding+me().state.sizeUnit+me().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",me().state.sizeUnit).attr("cx",me().state.padding+me().state.sizeUnit+2).attr("cy",me().state.padding+me().state.sizeUnit+2)),"drawEndState"),TUe=o((t,e)=>{let r=me().state.forkWidth,n=me().state.forkHeight;if(e.parentId){let i=r;r=n,n=i}return t.append("rect").style("stroke","black").style("fill","black").attr("width",r).attr("height",n).attr("x",me().state.padding).attr("y",me().state.padding)},"drawForkJoinState"),kUe=o((t,e,r,n)=>{let i=0,a=n.append("text");a.style("text-anchor","start"),a.attr("class","noteText");let s=t.replace(/\r\n/g,"<br/>");s=s.replace(/\n/g,"<br/>");let l=s.split(Ze.lineBreakRegex),u=1.25*me().state.noteMargin;for(let h of l){let f=h.trim();if(f.length>0){let d=a.append("tspan");if(d.text(f),u===0){let p=d.node().getBBox();u+=p.height}i+=u,d.attr("x",e+me().state.noteMargin),d.attr("y",r+i+1.25*me().state.noteMargin)}}return{textWidth:a.node().getBBox().width,textHeight:i}},"_drawLongText"),EUe=o((t,e)=>{e.attr("class","state-note");let r=e.append("rect").attr("x",0).attr("y",me().state.padding),n=e.append("g"),{textWidth:i,textHeight:a}=kUe(t,0,0,n);return r.attr("height",a+2*me().state.noteMargin),r.attr("width",i+me().state.noteMargin*2),r},"drawNote"),iP=o(function(t,e){let r=e.id,n={id:r,label:e.id,width:0,height:0},i=t.append("g").attr("id",r).attr("class","stateGroup");e.type==="start"&&yUe(i),e.type==="end"&&wUe(i),(e.type==="fork"||e.type==="join")&&TUe(i,e),e.type==="note"&&EUe(e.note.text,i),e.type==="divider"&&vUe(i),e.type==="default"&&e.descriptions.length===0&&xUe(i,e),e.type==="default"&&e.descriptions.length>0&&bUe(i,e);let a=i.node().getBBox();return n.width=a.width+2*me().state.padding,n.height=a.height+2*me().state.padding,dde.set(r,n),n},"drawState"),mde=0,yde=o(function(t,e,r){let n=o(function(u){switch(u){case Qo.relationType.AGGREGATION:return"aggregation";case Qo.relationType.EXTENSION:return"extension";case Qo.relationType.COMPOSITION:return"composition";case Qo.relationType.DEPENDENCY:return"dependency"}},"getRelationType");e.points=e.points.filter(u=>!Number.isNaN(u.y));let i=e.points,a=wl().x(function(u){return u.x}).y(function(u){return u.y}).curve(Do),s=t.append("path").attr("d",a(i)).attr("id","edge"+mde).attr("class","transition"),l="";if(me().state.arrowMarkerAbsolute&&(l=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,l=l.replace(/\(/g,"\\("),l=l.replace(/\)/g,"\\)")),s.attr("marker-end","url("+l+"#"+n(Qo.relationType.DEPENDENCY)+"End)"),r.title!==void 0){let u=t.append("g").attr("class","stateLabel"),{x:h,y:f}=Gt.calcLabelPosition(e.points),d=Ze.getRows(r.title),p=0,m=[],g=0,y=0;for(let b=0;b<=d.length;b++){let w=u.append("text").attr("text-anchor","middle").text(d[b]).attr("x",h).attr("y",f+p),C=w.node().getBBox();g=Math.max(g,C.width),y=Math.min(y,C.x),Y.info(C.x,h,f+p),p===0&&(p=w.node().getBBox().height,Y.info("Title height",p,f)),m.push(w)}let v=p*d.length;if(d.length>1){let b=(d.length-1)*p*.5;m.forEach((w,C)=>w.attr("y",f+C*p-b)),v=p*d.length}let x=u.node().getBBox();u.insert("rect",":first-child").attr("class","box").attr("x",h-g/2-me().state.padding/2).attr("y",f-v/2-me().state.padding/2-3.5).attr("width",g+me().state.padding).attr("height",v+me().state.padding),Y.info(x)}mde++},"drawEdge")});var fo,aP,SUe,CUe,AUe,_Ue,xde,bde,wde=N(()=>{"use strict";dr();gR();Vo();vt();gr();vde();zt();Ei();aP={},SUe=o(function(){},"setConf"),CUe=o(function(t){t.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"insertMarkers"),AUe=o(function(t,e,r,n){fo=me().state;let i=me().securityLevel,a;i==="sandbox"&&(a=Ge("#i"+e));let s=i==="sandbox"?Ge(a.nodes()[0].contentDocument.body):Ge("body"),l=i==="sandbox"?a.nodes()[0].contentDocument:document;Y.debug("Rendering diagram "+t);let u=s.select(`[id='${e}']`);CUe(u);let h=n.db.getRootDoc();xde(h,u,void 0,!1,s,l,n);let f=fo.padding,d=u.node().getBBox(),p=d.width+f*2,m=d.height+f*2,g=p*1.75;vn(u,m,g,fo.useMaxWidth),u.attr("viewBox",`${d.x-fo.padding} ${d.y-fo.padding} `+p+" "+m)},"draw"),_Ue=o(t=>t?t.length*fo.fontSizeFactor:1,"getLabelWidth"),xde=o((t,e,r,n,i,a,s)=>{let l=new sn({compound:!0,multigraph:!0}),u,h=!0;for(u=0;u<t.length;u++)if(t[u].stmt==="relation"){h=!1;break}r?l.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:h?1:fo.edgeLengthFactor,nodeSep:h?1:50,isMultiGraph:!0}):l.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:h?1:fo.edgeLengthFactor,nodeSep:h?1:50,ranker:"tight-tree",isMultiGraph:!0}),l.setDefaultEdgeLabel(function(){return{}});let f=s.db.getStates(),d=s.db.getRelations(),p=Object.keys(f),m=!0;for(let b of p){let w=f[b];r&&(w.parentId=r);let C;if(w.doc){let T=e.append("g").attr("id",w.id).attr("class","stateGroup");if(C=xde(w.doc,T,w.id,!n,i,a,s),m){T=gde(T,w,n);let E=T.node().getBBox();C.width=E.width,C.height=E.height+fo.padding/2,aP[w.id]={y:fo.compositTitleSize}}else{let E=T.node().getBBox();C.width=E.width,C.height=E.height}}else C=iP(e,w,l);if(w.note){let T={descriptions:[],id:w.id+"-note",note:w.note,type:"note"},E=iP(e,T,l);w.note.position==="left of"?(l.setNode(C.id+"-note",E),l.setNode(C.id,C)):(l.setNode(C.id,C),l.setNode(C.id+"-note",E)),l.setParent(C.id,C.id+"-group"),l.setParent(C.id+"-note",C.id+"-group")}else l.setNode(C.id,C)}Y.debug("Count=",l.nodeCount(),l);let g=0;d.forEach(function(b){g++,Y.debug("Setting edge",b),l.setEdge(b.id1,b.id2,{relation:b,width:_Ue(b.title),height:fo.labelHeight*Ze.getRows(b.title).length,labelpos:"c"},"id"+g)}),R2(l),Y.debug("Graph after layout",l.nodes());let y=e.node();l.nodes().forEach(function(b){b!==void 0&&l.node(b)!==void 0?(Y.warn("Node "+b+": "+JSON.stringify(l.node(b))),i.select("#"+y.id+" #"+b).attr("transform","translate("+(l.node(b).x-l.node(b).width/2)+","+(l.node(b).y+(aP[b]?aP[b].y:0)-l.node(b).height/2)+" )"),i.select("#"+y.id+" #"+b).attr("data-x-shift",l.node(b).x-l.node(b).width/2),a.querySelectorAll("#"+y.id+" #"+b+" .divider").forEach(C=>{let T=C.parentElement,E=0,A=0;T&&(T.parentElement&&(E=T.parentElement.getBBox().width),A=parseInt(T.getAttribute("data-x-shift"),10),Number.isNaN(A)&&(A=0)),C.setAttribute("x1",0-A+8),C.setAttribute("x2",E-A-8)})):Y.debug("No Node "+b+": "+JSON.stringify(l.node(b)))});let v=y.getBBox();l.edges().forEach(function(b){b!==void 0&&l.edge(b)!==void 0&&(Y.debug("Edge "+b.v+" -> "+b.w+": "+JSON.stringify(l.edge(b))),yde(e,l.edge(b),l.edge(b).relation))}),v=y.getBBox();let x={id:r||"root",label:r||"root",width:0,height:0};return x.width=v.width+2*fo.padding,x.height=v.height+2*fo.padding,Y.debug("Doc rendered",x,l),x},"renderDoc"),bde={setConf:SUe,draw:AUe}});var Tde={};hr(Tde,{diagram:()=>DUe});var DUe,kde=N(()=>{"use strict";$O();H6();rP();wde();DUe={parser:I6,get db(){return new Qo(1)},renderer:bde,styles:W6,init:o(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var Cde={};hr(Cde,{diagram:()=>MUe});var MUe,Ade=N(()=>{"use strict";$O();H6();rP();eP();MUe={parser:I6,get db(){return new Qo(2)},renderer:ide,styles:W6,init:o(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")}});var sP,Lde,Rde=N(()=>{"use strict";sP=function(){var t=o(function(d,p,m,g){for(m=m||{},g=d.length;g--;m[d[g]]=p);return m},"o"),e=[6,8,10,11,12,14,16,17,18],r=[1,9],n=[1,10],i=[1,11],a=[1,12],s=[1,13],l=[1,14],u={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:o(function(p,m,g,y,v,x,b){var w=x.length-1;switch(v){case 1:return x[w-1];case 2:this.$=[];break;case 3:x[w-1].push(x[w]),this.$=x[w-1];break;case 4:case 5:this.$=x[w];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(x[w].substr(6)),this.$=x[w].substr(6);break;case 9:this.$=x[w].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=x[w].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(x[w].substr(8)),this.$=x[w].substr(8);break;case 13:y.addTask(x[w-1],x[w]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:r,12:n,14:i,16:a,17:s,18:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:r,12:n,14:i,16:a,17:s,18:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:o(function(p,m){if(m.recoverable)this.trace(p);else{var g=new Error(p);throw g.hash=m,g}},"parseError"),parse:o(function(p){var m=this,g=[0],y=[],v=[null],x=[],b=this.table,w="",C=0,T=0,E=0,A=2,S=1,_=x.slice.call(arguments,1),I=Object.create(this.lexer),D={yy:{}};for(var k in this.yy)Object.prototype.hasOwnProperty.call(this.yy,k)&&(D.yy[k]=this.yy[k]);I.setInput(p,D.yy),D.yy.lexer=I,D.yy.parser=this,typeof I.yylloc>"u"&&(I.yylloc={});var L=I.yylloc;x.push(L);var R=I.options&&I.options.ranges;typeof D.yy.parseError=="function"?this.parseError=D.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function O(K){g.length=g.length-2*K,v.length=v.length-K,x.length=x.length-K}o(O,"popStack");function M(){var K;return K=y.pop()||I.lex()||S,typeof K!="number"&&(K instanceof Array&&(y=K,K=y.pop()),K=m.symbols_[K]||K),K}o(M,"lex");for(var B,F,P,z,$,H,Q={},j,ie,ne,le;;){if(P=g[g.length-1],this.defaultActions[P]?z=this.defaultActions[P]:((B===null||typeof B>"u")&&(B=M()),z=b[P]&&b[P][B]),typeof z>"u"||!z.length||!z[0]){var he="";le=[];for(j in b[P])this.terminals_[j]&&j>A&&le.push("'"+this.terminals_[j]+"'");I.showPosition?he="Parse error on line "+(C+1)+`:
+`+I.showPosition()+`
+Expecting `+le.join(", ")+", got '"+(this.terminals_[B]||B)+"'":he="Parse error on line "+(C+1)+": Unexpected "+(B==S?"end of input":"'"+(this.terminals_[B]||B)+"'"),this.parseError(he,{text:I.match,token:this.terminals_[B]||B,line:I.yylineno,loc:L,expected:le})}if(z[0]instanceof Array&&z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+P+", token: "+B);switch(z[0]){case 1:g.push(B),v.push(I.yytext),x.push(I.yylloc),g.push(z[1]),B=null,F?(B=F,F=null):(T=I.yyleng,w=I.yytext,C=I.yylineno,L=I.yylloc,E>0&&E--);break;case 2:if(ie=this.productions_[z[1]][1],Q.$=v[v.length-ie],Q._$={first_line:x[x.length-(ie||1)].first_line,last_line:x[x.length-1].last_line,first_column:x[x.length-(ie||1)].first_column,last_column:x[x.length-1].last_column},R&&(Q._$.range=[x[x.length-(ie||1)].range[0],x[x.length-1].range[1]]),H=this.performAction.apply(Q,[w,T,C,D.yy,z[1],v,x].concat(_)),typeof H<"u")return H;ie&&(g=g.slice(0,-1*ie*2),v=v.slice(0,-1*ie),x=x.slice(0,-1*ie)),g.push(this.productions_[z[1]][0]),v.push(Q.$),x.push(Q._$),ne=b[g[g.length-2]][g[g.length-1]],g.push(ne);break;case 3:return!0}}return!0},"parse")},h=function(){var d={EOF:1,parseError:o(function(m,g){if(this.yy.parser)this.yy.parser.parseError(m,g);else throw new Error(m)},"parseError"),setInput:o(function(p,m){return this.yy=m||this.yy||{},this._input=p,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var p=this._input[0];this.yytext+=p,this.yyleng++,this.offset++,this.match+=p,this.matched+=p;var m=p.match(/(?:\r\n?|\n).*/g);return m?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),p},"input"),unput:o(function(p){var m=p.length,g=p.split(/(?:\r\n?|\n)/g);this._input=p+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-m),this.offset-=m;var y=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),g.length-1&&(this.yylineno-=g.length-1);var v=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:g?(g.length===y.length?this.yylloc.first_column:0)+y[y.length-g.length].length-g[0].length:this.yylloc.first_column-m},this.options.ranges&&(this.yylloc.range=[v[0],v[0]+this.yyleng-m]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(p){this.unput(this.match.slice(p))},"less"),pastInput:o(function(){var p=this.matched.substr(0,this.matched.length-this.match.length);return(p.length>20?"...":"")+p.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var p=this.match;return p.length<20&&(p+=this._input.substr(0,20-p.length)),(p.substr(0,20)+(p.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var p=this.pastInput(),m=new Array(p.length+1).join("-");return p+this.upcomingInput()+`
+`+m+"^"},"showPosition"),test_match:o(function(p,m){var g,y,v;if(this.options.backtrack_lexer&&(v={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(v.yylloc.range=this.yylloc.range.slice(0))),y=p[0].match(/(?:\r\n?|\n).*/g),y&&(this.yylineno+=y.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:y?y[y.length-1].length-y[y.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+p[0].length},this.yytext+=p[0],this.match+=p[0],this.matches=p,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(p[0].length),this.matched+=p[0],g=this.performAction.call(this,this.yy,this,m,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),g)return g;if(this._backtrack){for(var x in v)this[x]=v[x];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var p,m,g,y;this._more||(this.yytext="",this.match="");for(var v=this._currentRules(),x=0;x<v.length;x++)if(g=this._input.match(this.rules[v[x]]),g&&(!m||g[0].length>m[0].length)){if(m=g,y=x,this.options.backtrack_lexer){if(p=this.test_match(g,v[x]),p!==!1)return p;if(this._backtrack){m=!1;continue}else return!1}else if(!this.options.flex)break}return m?(p=this.test_match(m,v[y]),p!==!1?p:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var m=this.next();return m||this.lex()},"lex"),begin:o(function(m){this.conditionStack.push(m)},"begin"),popState:o(function(){var m=this.conditionStack.length-1;return m>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(m){return m=this.conditionStack.length-1-Math.abs(m||0),m>=0?this.conditionStack[m]:"INITIAL"},"topState"),pushState:o(function(m){this.begin(m)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(m,g,y,v){var x=v;switch(y){case 0:break;case 1:break;case 2:return 10;case 3:break;case 4:break;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.begin("acc_descr"),14;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}};return d}();u.lexer=h;function f(){this.yy={}}return o(f,"Parser"),f.prototype=u,u.Parser=f,new f}();sP.parser=sP;Lde=sP});var M1,oP,Sb,Cb,BUe,FUe,$Ue,zUe,GUe,VUe,UUe,Nde,HUe,lP,Mde=N(()=>{"use strict";zt();mi();M1="",oP=[],Sb=[],Cb=[],BUe=o(function(){oP.length=0,Sb.length=0,M1="",Cb.length=0,Ar()},"clear"),FUe=o(function(t){M1=t,oP.push(t)},"addSection"),$Ue=o(function(){return oP},"getSections"),zUe=o(function(){let t=Nde(),e=100,r=0;for(;!t&&r<e;)t=Nde(),r++;return Sb.push(...Cb),Sb},"getTasks"),GUe=o(function(){let t=[];return Sb.forEach(r=>{r.people&&t.push(...r.people)}),[...new Set(t)].sort()},"updateActors"),VUe=o(function(t,e){let r=e.substr(1).split(":"),n=0,i=[];r.length===1?(n=Number(r[0]),i=[]):(n=Number(r[0]),i=r[1].split(","));let a=i.map(l=>l.trim()),s={section:M1,type:M1,people:a,task:t,score:n};Cb.push(s)},"addTask"),UUe=o(function(t){let e={section:M1,type:M1,description:t,task:t,classes:[]};Sb.push(e)},"addTaskOrg"),Nde=o(function(){let t=o(function(r){return Cb[r].processed},"compileTask"),e=!0;for(let[r,n]of Cb.entries())t(r),e=e&&n.processed;return e},"compileTasks"),HUe=o(function(){return GUe()},"getActors"),lP={getConfig:o(()=>me().journey,"getConfig"),clear:BUe,setDiagramTitle:$r,getDiagramTitle:Ir,setAccTitle:Lr,getAccTitle:Rr,setAccDescription:Nr,getAccDescription:Mr,addSection:FUe,getSections:$Ue,getTasks:zUe,addTask:VUe,addTaskOrg:UUe,getActors:HUe}});var WUe,Ide,Ode=N(()=>{"use strict";WUe=o(t=>`.label {
+ font-family: ${t.fontFamily};
+ color: ${t.textColor};
+ }
+ .mouth {
+ stroke: #666;
+ }
+
+ line {
+ stroke: ${t.textColor}
+ }
+
+ .legend {
+ fill: ${t.textColor};
+ font-family: ${t.fontFamily};
+ }
+
+ .label text {
+ fill: #333;
+ }
+ .label {
+ color: ${t.textColor}
+ }
+
+ .face {
+ ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};
+ stroke: #999;
+ }
+
+ .node rect,
+ .node circle,
+ .node ellipse,
+ .node polygon,
+ .node path {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+ stroke-width: 1px;
+ }
+
+ .node .label {
+ text-align: center;
+ }
+ .node.clickable {
+ cursor: pointer;
+ }
+
+ .arrowheadPath {
+ fill: ${t.arrowheadColor};
+ }
+
+ .edgePath .path {
+ stroke: ${t.lineColor};
+ stroke-width: 1.5px;
+ }
+
+ .flowchart-link {
+ stroke: ${t.lineColor};
+ fill: none;
+ }
+
+ .edgeLabel {
+ background-color: ${t.edgeLabelBackground};
+ rect {
+ opacity: 0.5;
+ }
+ text-align: center;
+ }
+
+ .cluster rect {
+ }
+
+ .cluster text {
+ fill: ${t.titleColor};
+ }
+
+ div.mermaidTooltip {
+ position: absolute;
+ text-align: center;
+ max-width: 200px;
+ padding: 2px;
+ font-family: ${t.fontFamily};
+ font-size: 12px;
+ background: ${t.tertiaryColor};
+ border: 1px solid ${t.border2};
+ border-radius: 2px;
+ pointer-events: none;
+ z-index: 100;
+ }
+
+ .task-type-0, .section-type-0 {
+ ${t.fillType0?`fill: ${t.fillType0}`:""};
+ }
+ .task-type-1, .section-type-1 {
+ ${t.fillType0?`fill: ${t.fillType1}`:""};
+ }
+ .task-type-2, .section-type-2 {
+ ${t.fillType0?`fill: ${t.fillType2}`:""};
+ }
+ .task-type-3, .section-type-3 {
+ ${t.fillType0?`fill: ${t.fillType3}`:""};
+ }
+ .task-type-4, .section-type-4 {
+ ${t.fillType0?`fill: ${t.fillType4}`:""};
+ }
+ .task-type-5, .section-type-5 {
+ ${t.fillType0?`fill: ${t.fillType5}`:""};
+ }
+ .task-type-6, .section-type-6 {
+ ${t.fillType0?`fill: ${t.fillType6}`:""};
+ }
+ .task-type-7, .section-type-7 {
+ ${t.fillType0?`fill: ${t.fillType7}`:""};
+ }
+
+ .actor-0 {
+ ${t.actor0?`fill: ${t.actor0}`:""};
+ }
+ .actor-1 {
+ ${t.actor1?`fill: ${t.actor1}`:""};
+ }
+ .actor-2 {
+ ${t.actor2?`fill: ${t.actor2}`:""};
+ }
+ .actor-3 {
+ ${t.actor3?`fill: ${t.actor3}`:""};
+ }
+ .actor-4 {
+ ${t.actor4?`fill: ${t.actor4}`:""};
+ }
+ .actor-5 {
+ ${t.actor5?`fill: ${t.actor5}`:""};
+ }
+`,"getStyles"),Ide=WUe});var cP,qUe,Bde,Fde,YUe,XUe,Pde,jUe,KUe,$de,QUe,I1,zde=N(()=>{"use strict";dr();Wv();cP=o(function(t,e){return kd(t,e)},"drawRect"),qUe=o(function(t,e){let n=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),i=t.append("g");i.append("circle").attr("cx",e.cx-15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),i.append("circle").attr("cx",e.cx+15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function a(u){let h=bl().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}o(a,"smile");function s(u){let h=bl().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}o(s,"sad");function l(u){u.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return o(l,"ambivalent"),e.score>3?a(i):e.score<3?s(i):l(i),n},"drawFace"),Bde=o(function(t,e){let r=t.append("circle");return r.attr("cx",e.cx),r.attr("cy",e.cy),r.attr("class","actor-"+e.pos),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("r",e.r),r.class!==void 0&&r.attr("class",r.class),e.title!==void 0&&r.append("title").text(e.title),r},"drawCircle"),Fde=o(function(t,e){return Nq(t,e)},"drawText"),YUe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");n.attr("points",r(e.x,e.y,50,20,7)),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,Fde(t,e)},"drawLabel"),XUe=o(function(t,e,r){let n=t.append("g"),i=Tl();i.x=e.x,i.y=e.y,i.fill=e.fill,i.width=r.width*e.taskCount+r.diagramMarginX*(e.taskCount-1),i.height=r.height,i.class="journey-section section-type-"+e.num,i.rx=3,i.ry=3,cP(n,i),$de(r)(e.text,n,i.x,i.y,i.width,i.height,{class:"journey-section section-type-"+e.num},r,e.colour)},"drawSection"),Pde=-1,jUe=o(function(t,e,r){let n=e.x+r.width/2,i=t.append("g");Pde++;let a=300+5*30;i.append("line").attr("id","task"+Pde).attr("x1",n).attr("y1",e.y).attr("x2",n).attr("y2",a).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),qUe(i,{cx:n,cy:300+(5-e.score)*30,score:e.score});let s=Tl();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=r.width,s.height=r.height,s.class="task task-type-"+e.num,s.rx=3,s.ry=3,cP(i,s);let l=e.x+14;e.people.forEach(u=>{let h=e.actors[u].color,f={cx:l,cy:e.y,r:7,fill:h,stroke:"#000",title:u,pos:e.actors[u].position};Bde(i,f),l+=10}),$de(r)(e.task,i,s.x,s.y,s.width,s.height,{class:"task"},r,e.colour)},"drawTask"),KUe=o(function(t,e){q5(t,e)},"drawBackgroundRect"),$de=function(){function t(i,a,s,l,u,h,f,d){let p=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("font-color",d).style("text-anchor","middle").text(i);n(p,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d,p){let{taskFontSize:m,taskFontFamily:g}=d,y=i.split(/<br\s*\/?>/gi);for(let v=0;v<y.length;v++){let x=v*m-m*(y.length-1)/2,b=a.append("text").attr("x",s+u/2).attr("y",l).attr("fill",p).style("text-anchor","middle").style("font-size",m).style("font-family",g);b.append("tspan").attr("x",s+u/2).attr("dy",x).text(y[v]),b.attr("y",l+h/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),n(b,f)}}o(e,"byTspan");function r(i,a,s,l,u,h,f,d){let p=a.append("switch"),g=p.append("foreignObject").attr("x",s).attr("y",l).attr("width",u).attr("height",h).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");g.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(i),e(i,p,s,l,u,h,f,d),n(g,f)}o(r,"byFo");function n(i,a){for(let s in a)s in a&&i.attr(s,a[s])}return o(n,"_setTextAttrs"),function(i){return i.textPlacement==="fo"?r:i.textPlacement==="old"?t:e}}(),QUe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},"initGraphics"),I1={drawRect:cP,drawCircle:Bde,drawSection:XUe,drawText:Fde,drawLabel:YUe,drawTask:jUe,drawBackgroundRect:KUe,initGraphics:QUe}});function JUe(t){let e=me().journey,r=60;Object.keys(ju).forEach(n=>{let i=ju[n].color,a={cx:20,cy:r,r:7,fill:i,stroke:"#000",pos:ju[n].position};I1.drawCircle(t,a);let s={x:40,y:r+7,fill:"#666",text:n,textMargin:e.boxTextMargin|5};I1.drawText(t,s),r+=20})}var ZUe,ju,q6,Np,eHe,Zo,uP,Gde,tHe,hP,Vde=N(()=>{"use strict";dr();zde();zt();Ei();ZUe=o(function(t){Object.keys(t).forEach(function(r){q6[r]=t[r]})},"setConf"),ju={};o(JUe,"drawActorLegend");q6=me().journey,Np=q6.leftMargin,eHe=o(function(t,e,r,n){let i=me().journey,a=me().securityLevel,s;a==="sandbox"&&(s=Ge("#i"+e));let l=a==="sandbox"?Ge(s.nodes()[0].contentDocument.body):Ge("body");Zo.init();let u=l.select("#"+e);I1.initGraphics(u);let h=n.db.getTasks(),f=n.db.getDiagramTitle(),d=n.db.getActors();for(let x in ju)delete ju[x];let p=0;d.forEach(x=>{ju[x]={color:i.actorColours[p%i.actorColours.length],position:p},p++}),JUe(u),Zo.insert(0,0,Np,Object.keys(ju).length*50),tHe(u,h,0);let m=Zo.getBounds();f&&u.append("text").text(f).attr("x",Np).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);let g=m.stopy-m.starty+2*i.diagramMarginY,y=Np+m.stopx+2*i.diagramMarginX;vn(u,g,y,i.useMaxWidth),u.append("line").attr("x1",Np).attr("y1",i.height*4).attr("x2",y-Np-4).attr("y2",i.height*4).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");let v=f?70:0;u.attr("viewBox",`${m.startx} -25 ${y} ${g+v}`),u.attr("preserveAspectRatio","xMinYMin meet"),u.attr("height",g+v+25)},"draw"),Zo={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:o(function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},"init"),updateVal:o(function(t,e,r,n){t[e]===void 0?t[e]=r:t[e]=n(r,t[e])},"updateVal"),updateBounds:o(function(t,e,r,n){let i=me().journey,a=this,s=0;function l(u){return o(function(f){s++;let d=a.sequenceItems.length-s+1;a.updateVal(f,"starty",e-d*i.boxMargin,Math.min),a.updateVal(f,"stopy",n+d*i.boxMargin,Math.max),a.updateVal(Zo.data,"startx",t-d*i.boxMargin,Math.min),a.updateVal(Zo.data,"stopx",r+d*i.boxMargin,Math.max),u!=="activation"&&(a.updateVal(f,"startx",t-d*i.boxMargin,Math.min),a.updateVal(f,"stopx",r+d*i.boxMargin,Math.max),a.updateVal(Zo.data,"starty",e-d*i.boxMargin,Math.min),a.updateVal(Zo.data,"stopy",n+d*i.boxMargin,Math.max))},"updateItemBounds")}o(l,"updateFn"),this.sequenceItems.forEach(l())},"updateBounds"),insert:o(function(t,e,r,n){let i=Math.min(t,r),a=Math.max(t,r),s=Math.min(e,n),l=Math.max(e,n);this.updateVal(Zo.data,"startx",i,Math.min),this.updateVal(Zo.data,"starty",s,Math.min),this.updateVal(Zo.data,"stopx",a,Math.max),this.updateVal(Zo.data,"stopy",l,Math.max),this.updateBounds(i,s,a,l)},"insert"),bumpVerticalPos:o(function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},"bumpVerticalPos"),getVerticalPos:o(function(){return this.verticalPos},"getVerticalPos"),getBounds:o(function(){return this.data},"getBounds")},uP=q6.sectionFills,Gde=q6.sectionColours,tHe=o(function(t,e,r){let n=me().journey,i="",a=n.height*2+n.diagramMarginY,s=r+a,l=0,u="#CCC",h="black",f=0;for(let[d,p]of e.entries()){if(i!==p.section){u=uP[l%uP.length],f=l%uP.length,h=Gde[l%Gde.length];let g=0,y=p.section;for(let x=d;x<e.length&&e[x].section==y;x++)g=g+1;let v={x:d*n.taskMargin+d*n.width+Np,y:50,text:p.section,fill:u,num:f,colour:h,taskCount:g};I1.drawSection(t,v,n),i=p.section,l++}let m=p.people.reduce((g,y)=>(ju[y]&&(g[y]=ju[y]),g),{});p.x=d*n.taskMargin+d*n.width+Np,p.y=s,p.width=n.diagramMarginX,p.height=n.diagramMarginY,p.colour=h,p.fill=u,p.num=f,p.actors=m,I1.drawTask(t,p,n),Zo.insert(p.x,p.y,p.x+p.width+n.taskMargin,300+5*30)}},"drawTasks"),hP={setConf:ZUe,draw:eHe}});var Ude={};hr(Ude,{diagram:()=>rHe});var rHe,Hde=N(()=>{"use strict";Rde();Mde();Ode();Vde();rHe={parser:Lde,db:lP,renderer:hP,styles:Ide,init:o(t=>{hP.setConf(t.journey),lP.clear()},"init")}});var dP,Qde,Zde=N(()=>{"use strict";dP=function(){var t=o(function(p,m,g,y){for(g=g||{},y=p.length;y--;g[p[y]]=m);return g},"o"),e=[6,8,10,11,12,14,16,17,20,21],r=[1,9],n=[1,10],i=[1,11],a=[1,12],s=[1,13],l=[1,16],u=[1,17],h={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:o(function(m,g,y,v,x,b,w){var C=b.length-1;switch(x){case 1:return b[C-1];case 2:this.$=[];break;case 3:b[C-1].push(b[C]),this.$=b[C-1];break;case 4:case 5:this.$=b[C];break;case 6:case 7:this.$=[];break;case 8:v.getCommonDb().setDiagramTitle(b[C].substr(6)),this.$=b[C].substr(6);break;case 9:this.$=b[C].trim(),v.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=b[C].trim(),v.getCommonDb().setAccDescription(this.$);break;case 12:v.addSection(b[C].substr(8)),this.$=b[C].substr(8);break;case 15:v.addTask(b[C],0,""),this.$=b[C];break;case 16:v.addEvent(b[C].substr(2)),this.$=b[C];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:r,12:n,14:i,16:a,17:s,18:14,19:15,20:l,21:u},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:r,12:n,14:i,16:a,17:s,18:14,19:15,20:l,21:u},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:o(function(m,g){if(g.recoverable)this.trace(m);else{var y=new Error(m);throw y.hash=g,y}},"parseError"),parse:o(function(m){var g=this,y=[0],v=[],x=[null],b=[],w=this.table,C="",T=0,E=0,A=0,S=2,_=1,I=b.slice.call(arguments,1),D=Object.create(this.lexer),k={yy:{}};for(var L in this.yy)Object.prototype.hasOwnProperty.call(this.yy,L)&&(k.yy[L]=this.yy[L]);D.setInput(m,k.yy),k.yy.lexer=D,k.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var R=D.yylloc;b.push(R);var O=D.options&&D.options.ranges;typeof k.yy.parseError=="function"?this.parseError=k.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function M(X){y.length=y.length-2*X,x.length=x.length-X,b.length=b.length-X}o(M,"popStack");function B(){var X;return X=v.pop()||D.lex()||_,typeof X!="number"&&(X instanceof Array&&(v=X,X=v.pop()),X=g.symbols_[X]||X),X}o(B,"lex");for(var F,P,z,$,H,Q,j={},ie,ne,le,he;;){if(z=y[y.length-1],this.defaultActions[z]?$=this.defaultActions[z]:((F===null||typeof F>"u")&&(F=B()),$=w[z]&&w[z][F]),typeof $>"u"||!$.length||!$[0]){var K="";he=[];for(ie in w[z])this.terminals_[ie]&&ie>S&&he.push("'"+this.terminals_[ie]+"'");D.showPosition?K="Parse error on line "+(T+1)+`:
+`+D.showPosition()+`
+Expecting `+he.join(", ")+", got '"+(this.terminals_[F]||F)+"'":K="Parse error on line "+(T+1)+": Unexpected "+(F==_?"end of input":"'"+(this.terminals_[F]||F)+"'"),this.parseError(K,{text:D.match,token:this.terminals_[F]||F,line:D.yylineno,loc:R,expected:he})}if($[0]instanceof Array&&$.length>1)throw new Error("Parse Error: multiple actions possible at state: "+z+", token: "+F);switch($[0]){case 1:y.push(F),x.push(D.yytext),b.push(D.yylloc),y.push($[1]),F=null,P?(F=P,P=null):(E=D.yyleng,C=D.yytext,T=D.yylineno,R=D.yylloc,A>0&&A--);break;case 2:if(ne=this.productions_[$[1]][1],j.$=x[x.length-ne],j._$={first_line:b[b.length-(ne||1)].first_line,last_line:b[b.length-1].last_line,first_column:b[b.length-(ne||1)].first_column,last_column:b[b.length-1].last_column},O&&(j._$.range=[b[b.length-(ne||1)].range[0],b[b.length-1].range[1]]),Q=this.performAction.apply(j,[C,E,T,k.yy,$[1],x,b].concat(I)),typeof Q<"u")return Q;ne&&(y=y.slice(0,-1*ne*2),x=x.slice(0,-1*ne),b=b.slice(0,-1*ne)),y.push(this.productions_[$[1]][0]),x.push(j.$),b.push(j._$),le=w[y[y.length-2]][y[y.length-1]],y.push(le);break;case 3:return!0}}return!0},"parse")},f=function(){var p={EOF:1,parseError:o(function(g,y){if(this.yy.parser)this.yy.parser.parseError(g,y);else throw new Error(g)},"parseError"),setInput:o(function(m,g){return this.yy=g||this.yy||{},this._input=m,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var m=this._input[0];this.yytext+=m,this.yyleng++,this.offset++,this.match+=m,this.matched+=m;var g=m.match(/(?:\r\n?|\n).*/g);return g?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),m},"input"),unput:o(function(m){var g=m.length,y=m.split(/(?:\r\n?|\n)/g);this._input=m+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-g),this.offset-=g;var v=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),y.length-1&&(this.yylineno-=y.length-1);var x=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:y?(y.length===v.length?this.yylloc.first_column:0)+v[v.length-y.length].length-y[0].length:this.yylloc.first_column-g},this.options.ranges&&(this.yylloc.range=[x[0],x[0]+this.yyleng-g]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(m){this.unput(this.match.slice(m))},"less"),pastInput:o(function(){var m=this.matched.substr(0,this.matched.length-this.match.length);return(m.length>20?"...":"")+m.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var m=this.match;return m.length<20&&(m+=this._input.substr(0,20-m.length)),(m.substr(0,20)+(m.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var m=this.pastInput(),g=new Array(m.length+1).join("-");return m+this.upcomingInput()+`
+`+g+"^"},"showPosition"),test_match:o(function(m,g){var y,v,x;if(this.options.backtrack_lexer&&(x={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(x.yylloc.range=this.yylloc.range.slice(0))),v=m[0].match(/(?:\r\n?|\n).*/g),v&&(this.yylineno+=v.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:v?v[v.length-1].length-v[v.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+m[0].length},this.yytext+=m[0],this.match+=m[0],this.matches=m,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(m[0].length),this.matched+=m[0],y=this.performAction.call(this,this.yy,this,g,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),y)return y;if(this._backtrack){for(var b in x)this[b]=x[b];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var m,g,y,v;this._more||(this.yytext="",this.match="");for(var x=this._currentRules(),b=0;b<x.length;b++)if(y=this._input.match(this.rules[x[b]]),y&&(!g||y[0].length>g[0].length)){if(g=y,v=b,this.options.backtrack_lexer){if(m=this.test_match(y,x[b]),m!==!1)return m;if(this._backtrack){g=!1;continue}else return!1}else if(!this.options.flex)break}return g?(m=this.test_match(g,x[v]),m!==!1?m:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var g=this.next();return g||this.lex()},"lex"),begin:o(function(g){this.conditionStack.push(g)},"begin"),popState:o(function(){var g=this.conditionStack.length-1;return g>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(g){return g=this.conditionStack.length-1-Math.abs(g||0),g>=0?this.conditionStack[g]:"INITIAL"},"topState"),pushState:o(function(g){this.begin(g)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(g,y,v,x){var b=x;switch(v){case 0:break;case 1:break;case 2:return 10;case 3:break;case 4:break;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;break;case 8:return this.popState(),"acc_title_value";break;case 9:return this.begin("acc_descr"),14;break;case 10:return this.popState(),"acc_descr_value";break;case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^:\n]+)/i,/^(?::\s[^:\n]+)/i,/^(?:[^#:\n]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}};return p}();h.lexer=f;function d(){this.yy={}}return o(d,"Parser"),d.prototype=h,h.Parser=d,new d}();dP.parser=dP;Qde=dP});var mP={};hr(mP,{addEvent:()=>ope,addSection:()=>npe,addTask:()=>spe,addTaskOrg:()=>lpe,clear:()=>rpe,default:()=>hHe,getCommonDb:()=>tpe,getSections:()=>ipe,getTasks:()=>ape});var O1,epe,pP,Y6,P1,tpe,rpe,npe,ipe,ape,spe,ope,lpe,Jde,hHe,cpe=N(()=>{"use strict";mi();O1="",epe=0,pP=[],Y6=[],P1=[],tpe=o(()=>qy,"getCommonDb"),rpe=o(function(){pP.length=0,Y6.length=0,O1="",P1.length=0,Ar()},"clear"),npe=o(function(t){O1=t,pP.push(t)},"addSection"),ipe=o(function(){return pP},"getSections"),ape=o(function(){let t=Jde(),e=100,r=0;for(;!t&&r<e;)t=Jde(),r++;return Y6.push(...P1),Y6},"getTasks"),spe=o(function(t,e,r){let n={id:epe++,section:O1,type:O1,task:t,score:e||0,events:r?[r]:[]};P1.push(n)},"addTask"),ope=o(function(t){P1.find(r=>r.id===epe-1).events.push(t)},"addEvent"),lpe=o(function(t){let e={section:O1,type:O1,description:t,task:t,classes:[]};Y6.push(e)},"addTaskOrg"),Jde=o(function(){let t=o(function(r){return P1[r].processed},"compileTask"),e=!0;for(let[r,n]of P1.entries())t(r),e=e&&n.processed;return e},"compileTasks"),hHe={clear:rpe,getCommonDb:tpe,addSection:npe,getSections:ipe,getTasks:ape,addTask:spe,addTaskOrg:lpe,addEvent:ope}});function dpe(t,e){t.each(function(){var r=Ge(this),n=r.text().split(/(\s+|<br>)/).reverse(),i,a=[],s=1.1,l=r.attr("y"),u=parseFloat(r.attr("dy")),h=r.text(null).append("tspan").attr("x",0).attr("y",l).attr("dy",u+"em");for(let f=0;f<n.length;f++)i=n[n.length-1-f],a.push(i),h.text(a.join(" ").trim()),(h.node().getComputedTextLength()>e||i==="<br>")&&(a.pop(),h.text(a.join(" ").trim()),i==="<br>"?a=[""]:a=[i],h=r.append("tspan").attr("x",0).attr("y",l).attr("dy",s+"em").text(i))})}var fHe,X6,dHe,pHe,hpe,mHe,gHe,upe,yHe,vHe,xHe,gP,fpe,bHe,wHe,THe,kHe,bf,ppe=N(()=>{"use strict";dr();fHe=12,X6=o(function(t,e){let r=t.append("rect");return r.attr("x",e.x),r.attr("y",e.y),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("width",e.width),r.attr("height",e.height),r.attr("rx",e.rx),r.attr("ry",e.ry),e.class!==void 0&&r.attr("class",e.class),r},"drawRect"),dHe=o(function(t,e){let n=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",15).attr("stroke-width",2).attr("overflow","visible"),i=t.append("g");i.append("circle").attr("cx",e.cx-15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),i.append("circle").attr("cx",e.cx+15/3).attr("cy",e.cy-15/3).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666");function a(u){let h=bl().startAngle(Math.PI/2).endAngle(3*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}o(a,"smile");function s(u){let h=bl().startAngle(3*Math.PI/2).endAngle(5*(Math.PI/2)).innerRadius(7.5).outerRadius(6.8181818181818175);u.append("path").attr("class","mouth").attr("d",h).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}o(s,"sad");function l(u){u.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return o(l,"ambivalent"),e.score>3?a(i):e.score<3?s(i):l(i),n},"drawFace"),pHe=o(function(t,e){let r=t.append("circle");return r.attr("cx",e.cx),r.attr("cy",e.cy),r.attr("class","actor-"+e.pos),r.attr("fill",e.fill),r.attr("stroke",e.stroke),r.attr("r",e.r),r.class!==void 0&&r.attr("class",r.class),e.title!==void 0&&r.append("title").text(e.title),r},"drawCircle"),hpe=o(function(t,e){let r=e.text.replace(/<br\s*\/?>/gi," "),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.attr("class","legend"),n.style("text-anchor",e.anchor),e.class!==void 0&&n.attr("class",e.class);let i=n.append("tspan");return i.attr("x",e.x+e.textMargin*2),i.text(r),n},"drawText"),mHe=o(function(t,e){function r(i,a,s,l,u){return i+","+a+" "+(i+s)+","+a+" "+(i+s)+","+(a+l-u)+" "+(i+s-u*1.2)+","+(a+l)+" "+i+","+(a+l)}o(r,"genPoints");let n=t.append("polygon");n.attr("points",r(e.x,e.y,50,20,7)),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,hpe(t,e)},"drawLabel"),gHe=o(function(t,e,r){let n=t.append("g"),i=gP();i.x=e.x,i.y=e.y,i.fill=e.fill,i.width=r.width,i.height=r.height,i.class="journey-section section-type-"+e.num,i.rx=3,i.ry=3,X6(n,i),fpe(r)(e.text,n,i.x,i.y,i.width,i.height,{class:"journey-section section-type-"+e.num},r,e.colour)},"drawSection"),upe=-1,yHe=o(function(t,e,r){let n=e.x+r.width/2,i=t.append("g");upe++;let a=300+5*30;i.append("line").attr("id","task"+upe).attr("x1",n).attr("y1",e.y).attr("x2",n).attr("y2",a).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),dHe(i,{cx:n,cy:300+(5-e.score)*30,score:e.score});let s=gP();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=r.width,s.height=r.height,s.class="task task-type-"+e.num,s.rx=3,s.ry=3,X6(i,s),fpe(r)(e.task,i,s.x,s.y,s.width,s.height,{class:"task"},r,e.colour)},"drawTask"),vHe=o(function(t,e){X6(t,{x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,class:"rect"}).lower()},"drawBackgroundRect"),xHe=o(function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",width:100,height:100,textMargin:0,rx:0,ry:0}},"getTextObj"),gP=o(function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},"getNoteRect"),fpe=function(){function t(i,a,s,l,u,h,f,d){let p=a.append("text").attr("x",s+u/2).attr("y",l+h/2+5).style("font-color",d).style("text-anchor","middle").text(i);n(p,f)}o(t,"byText");function e(i,a,s,l,u,h,f,d,p){let{taskFontSize:m,taskFontFamily:g}=d,y=i.split(/<br\s*\/?>/gi);for(let v=0;v<y.length;v++){let x=v*m-m*(y.length-1)/2,b=a.append("text").attr("x",s+u/2).attr("y",l).attr("fill",p).style("text-anchor","middle").style("font-size",m).style("font-family",g);b.append("tspan").attr("x",s+u/2).attr("dy",x).text(y[v]),b.attr("y",l+h/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),n(b,f)}}o(e,"byTspan");function r(i,a,s,l,u,h,f,d){let p=a.append("switch"),g=p.append("foreignObject").attr("x",s).attr("y",l).attr("width",u).attr("height",h).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");g.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(i),e(i,p,s,l,u,h,f,d),n(g,f)}o(r,"byFo");function n(i,a){for(let s in a)s in a&&i.attr(s,a[s])}return o(n,"_setTextAttrs"),function(i){return i.textPlacement==="fo"?r:i.textPlacement==="old"?t:e}}(),bHe=o(function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},"initGraphics");o(dpe,"wrap");wHe=o(function(t,e,r,n){let i=r%fHe-1,a=t.append("g");e.section=i,a.attr("class",(e.class?e.class+" ":"")+"timeline-node "+("section-"+i));let s=a.append("g"),l=a.append("g"),h=l.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(dpe,e.width).node().getBBox(),f=n.fontSize?.replace?n.fontSize.replace("px",""):n.fontSize;return e.height=h.height+f*1.1*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,l.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),kHe(s,e,i,n),e},"drawNode"),THe=o(function(t,e,r){let n=t.append("g"),a=n.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(dpe,e.width).node().getBBox(),s=r.fontSize?.replace?r.fontSize.replace("px",""):r.fontSize;return n.remove(),a.height+s*1.1*.5+e.padding},"getVirtualNodeHeight"),kHe=o(function(t,e,r){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${-e.height+2*5} q0,-5 5,-5 h${e.width-2*5} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+r).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},"defaultBkg"),bf={drawRect:X6,drawCircle:pHe,drawSection:gHe,drawText:hpe,drawLabel:mHe,drawTask:yHe,drawBackgroundRect:vHe,getTextObj:xHe,getNoteRect:gP,initGraphics:bHe,drawNode:wHe,getVirtualNodeHeight:THe}});var EHe,mpe,SHe,gpe,ype=N(()=>{"use strict";dr();ppe();vt();zt();Ei();EHe=o(function(t,e,r,n){let i=me(),a=i.leftMargin??50;Y.debug("timeline",n.db);let s=i.securityLevel,l;s==="sandbox"&&(l=Ge("#i"+e));let h=(s==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body")).select("#"+e);h.append("g");let f=n.db.getTasks(),d=n.db.getCommonDb().getDiagramTitle();Y.debug("task",f),bf.initGraphics(h);let p=n.db.getSections();Y.debug("sections",p);let m=0,g=0,y=0,v=0,x=50+a,b=50;v=50;let w=0,C=!0;p.forEach(function(_){let I={number:w,descr:_,section:w,width:150,padding:20,maxHeight:m},D=bf.getVirtualNodeHeight(h,I,i);Y.debug("sectionHeight before draw",D),m=Math.max(m,D+20)});let T=0,E=0;Y.debug("tasks.length",f.length);for(let[_,I]of f.entries()){let D={number:_,descr:I,section:I.section,width:150,padding:20,maxHeight:g},k=bf.getVirtualNodeHeight(h,D,i);Y.debug("taskHeight before draw",k),g=Math.max(g,k+20),T=Math.max(T,I.events.length);let L=0;for(let R of I.events){let O={descr:R,section:I.section,number:I.section,width:150,padding:20,maxHeight:50};L+=bf.getVirtualNodeHeight(h,O,i)}E=Math.max(E,L)}Y.debug("maxSectionHeight before draw",m),Y.debug("maxTaskHeight before draw",g),p&&p.length>0?p.forEach(_=>{let I=f.filter(R=>R.section===_),D={number:w,descr:_,section:w,width:200*Math.max(I.length,1)-50,padding:20,maxHeight:m};Y.debug("sectionNode",D);let k=h.append("g"),L=bf.drawNode(k,D,w,i);Y.debug("sectionNode output",L),k.attr("transform",`translate(${x}, ${v})`),b+=m+50,I.length>0&&mpe(h,I,w,x,b,g,i,T,E,m,!1),x+=200*Math.max(I.length,1),b=v,w++}):(C=!1,mpe(h,f,w,x,b,g,i,T,E,m,!0));let A=h.node().getBBox();Y.debug("bounds",A),d&&h.append("text").text(d).attr("x",A.width/2-a).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),y=C?m+g+150:g+100,h.append("g").attr("class","lineWrapper").append("line").attr("x1",a).attr("y1",y).attr("x2",A.width+3*a).attr("y2",y).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),Ao(void 0,h,i.timeline?.padding??50,i.timeline?.useMaxWidth??!1)},"draw"),mpe=o(function(t,e,r,n,i,a,s,l,u,h,f){for(let d of e){let p={descr:d.task,section:r,number:r,width:150,padding:20,maxHeight:a};Y.debug("taskNode",p);let m=t.append("g").attr("class","taskWrapper"),y=bf.drawNode(m,p,r,s).height;if(Y.debug("taskHeight after draw",y),m.attr("transform",`translate(${n}, ${i})`),a=Math.max(a,y),d.events){let v=t.append("g").attr("class","lineWrapper"),x=a;i+=100,x=x+SHe(t,d.events,r,n,i,s),i-=100,v.append("line").attr("x1",n+190/2).attr("y1",i+a).attr("x2",n+190/2).attr("y2",i+a+(f?a:h)+u+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}n=n+200,f&&!s.timeline?.disableMulticolor&&r++}i=i-10},"drawTasks"),SHe=o(function(t,e,r,n,i,a){let s=0,l=i;i=i+100;for(let u of e){let h={descr:u,section:r,number:r,width:150,padding:20,maxHeight:50};Y.debug("eventNode",h);let f=t.append("g").attr("class","eventWrapper"),p=bf.drawNode(f,h,r,a).height;s=s+p,f.attr("transform",`translate(${n}, ${i})`),i=i+10+p}return i=l,s},"drawEvents"),gpe={setConf:o(()=>{},"setConf"),draw:EHe}});var CHe,AHe,vpe,xpe=N(()=>{"use strict";Ys();CHe=o(t=>{let e="";for(let r=0;r<t.THEME_COLOR_LIMIT;r++)t["lineColor"+r]=t["lineColor"+r]||t["cScaleInv"+r],ca(t["lineColor"+r])?t["lineColor"+r]=Dt(t["lineColor"+r],20):t["lineColor"+r]=Ot(t["lineColor"+r],20);for(let r=0;r<t.THEME_COLOR_LIMIT;r++){let n=""+(17-3*r);e+=`
+ .section-${r-1} rect, .section-${r-1} path, .section-${r-1} circle, .section-${r-1} path {
+ fill: ${t["cScale"+r]};
+ }
+ .section-${r-1} text {
+ fill: ${t["cScaleLabel"+r]};
+ }
+ .node-icon-${r-1} {
+ font-size: 40px;
+ color: ${t["cScaleLabel"+r]};
+ }
+ .section-edge-${r-1}{
+ stroke: ${t["cScale"+r]};
+ }
+ .edge-depth-${r-1}{
+ stroke-width: ${n};
+ }
+ .section-${r-1} line {
+ stroke: ${t["cScaleInv"+r]} ;
+ stroke-width: 3;
+ }
+
+ .lineWrapper line{
+ stroke: ${t["cScaleLabel"+r]} ;
+ }
+
+ .disabled, .disabled circle, .disabled text {
+ fill: lightgray;
+ }
+ .disabled text {
+ fill: #efefef;
+ }
+ `}return e},"genSections"),AHe=o(t=>`
+ .edge {
+ stroke-width: 3;
+ }
+ ${CHe(t)}
+ .section-root rect, .section-root path, .section-root circle {
+ fill: ${t.git0};
+ }
+ .section-root text {
+ fill: ${t.gitBranchLabel0};
+ }
+ .icon-container {
+ height:100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ .edge {
+ fill: none;
+ }
+ .eventWrapper {
+ filter: brightness(120%);
+ }
+`,"getStyles"),vpe=AHe});var bpe={};hr(bpe,{diagram:()=>_He});var _He,wpe=N(()=>{"use strict";Zde();cpe();ype();xpe();_He={db:mP,renderer:gpe,parser:Qde,styles:vpe}});var yP,Epe,Spe=N(()=>{"use strict";yP=function(){var t=o(function(C,T,E,A){for(E=E||{},A=C.length;A--;E[C[A]]=T);return E},"o"),e=[1,4],r=[1,13],n=[1,12],i=[1,15],a=[1,16],s=[1,20],l=[1,19],u=[6,7,8],h=[1,26],f=[1,24],d=[1,25],p=[6,7,11],m=[1,6,13,15,16,19,22],g=[1,33],y=[1,34],v=[1,6,7,11,13,15,16,19,22],x={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:o(function(T,E,A,S,_,I,D){var k=I.length-1;switch(_){case 6:case 7:return S;case 8:S.getLogger().trace("Stop NL ");break;case 9:S.getLogger().trace("Stop EOF ");break;case 11:S.getLogger().trace("Stop NL2 ");break;case 12:S.getLogger().trace("Stop EOF2 ");break;case 15:S.getLogger().info("Node: ",I[k].id),S.addNode(I[k-1].length,I[k].id,I[k].descr,I[k].type);break;case 16:S.getLogger().trace("Icon: ",I[k]),S.decorateNode({icon:I[k]});break;case 17:case 21:S.decorateNode({class:I[k]});break;case 18:S.getLogger().trace("SPACELIST");break;case 19:S.getLogger().trace("Node: ",I[k].id),S.addNode(0,I[k].id,I[k].descr,I[k].type);break;case 20:S.decorateNode({icon:I[k]});break;case 25:S.getLogger().trace("node found ..",I[k-2]),this.$={id:I[k-1],descr:I[k-1],type:S.getType(I[k-2],I[k])};break;case 26:this.$={id:I[k],descr:I[k],type:S.nodeType.DEFAULT};break;case 27:S.getLogger().trace("node found ..",I[k-3]),this.$={id:I[k-3],descr:I[k-1],type:S.getType(I[k-2],I[k])};break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:r,7:[1,10],9:9,12:11,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},t(u,[2,3]),{1:[2,2]},t(u,[2,4]),t(u,[2,5]),{1:[2,6],6:r,12:21,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},{6:r,9:22,12:11,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},{6:h,7:f,10:23,11:d},t(p,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:s,22:l}),t(p,[2,18]),t(p,[2,19]),t(p,[2,20]),t(p,[2,21]),t(p,[2,23]),t(p,[2,24]),t(p,[2,26],{19:[1,30]}),{20:[1,31]},{6:h,7:f,10:32,11:d},{1:[2,7],6:r,12:21,13:n,14:14,15:i,16:a,17:17,18:18,19:s,22:l},t(m,[2,14],{7:g,11:y}),t(v,[2,8]),t(v,[2,9]),t(v,[2,10]),t(p,[2,15]),t(p,[2,16]),t(p,[2,17]),{20:[1,35]},{21:[1,36]},t(m,[2,13],{7:g,11:y}),t(v,[2,11]),t(v,[2,12]),{21:[1,37]},t(p,[2,25]),t(p,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(T,E){if(E.recoverable)this.trace(T);else{var A=new Error(T);throw A.hash=E,A}},"parseError"),parse:o(function(T){var E=this,A=[0],S=[],_=[null],I=[],D=this.table,k="",L=0,R=0,O=0,M=2,B=1,F=I.slice.call(arguments,1),P=Object.create(this.lexer),z={yy:{}};for(var $ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,$)&&(z.yy[$]=this.yy[$]);P.setInput(T,z.yy),z.yy.lexer=P,z.yy.parser=this,typeof P.yylloc>"u"&&(P.yylloc={});var H=P.yylloc;I.push(H);var Q=P.options&&P.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function j(ae){A.length=A.length-2*ae,_.length=_.length-ae,I.length=I.length-ae}o(j,"popStack");function ie(){var ae;return ae=S.pop()||P.lex()||B,typeof ae!="number"&&(ae instanceof Array&&(S=ae,ae=S.pop()),ae=E.symbols_[ae]||ae),ae}o(ie,"lex");for(var ne,le,he,K,X,te,J={},se,ue,Z,Se;;){if(he=A[A.length-1],this.defaultActions[he]?K=this.defaultActions[he]:((ne===null||typeof ne>"u")&&(ne=ie()),K=D[he]&&D[he][ne]),typeof K>"u"||!K.length||!K[0]){var ce="";Se=[];for(se in D[he])this.terminals_[se]&&se>M&&Se.push("'"+this.terminals_[se]+"'");P.showPosition?ce="Parse error on line "+(L+1)+`:
+`+P.showPosition()+`
+Expecting `+Se.join(", ")+", got '"+(this.terminals_[ne]||ne)+"'":ce="Parse error on line "+(L+1)+": Unexpected "+(ne==B?"end of input":"'"+(this.terminals_[ne]||ne)+"'"),this.parseError(ce,{text:P.match,token:this.terminals_[ne]||ne,line:P.yylineno,loc:H,expected:Se})}if(K[0]instanceof Array&&K.length>1)throw new Error("Parse Error: multiple actions possible at state: "+he+", token: "+ne);switch(K[0]){case 1:A.push(ne),_.push(P.yytext),I.push(P.yylloc),A.push(K[1]),ne=null,le?(ne=le,le=null):(R=P.yyleng,k=P.yytext,L=P.yylineno,H=P.yylloc,O>0&&O--);break;case 2:if(ue=this.productions_[K[1]][1],J.$=_[_.length-ue],J._$={first_line:I[I.length-(ue||1)].first_line,last_line:I[I.length-1].last_line,first_column:I[I.length-(ue||1)].first_column,last_column:I[I.length-1].last_column},Q&&(J._$.range=[I[I.length-(ue||1)].range[0],I[I.length-1].range[1]]),te=this.performAction.apply(J,[k,R,L,z.yy,K[1],_,I].concat(F)),typeof te<"u")return te;ue&&(A=A.slice(0,-1*ue*2),_=_.slice(0,-1*ue),I=I.slice(0,-1*ue)),A.push(this.productions_[K[1]][0]),_.push(J.$),I.push(J._$),Z=D[A[A.length-2]][A[A.length-1]],A.push(Z);break;case 3:return!0}}return!0},"parse")},b=function(){var C={EOF:1,parseError:o(function(E,A){if(this.yy.parser)this.yy.parser.parseError(E,A);else throw new Error(E)},"parseError"),setInput:o(function(T,E){return this.yy=E||this.yy||{},this._input=T,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var T=this._input[0];this.yytext+=T,this.yyleng++,this.offset++,this.match+=T,this.matched+=T;var E=T.match(/(?:\r\n?|\n).*/g);return E?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),T},"input"),unput:o(function(T){var E=T.length,A=T.split(/(?:\r\n?|\n)/g);this._input=T+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-E),this.offset-=E;var S=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),A.length-1&&(this.yylineno-=A.length-1);var _=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:A?(A.length===S.length?this.yylloc.first_column:0)+S[S.length-A.length].length-A[0].length:this.yylloc.first_column-E},this.options.ranges&&(this.yylloc.range=[_[0],_[0]+this.yyleng-E]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(T){this.unput(this.match.slice(T))},"less"),pastInput:o(function(){var T=this.matched.substr(0,this.matched.length-this.match.length);return(T.length>20?"...":"")+T.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var T=this.match;return T.length<20&&(T+=this._input.substr(0,20-T.length)),(T.substr(0,20)+(T.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var T=this.pastInput(),E=new Array(T.length+1).join("-");return T+this.upcomingInput()+`
+`+E+"^"},"showPosition"),test_match:o(function(T,E){var A,S,_;if(this.options.backtrack_lexer&&(_={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(_.yylloc.range=this.yylloc.range.slice(0))),S=T[0].match(/(?:\r\n?|\n).*/g),S&&(this.yylineno+=S.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:S?S[S.length-1].length-S[S.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+T[0].length},this.yytext+=T[0],this.match+=T[0],this.matches=T,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(T[0].length),this.matched+=T[0],A=this.performAction.call(this,this.yy,this,E,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),A)return A;if(this._backtrack){for(var I in _)this[I]=_[I];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var T,E,A,S;this._more||(this.yytext="",this.match="");for(var _=this._currentRules(),I=0;I<_.length;I++)if(A=this._input.match(this.rules[_[I]]),A&&(!E||A[0].length>E[0].length)){if(E=A,S=I,this.options.backtrack_lexer){if(T=this.test_match(A,_[I]),T!==!1)return T;if(this._backtrack){E=!1;continue}else return!1}else if(!this.options.flex)break}return E?(T=this.test_match(E,_[S]),T!==!1?T:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var E=this.next();return E||this.lex()},"lex"),begin:o(function(E){this.conditionStack.push(E)},"begin"),popState:o(function(){var E=this.conditionStack.length-1;return E>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(E){return E=this.conditionStack.length-1-Math.abs(E||0),E>=0?this.conditionStack[E]:"INITIAL"},"topState"),pushState:o(function(E){this.begin(E)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(E,A,S,_){var I=_;switch(S){case 0:return E.getLogger().trace("Found comment",A.yytext),6;break;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;break;case 4:this.popState();break;case 5:E.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return E.getLogger().trace("SPACELINE"),6;break;case 7:return 7;case 8:return 15;case 9:E.getLogger().trace("end icon"),this.popState();break;case 10:return E.getLogger().trace("Exploding node"),this.begin("NODE"),19;break;case 11:return E.getLogger().trace("Cloud"),this.begin("NODE"),19;break;case 12:return E.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;break;case 13:return E.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;break;case 14:return this.begin("NODE"),19;break;case 15:return this.begin("NODE"),19;break;case 16:return this.begin("NODE"),19;break;case 17:return this.begin("NODE"),19;break;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 23:this.popState();break;case 24:E.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return E.getLogger().trace("description:",A.yytext),"NODE_DESCR";break;case 26:this.popState();break;case 27:return this.popState(),E.getLogger().trace("node end ))"),"NODE_DEND";break;case 28:return this.popState(),E.getLogger().trace("node end )"),"NODE_DEND";break;case 29:return this.popState(),E.getLogger().trace("node end ...",A.yytext),"NODE_DEND";break;case 30:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 31:return this.popState(),E.getLogger().trace("node end (-"),"NODE_DEND";break;case 32:return this.popState(),E.getLogger().trace("node end (-"),"NODE_DEND";break;case 33:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 34:return this.popState(),E.getLogger().trace("node end (("),"NODE_DEND";break;case 35:return E.getLogger().trace("Long description:",A.yytext),20;break;case 36:return E.getLogger().trace("Long description:",A.yytext),20;break}},"anonymous"),rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};return C}();x.lexer=b;function w(){this.yy={}}return o(w,"Parser"),w.prototype=x,x.Parser=w,new w}();yP.parser=yP;Epe=yP});var $l,Cpe,vP,NHe,MHe,IHe,OHe,Vi,PHe,BHe,FHe,$He,zHe,GHe,VHe,Ape,_pe=N(()=>{"use strict";zt();gr();vt();Ya();$l=[],Cpe=0,vP={},NHe=o(()=>{$l=[],Cpe=0,vP={}},"clear"),MHe=o(function(t){for(let e=$l.length-1;e>=0;e--)if($l[e].level<t)return $l[e];return null},"getParent"),IHe=o(()=>$l.length>0?$l[0]:null,"getMindmap"),OHe=o((t,e,r,n)=>{Y.info("addNode",t,e,r,n);let i=me(),a=i.mindmap?.padding??or.mindmap.padding;switch(n){case Vi.ROUNDED_RECT:case Vi.RECT:case Vi.HEXAGON:a*=2}let s={id:Cpe++,nodeId:Tr(e,i),level:t,descr:Tr(r,i),type:n,children:[],width:i.mindmap?.maxNodeWidth??or.mindmap.maxNodeWidth,padding:a},l=MHe(t);if(l)l.children.push(s),$l.push(s);else if($l.length===0)$l.push(s);else throw new Error('There can be only one root. No parent could be found for ("'+s.descr+'")')},"addNode"),Vi={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},PHe=o((t,e)=>{switch(Y.debug("In get type",t,e),t){case"[":return Vi.RECT;case"(":return e===")"?Vi.ROUNDED_RECT:Vi.CLOUD;case"((":return Vi.CIRCLE;case")":return Vi.CLOUD;case"))":return Vi.BANG;case"{{":return Vi.HEXAGON;default:return Vi.DEFAULT}},"getType"),BHe=o((t,e)=>{vP[t]=e},"setElementForId"),FHe=o(t=>{if(!t)return;let e=me(),r=$l[$l.length-1];t.icon&&(r.icon=Tr(t.icon,e)),t.class&&(r.class=Tr(t.class,e))},"decorateNode"),$He=o(t=>{switch(t){case Vi.DEFAULT:return"no-border";case Vi.RECT:return"rect";case Vi.ROUNDED_RECT:return"rounded-rect";case Vi.CIRCLE:return"circle";case Vi.CLOUD:return"cloud";case Vi.BANG:return"bang";case Vi.HEXAGON:return"hexgon";default:return"no-border"}},"type2Str"),zHe=o(()=>Y,"getLogger"),GHe=o(t=>vP[t],"getElementById"),VHe={clear:NHe,addNode:OHe,getMindmap:IHe,nodeType:Vi,getType:PHe,setElementForId:BHe,decorateNode:FHe,type2Str:$He,getLogger:zHe,getElementById:GHe},Ape=VHe});function Wi(t){"@babel/helpers - typeof";return Wi=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Wi(t)}function Mf(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function Dpe(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function If(t,e,r){return e&&Dpe(t.prototype,e),r&&Dpe(t,r),Object.defineProperty(t,"prototype",{writable:!1}),t}function X0e(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function _i(t,e){return HHe(t)||qHe(t,e)||ZP(t,e)||XHe()}function j0e(t){return UHe(t)||WHe(t)||ZP(t)||YHe()}function UHe(t){if(Array.isArray(t))return OP(t)}function HHe(t){if(Array.isArray(t))return t}function WHe(t){if(typeof Symbol<"u"&&t[Symbol.iterator]!=null||t["@@iterator"]!=null)return Array.from(t)}function qHe(t,e){var r=t==null?null:typeof Symbol<"u"&&t[Symbol.iterator]||t["@@iterator"];if(r!=null){var n=[],i=!0,a=!1,s,l;try{for(r=r.call(t);!(i=(s=r.next()).done)&&(n.push(s.value),!(e&&n.length===e));i=!0);}catch(u){a=!0,l=u}finally{try{!i&&r.return!=null&&r.return()}finally{if(a)throw l}}return n}}function ZP(t,e){if(t){if(typeof t=="string")return OP(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if(r==="Object"&&t.constructor&&(r=t.constructor.name),r==="Map"||r==="Set")return Array.from(t);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return OP(t,e)}}function OP(t,e){(e==null||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r<e;r++)n[r]=t[r];return n}function YHe(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
+In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function XHe(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
+In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function mo(t,e){var r=typeof Symbol<"u"&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=ZP(t))||e&&t&&typeof t.length=="number"){r&&(t=r);var n=0,i=o(function(){},"F");return{s:i,n:o(function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},"n"),e:o(function(u){throw u},"e"),f:i}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
+In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var a=!0,s=!1,l;return{s:o(function(){r=r.call(t)},"s"),n:o(function(){var u=r.next();return a=u.done,u},"n"),e:o(function(u){s=!0,l=u},"e"),f:o(function(){try{!a&&r.return!=null&&r.return()}finally{if(s)throw l}},"f")}}function yWe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}function vWe(t,e){return e={exports:{}},t(e,e.exports),e.exports}function SWe(t){for(var e=t.length;e--&&EWe.test(t.charAt(e)););return e}function _We(t){return t&&t.slice(0,CWe(t)+1).replace(AWe,"")}function MWe(t){var e=RWe.call(t,Ab),r=t[Ab];try{t[Ab]=void 0;var n=!0}catch{}var i=NWe.call(t);return n&&(e?t[Ab]=r:delete t[Ab]),i}function BWe(t){return PWe.call(t)}function GWe(t){return t==null?t===void 0?zWe:$We:Npe&&Npe in Object(t)?IWe(t):FWe(t)}function VWe(t){return t!=null&&typeof t=="object"}function WWe(t){return typeof t=="symbol"||UWe(t)&&ame(t)==HWe}function KWe(t){if(typeof t=="number")return t;if(r4(t))return Mpe;if(zp(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=zp(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=DWe(t);var r=YWe.test(t);return r||XWe.test(t)?jWe(t.slice(2),r?2:8):qWe.test(t)?Mpe:+t}function eqe(t,e,r){var n,i,a,s,l,u,h=0,f=!1,d=!1,p=!0;if(typeof t!="function")throw new TypeError(QWe);e=Ipe(e)||0,zp(r)&&(f=!!r.leading,d="maxWait"in r,a=d?ZWe(Ipe(r.maxWait)||0,e):a,p="trailing"in r?!!r.trailing:p);function m(E){var A=n,S=i;return n=i=void 0,h=E,s=t.apply(S,A),s}o(m,"invokeFunc");function g(E){return h=E,l=setTimeout(x,e),f?m(E):s}o(g,"leadingEdge");function y(E){var A=E-u,S=E-h,_=e-A;return d?JWe(_,a-S):_}o(y,"remainingWait");function v(E){var A=E-u,S=E-h;return u===void 0||A>=e||A<0||d&&S>=a}o(v,"shouldInvoke");function x(){var E=xP();if(v(E))return b(E);l=setTimeout(x,y(E))}o(x,"timerExpired");function b(E){return l=void 0,p&&n?m(E):(n=i=void 0,s)}o(b,"trailingEdge");function w(){l!==void 0&&clearTimeout(l),h=0,n=u=i=l=void 0}o(w,"cancel");function C(){return l===void 0?s:b(xP())}o(C,"flush");function T(){var E=xP(),A=v(E);if(n=arguments,i=this,u=E,A){if(l===void 0)return g(u);if(d)return clearTimeout(l),l=setTimeout(x,e),m(u)}return l===void 0&&(l=setTimeout(x,e)),s}return o(T,"debounced"),T.cancel=w,T.flush=C,T}function IS(t,e,r,n,i,a){var s;return si(t)?s=t:s=Q1[t]||Q1.euclidean,e===0&&si(t)?s(i,a):s(e,r,n,i,a)}function qYe(t,e){if(OS(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||r4(t)?!0:WYe.test(t)||!HYe.test(t)||e!=null&&t in Object(e)}function ZYe(t){if(!zp(t))return!1;var e=ame(t);return e==jYe||e==KYe||e==XYe||e==QYe}function tXe(t){return!!e0e&&e0e in t}function aXe(t){if(t!=null){try{return iXe.call(t)}catch{}try{return t+""}catch{}}return""}function pXe(t){if(!zp(t)||rXe(t))return!1;var e=JYe(t)?dXe:lXe;return e.test(sXe(t))}function gXe(t,e){return t?.[e]}function vXe(t,e){var r=yXe(t,e);return mXe(r)?r:void 0}function bXe(){this.__data__=jb?jb(null):{},this.size=0}function TXe(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}function AXe(t){var e=this.__data__;if(jb){var r=e[t];return r===EXe?void 0:r}return CXe.call(e,t)?e[t]:void 0}function RXe(t){var e=this.__data__;return jb?e[t]!==void 0:LXe.call(e,t)}function IXe(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=jb&&e===void 0?MXe:e,this}function ty(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function PXe(){this.__data__=[],this.size=0}function FXe(t,e){return t===e||t!==t&&e!==e}function $Xe(t,e){for(var r=t.length;r--;)if(Lme(t[r][0],e))return r;return-1}function VXe(t){var e=this.__data__,r=PS(e,t);if(r<0)return!1;var n=e.length-1;return r==n?e.pop():GXe.call(e,r,1),--this.size,!0}function HXe(t){var e=this.__data__,r=PS(e,t);return r<0?void 0:e[r][1]}function qXe(t){return PS(this.__data__,t)>-1}function XXe(t,e){var r=this.__data__,n=PS(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this}function ry(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function JXe(){this.size=0,this.__data__={hash:new t0e,map:new(ZXe||KXe),string:new t0e}}function tje(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}function nje(t,e){var r=t.__data__;return rje(e)?r[typeof e=="string"?"string":"hash"]:r.map}function ije(t){var e=BS(this,t).delete(t);return this.size-=e?1:0,e}function sje(t){return BS(this,t).get(t)}function lje(t){return BS(this,t).has(t)}function uje(t,e){var r=BS(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,this}function ny(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function cB(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(fje);var r=o(function(){var n=arguments,i=e?e.apply(this,n):n[0],a=r.cache;if(a.has(i))return a.get(i);var s=t.apply(this,n);return r.cache=a.set(i,s)||a,s},"memoized");return r.cache=new(cB.Cache||Rme),r}function mje(t){var e=dje(t,function(n){return r.size===pje&&r.clear(),n}),r=e.cache;return e}function bje(t,e){for(var r=-1,n=t==null?0:t.length,i=Array(n);++r<n;)i[r]=e(t[r],r,t);return i}function Ime(t){if(typeof t=="string")return t;if(OS(t))return Mme(t,Ime)+"";if(r4(t))return n0e?n0e.call(t):"";var e=t+"";return e=="0"&&1/t==-wje?"-0":e}function kje(t){return t==null?"":Tje(t)}function Eje(t,e){return OS(t)?t:YYe(t,e)?[t]:Nme(Ome(t))}function Cje(t){if(typeof t=="string"||r4(t))return t;var e=t+"";return e=="0"&&1/t==-Sje?"-0":e}function Aje(t,e){e=Pme(e,t);for(var r=0,n=e.length;t!=null&&r<n;)t=t[uB(e[r++])];return r&&r==n?t:void 0}function Dje(t,e,r){var n=t==null?void 0:_je(t,e);return n===void 0?r:n}function Nje(t,e,r){e=="__proto__"&&i0e?i0e(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}function Pje(t,e,r){var n=t[e];(!(Oje.call(t,e)&&Lme(n,r))||r===void 0&&!(e in t))&&Mje(t,e,r)}function zje(t,e){var r=typeof t;return e=e??Fje,!!e&&(r=="number"||r!="symbol"&&$je.test(t))&&t>-1&&t%1==0&&t<e}function Vje(t,e,r,n){if(!zp(t))return t;e=Pme(e,t);for(var i=-1,a=e.length,s=a-1,l=t;l!=null&&++i<a;){var u=uB(e[i]),h=r;if(u==="__proto__"||u==="constructor"||u==="prototype")return t;if(i!=s){var f=l[u];h=n?n(f,u,l):void 0,h===void 0&&(h=zp(f)?f:Gje(e[i+1])?[]:{})}Bje(l,u,h),l=l[u]}return t}function Hje(t,e,r){return t==null?t:Uje(t,e,r)}function qje(t,e){var r=-1,n=t.length;for(e||(e=Array(n));++r<n;)e[r]=t[r];return e}function Xje(t){return OS(t)?Mme(t,uB):r4(t)?[t]:Yje(Nme(Ome(t)))}function fB(t,e,r,n){for(var i=[],a=new J1,s=t.cy(),l=s.hasCompoundNodes(),u=0;u<t.length;u++){var h=t[u];r?i.push(h):l&&n(i,a,h)}for(;i.length>0;){var f=i.shift();e(f),a.add(f.id()),l&&n(i,a,f)}return t}function Fme(t,e,r){if(r.isParent())for(var n=r._private.children,i=0;i<n.length;i++){var a=n[i];e.has(a.id())||t.push(a)}}function $me(t,e,r){if(r.isChild()){var n=r._private.parent;e.has(n.id())||t.push(n)}}function dKe(t,e,r){$me(t,e,r),Fme(t,e,r)}function SP(t){return function(e){var r=this;if(e===void 0&&(e=!0),r.length!==0)if(r.isNode()&&!r.removed()){for(var n=0,i=r[0],a=i._private.edges,s=0;s<a.length;s++){var l=a[s];!e&&l.isLoop()||(n+=t(i,l))}return n}else return}}function F1(t,e){return function(r){for(var n,i=this.nodes(),a=0;a<i.length;a++){var s=i[a],l=s[t](r);l!==void 0&&(n===void 0||e(l,n))&&(n=l)}return n}}function Lb(){return!1}function rS(){return!0}function $S(){for(var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:NKe,e=arguments.length>1?arguments[1]:void 0,r=0;r<u0e.length;r++){var n=u0e[r];this[n]=t[n]||Xme[n]}this.context=e||this.context,this.listeners=[],this.emitting=0}function Jme(t,e,r){var n=r._private,i=n.styleCache=n.styleCache||[],a;return(a=i[t])!=null||(a=i[t]=e(r)),a}function zS(t,e){return t=_f(t),o(function(n){return Jme(t,e,n)},"cachedStyleFunction")}function GS(t,e){t=_f(t);var r=o(function(i){return e.call(i)},"selfFn");return o(function(){var i=this[0];if(i)return Jme(t,r,i)},"cachedPrototypeStyleFunction")}function AP(t,e){var r=t._private,n=r.data.parent?t.parents():null;if(n)for(var i=0;i<n.length;i++){var a=n[i];if(!e(a))return!1}return!0}function dB(t){var e=t.ok,r=t.edgeOkViaNode||t.ok,n=t.parentOk||t.ok;return function(){var i=this.cy();if(!i.styleEnabled())return!0;var a=this[0],s=i.hasCompoundNodes();if(a){var l=a._private;if(!e(a))return!1;if(a.isNode())return!s||AP(a,n);var u=l.source,h=l.target;return r(u)&&(!s||AP(u,r))&&(u===h||r(h)&&(!s||AP(h,r)))}}}function f0e(t){return function(){var e=arguments,r=[];if(e.length===2){var n=e[0],i=e[1];this.on(t.event,n,i)}else if(e.length===1&&si(e[0])){var a=e[0];this.on(t.event,a)}else if(e.length===0||e.length===1&&En(e[0])){for(var s=e.length===1?e[0]:null,l=0;l<this.length;l++){var u=this[l],h=!t.ableField||u._private[t.ableField],f=u._private[t.field]!=t.value;if(t.overrideAble){var d=t.overrideAble(u);if(d!==void 0&&(h=d,!d))return this}h&&(u._private[t.field]=t.value,f&&r.push(u))}var p=this.spawn(r);p.updateStyle(),p.emit(t.event),s&&p.emit(s)}return this}}function ay(t){Cf[t.field]=function(){var e=this[0];if(e){if(t.overrideField){var r=t.overrideField(e);if(r!==void 0)return r}return e._private[t.field]}},Cf[t.on]=f0e({event:t.on,field:t.field,ableField:t.ableField,overrideAble:t.overrideAble,value:!0}),Cf[t.off]=f0e({event:t.off,field:t.field,ableField:t.ableField,overrideAble:t.overrideAble,value:!1})}function g0e(t){return o(function(r){for(var n=[],i=0;i<this.length;i++){var a=this[i],s=a._private[t.attr];s&&n.push(s)}return this.spawn(n,!0).filter(r)},"sourceImpl")}function y0e(t){return o(function(r){var n=[],i=this._private.cy,a=t||{};Zt(r)&&(r=i.$(r));for(var s=0;s<r.length;s++)for(var l=r[s]._private.edges,u=0;u<l.length;u++){var h=l[u],f=h._private.data,d=this.hasElementWithId(f.source)&&r.hasElementWithId(f.target),p=r.hasElementWithId(f.source)&&this.hasElementWithId(f.target),m=d||p;m&&((a.thisIsSrc||a.thisIsTgt)&&(a.thisIsSrc&&!d||a.thisIsTgt&&!p)||n.push(h))}return this.spawn(n,!0)},"edgesWithImpl")}function v0e(t){var e={codirected:!1};return t=rr({},e,t),o(function(n){for(var i=[],a=this.edges(),s=t,l=0;l<a.length;l++)for(var u=a[l],h=u._private,f=h.source,d=f._private.data.id,p=h.data.target,m=f._private.edges,g=0;g<m.length;g++){var y=m[g],v=y._private.data,x=v.target,b=v.source,w=x===p&&b===d,C=d===x&&p===b;(s.codirected&&w||!s.codirected&&(w||C))&&i.push(y)}return this.spawn(i,!0).filter(n)},"parallelEdgesImpl")}function UKe(t,e,r,n){var i=4,a=.001,s=1e-7,l=10,u=11,h=1/(u-1),f=typeof Float32Array<"u";if(arguments.length!==4)return!1;for(var d=0;d<4;++d)if(typeof arguments[d]!="number"||isNaN(arguments[d])||!isFinite(arguments[d]))return!1;t=Math.min(t,1),r=Math.min(r,1),t=Math.max(t,0),r=Math.max(r,0);var p=f?new Float32Array(u):new Array(u);function m(I,D){return 1-3*D+3*I}o(m,"A");function g(I,D){return 3*D-6*I}o(g,"B");function y(I){return 3*I}o(y,"C");function v(I,D,k){return((m(D,k)*I+g(D,k))*I+y(D))*I}o(v,"calcBezier");function x(I,D,k){return 3*m(D,k)*I*I+2*g(D,k)*I+y(D)}o(x,"getSlope");function b(I,D){for(var k=0;k<i;++k){var L=x(D,t,r);if(L===0)return D;var R=v(D,t,r)-I;D-=R/L}return D}o(b,"newtonRaphsonIterate");function w(){for(var I=0;I<u;++I)p[I]=v(I*h,t,r)}o(w,"calcSampleValues");function C(I,D,k){var L,R,O=0;do R=D+(k-D)/2,L=v(R,t,r)-I,L>0?k=R:D=R;while(Math.abs(L)>s&&++O<l);return R}o(C,"binarySubdivide");function T(I){for(var D=0,k=1,L=u-1;k!==L&&p[k]<=I;++k)D+=h;--k;var R=(I-p[k])/(p[k+1]-p[k]),O=D+R*h,M=x(O,t,r);return M>=a?b(I,O):M===0?O:C(I,D,D+h)}o(T,"getTForX");var E=!1;function A(){E=!0,(t!==e||r!==n)&&w()}o(A,"precompute");var S=o(function(D){return E||A(),t===e&&r===n?D:D===0?0:D===1?1:v(T(D),e,n)},"f");S.getControlPoints=function(){return[{x:t,y:e},{x:r,y:n}]};var _="generateBezier("+[t,e,r,n]+")";return S.toString=function(){return _},S}function x0e(t,e,r,n,i){if(n===1||e===r)return r;var a=i(e,r,n);return t==null||((t.roundValue||t.color)&&(a=Math.round(a)),t.min!==void 0&&(a=Math.max(a,t.min)),t.max!==void 0&&(a=Math.min(a,t.max))),a}function b0e(t,e){return t.pfValue!=null||t.value!=null?t.pfValue!=null&&(e==null||e.type.units!=="%")?t.pfValue:t.value:t}function $1(t,e,r,n,i){var a=i!=null?i.type:null;r<0?r=0:r>1&&(r=1);var s=b0e(t,i),l=b0e(e,i);if(Ct(s)&&Ct(l))return x0e(a,s,l,r,n);if(En(s)&&En(l)){for(var u=[],h=0;h<l.length;h++){var f=s[h],d=l[h];if(f!=null&&d!=null){var p=x0e(a,f,d,r,n);u.push(p)}else u.push(d)}return u}}function WKe(t,e,r,n){var i=!n,a=t._private,s=e._private,l=s.easing,u=s.startTime,h=n?t:t.cy(),f=h.style();if(!s.easingImpl)if(l==null)s.easingImpl=dS.linear;else{var d;if(Zt(l)){var p=f.parse("transition-timing-function",l);d=p.value}else d=l;var m,g;Zt(d)?(m=d,g=[]):(m=d[1],g=d.slice(2).map(function(P){return+P})),g.length>0?(m==="spring"&&g.push(s.duration),s.easingImpl=dS[m].apply(null,g)):s.easingImpl=dS[m]}var y=s.easingImpl,v;if(s.duration===0?v=1:v=(r-u)/s.duration,s.applying&&(v=s.progress),v<0?v=0:v>1&&(v=1),s.delay==null){var x=s.startPosition,b=s.position;if(b&&i&&!t.locked()){var w={};Rb(x.x,b.x)&&(w.x=$1(x.x,b.x,v,y)),Rb(x.y,b.y)&&(w.y=$1(x.y,b.y,v,y)),t.position(w)}var C=s.startPan,T=s.pan,E=a.pan,A=T!=null&&n;A&&(Rb(C.x,T.x)&&(E.x=$1(C.x,T.x,v,y)),Rb(C.y,T.y)&&(E.y=$1(C.y,T.y,v,y)),t.emit("pan"));var S=s.startZoom,_=s.zoom,I=_!=null&&n;I&&(Rb(S,_)&&(a.zoom=Yb(a.minZoom,$1(S,_,v,y),a.maxZoom)),t.emit("zoom")),(A||I)&&t.emit("viewport");var D=s.style;if(D&&D.length>0&&i){for(var k=0;k<D.length;k++){var L=D[k],R=L.name,O=L,M=s.startStyle[R],B=f.properties[M.name],F=$1(M,O,v,y,B);f.overrideBypass(t,R,F)}t.emit("style")}}return s.progress=v,v}function Rb(t,e){return t==null||e==null?!1:Ct(t)&&Ct(e)?!0:!!(t&&e)}function qKe(t,e,r,n){var i=e._private;i.started=!0,i.startTime=r-i.progress*i.duration}function w0e(t,e){var r=e._private.aniEles,n=[];function i(f,d){var p=f._private,m=p.animation.current,g=p.animation.queue,y=!1;if(m.length===0){var v=g.shift();v&&m.push(v)}for(var x=o(function(E){for(var A=E.length-1;A>=0;A--){var S=E[A];S()}E.splice(0,E.length)},"callbacks"),b=m.length-1;b>=0;b--){var w=m[b],C=w._private;if(C.stopped){m.splice(b,1),C.hooked=!1,C.playing=!1,C.started=!1,x(C.frames);continue}!C.playing&&!C.applying||(C.playing&&C.applying&&(C.applying=!1),C.started||qKe(f,w,t),WKe(f,w,t,d),C.applying&&(C.applying=!1),x(C.frames),C.step!=null&&C.step(t),w.completed()&&(m.splice(b,1),C.hooked=!1,C.playing=!1,C.started=!1,x(C.completes)),y=!0)}return!d&&m.length===0&&g.length===0&&n.push(f),y}o(i,"stepOne");for(var a=!1,s=0;s<r.length;s++){var l=r[s],u=i(l);a=a||u}var h=i(e,!0);(a||h)&&(r.length>0?e.notify("draw",r):e.notify("draw")),r.unmerge(n),e.emit("step")}function tge(t){this.options=rr({},eQe,tQe,t)}function rge(t){this.options=rr({},rQe,t)}function nge(t){this.options=rr({},nQe,t)}function HS(t){this.options=rr({},iQe,t),this.options.layout=this;var e=this.options.eles.nodes(),r=this.options.eles.edges(),n=r.filter(function(i){var a=i.source().data("id"),s=i.target().data("id"),l=e.some(function(h){return h.data("id")===a}),u=e.some(function(h){return h.data("id")===s});return!l||!u});this.options.eles=this.options.eles.not(n)}function age(t){this.options=rr({},wQe,t)}function gB(t){this.options=rr({},TQe,t)}function sge(t){this.options=rr({},kQe,t)}function oge(t){this.options=rr({},EQe,t)}function lge(t){this.options=t,this.notifications=0}function hge(t,e){e.radius===0?t.lineTo(e.cx,e.cy):t.arc(e.cx,e.cy,e.radius,e.startAngle,e.endAngle,e.counterClockwise)}function vB(t,e,r,n){var i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0;return n===0||e.radius===0?{cx:e.x,cy:e.y,radius:0,startX:e.x,startY:e.y,stopX:e.x,stopY:e.y,startAngle:void 0,endAngle:void 0,counterClockwise:void 0}:(AQe(t,e,r,n,i),{cx:HP,cy:WP,radius:Bp,startX:cge,startY:uge,stopX:qP,stopY:YP,startAngle:qc.ang+Math.PI/2*Fp,endAngle:Jo.ang-Math.PI/2*Fp,counterClockwise:gS})}function fge(t){var e=[];if(t!=null){for(var r=0;r<t.length;r+=2){var n=t[r],i=t[r+1];e.push({x:n,y:i})}return e}}function _Qe(t,e,r){for(var n=o(function(h,f,d,p){return oa(h,f,d,p)},"qbezierAt$1"),i=e._private,a=i.rstyle.bezierPts,s=0;s<t.bezierProjPcts.length;s++){var l=t.bezierProjPcts[s];a.push({x:n(r[0],r[2],r[4],l),y:n(r[1],r[3],r[5],l)})}}function iZe(t,e){for(var r=0;r<e.length;r++){var n=e[r];t.lineTo(n.x,n.y)}}function aZe(t,e,r){for(var n,i=0;i<e.length;i++){var a=e[i];i===0&&(n=a),t.lineTo(a.x,a.y)}t.quadraticCurveTo(r.x,r.y,n.x,n.y)}function $0e(t,e,r){t.beginPath&&t.beginPath();for(var n=e,i=0;i<n.length;i++){var a=n[i];t.lineTo(a.x,a.y)}var s=r,l=r[0];t.moveTo(l.x,l.y);for(var i=1;i<s.length;i++){var a=s[i];t.lineTo(a.x,a.y)}t.closePath&&t.closePath()}function sZe(t,e,r,n,i){t.beginPath&&t.beginPath(),t.arc(r,n,i,0,Math.PI*2,!1);var a=e,s=a[0];t.moveTo(s.x,s.y);for(var l=0;l<a.length;l++){var u=a[l];t.lineTo(u.x,u.y)}t.closePath&&t.closePath()}function oZe(t,e,r,n){t.arc(e,r,n,0,Math.PI*2,!1)}function RP(t,e,r,n,i){var a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:5,s=arguments.length>6?arguments[6]:void 0;t.beginPath(),t.moveTo(e+a,r),t.lineTo(e+n-a,r),t.quadraticCurveTo(e+n,r,e+n,r+a),t.lineTo(e+n,r+i-a),t.quadraticCurveTo(e+n,r+i,e+n-a,r+i),t.lineTo(e+a,r+i),t.quadraticCurveTo(e,r+i,e,r+i-a),t.lineTo(e,r+a),t.quadraticCurveTo(e,r,e+a,r),t.closePath(),s?t.stroke():t.fill()}function z0e(t,e,r){var n=t.createShader(e);if(t.shaderSource(n,r),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(n));return n}function pZe(t,e,r){var n=z0e(t,t.VERTEX_SHADER,e),i=z0e(t,t.FRAGMENT_SHADER,r),a=t.createProgram();if(t.attachShader(a,n),t.attachShader(a,i),t.linkProgram(a),!t.getProgramParameter(a,t.LINK_STATUS))throw new Error("Could not initialize shaders");return a}function mZe(t,e,r){r===void 0&&(r=e);var n=t.makeOffscreenCanvas(e,r),i=n.context=n.getContext("2d");return n.clear=function(){return i.clearRect(0,0,n.width,n.height)},n.clear(),n}function wB(t){var e=t.pixelRatio,r=t.cy.zoom(),n=t.cy.pan();return{zoom:r*e,pan:{x:n.x*e,y:n.y*e}}}function NP(t,e,r,n,i){var a=n*r+e.x,s=i*r+e.y;return s=Math.round(t.canvasHeight-s),[a,s]}function oS(t,e,r){var n=t[0]/255,i=t[1]/255,a=t[2]/255,s=e,l=r||new Array(4);return l[0]=n*s,l[1]=i*s,l[2]=a*s,l[3]=s,l}function lS(t,e){var r=e||new Array(4);return r[0]=(t>>0&255)/255,r[1]=(t>>8&255)/255,r[2]=(t>>16&255)/255,r[3]=(t>>24&255)/255,r}function gZe(t){return t[0]+(t[1]<<8)+(t[2]<<16)+(t[3]<<24)}function yZe(t,e){var r=t.createTexture();return r.buffer=function(n){t.bindTexture(t.TEXTURE_2D,r),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR_MIPMAP_NEAREST),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,n),t.generateMipmap(t.TEXTURE_2D),t.bindTexture(t.TEXTURE_2D,null)},r.deleteTexture=function(){t.deleteTexture(r)},r}function Sge(t,e){switch(e){case"float":return[1,t.FLOAT,4];case"vec2":return[2,t.FLOAT,4];case"vec3":return[3,t.FLOAT,4];case"vec4":return[4,t.FLOAT,4];case"int":return[1,t.INT,4];case"ivec2":return[2,t.INT,4]}}function Cge(t,e,r){switch(e){case t.FLOAT:return new Float32Array(r);case t.INT:return new Int32Array(r)}}function vZe(t,e,r,n,i,a){switch(e){case t.FLOAT:return new Float32Array(r.buffer,a*n,i);case t.INT:return new Int32Array(r.buffer,a*n,i)}}function xZe(t,e,r,n){var i=Sge(t,e),a=_i(i,2),s=a[0],l=a[1],u=Cge(t,l,n),h=t.createBuffer();return t.bindBuffer(t.ARRAY_BUFFER,h),t.bufferData(t.ARRAY_BUFFER,u,t.STATIC_DRAW),l===t.FLOAT?t.vertexAttribPointer(r,s,l,!1,0,0):l===t.INT&&t.vertexAttribIPointer(r,s,l,0,0),t.enableVertexAttribArray(r),t.bindBuffer(t.ARRAY_BUFFER,null),h}function po(t,e,r,n){var i=Sge(t,r),a=_i(i,3),s=a[0],l=a[1],u=a[2],h=Cge(t,l,e*s),f=s*u,d=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,d),t.bufferData(t.ARRAY_BUFFER,e*f,t.DYNAMIC_DRAW),t.enableVertexAttribArray(n),l===t.FLOAT?t.vertexAttribPointer(n,s,l,!1,f,0):l===t.INT&&t.vertexAttribIPointer(n,s,l,f,0),t.vertexAttribDivisor(n,1),t.bindBuffer(t.ARRAY_BUFFER,null);for(var p=new Array(e),m=0;m<e;m++)p[m]=vZe(t,l,h,f,s,m);return d.dataArray=h,d.stride=f,d.size=s,d.getView=function(g){return p[g]},d.setPoint=function(g,y,v){var x=p[g];x[0]=y,x[1]=v},d.bufferSubData=function(g){t.bindBuffer(t.ARRAY_BUFFER,d),g?t.bufferSubData(t.ARRAY_BUFFER,0,h,0,g*s):t.bufferSubData(t.ARRAY_BUFFER,0,h)},d}function bZe(t){var e=t.createFramebuffer();t.bindFramebuffer(t.FRAMEBUFFER,e);var r=t.createTexture();return t.bindTexture(t.TEXTURE_2D,r),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,r,0),t.bindFramebuffer(t.FRAMEBUFFER,null),e.setFramebufferAttachmentSizes=function(n,i){t.bindTexture(t.TEXTURE_2D,r),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,n,i,0,t.RGBA,t.UNSIGNED_BYTE,null)},e}function Gb(){var t=new G0e(9);return G0e!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[5]=0,t[6]=0,t[7]=0),t[0]=1,t[4]=1,t[8]=1,t}function Age(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function wZe(t,e,r){var n=e[0],i=e[1],a=e[2],s=e[3],l=e[4],u=e[5],h=e[6],f=e[7],d=e[8],p=r[0],m=r[1],g=r[2],y=r[3],v=r[4],x=r[5],b=r[6],w=r[7],C=r[8];return t[0]=p*n+m*s+g*h,t[1]=p*i+m*l+g*f,t[2]=p*a+m*u+g*d,t[3]=y*n+v*s+x*h,t[4]=y*i+v*l+x*f,t[5]=y*a+v*u+x*d,t[6]=b*n+w*s+C*h,t[7]=b*i+w*l+C*f,t[8]=b*a+w*u+C*d,t}function DS(t,e,r){var n=e[0],i=e[1],a=e[2],s=e[3],l=e[4],u=e[5],h=e[6],f=e[7],d=e[8],p=r[0],m=r[1];return t[0]=n,t[1]=i,t[2]=a,t[3]=s,t[4]=l,t[5]=u,t[6]=p*n+m*s+h,t[7]=p*i+m*l+f,t[8]=p*a+m*u+d,t}function _ge(t,e,r){var n=e[0],i=e[1],a=e[2],s=e[3],l=e[4],u=e[5],h=e[6],f=e[7],d=e[8],p=Math.sin(r),m=Math.cos(r);return t[0]=m*n+p*s,t[1]=m*i+p*l,t[2]=m*a+p*u,t[3]=m*s-p*n,t[4]=m*l-p*i,t[5]=m*u-p*a,t[6]=h,t[7]=f,t[8]=d,t}function TB(t,e,r){var n=r[0],i=r[1];return t[0]=n*e[0],t[1]=n*e[1],t[2]=n*e[2],t[3]=i*e[3],t[4]=i*e[4],t[5]=i*e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t}function TZe(t,e,r){return t[0]=2/e,t[1]=0,t[2]=0,t[3]=0,t[4]=-2/r,t[5]=0,t[6]=-1,t[7]=1,t[8]=1,t}function SZe(t,e){return t.intersection?t.intersection(e):new Set(j0e(t).filter(function(r){return e.has(r)}))}function H0e(t,e){return"rgba(".concat(t[0],", ").concat(t[1],", ").concat(t[2],", ").concat(e,")")}function DZe(t){var e=t&&t.style&&t.style.backgroundColor||"white";return tme(e)}function LZe(t){{var e=t.render;t.render=function(a){a=a||{};var s=t.cy;t.webgl&&(s.zoom()>bge?(RZe(t),e.call(t,a)):(NZe(t),Rge(t,a,Vb.SCREEN)))}}{var r=t.matchCanvasSize;t.matchCanvasSize=function(a){r.call(t,a),t.pickingFrameBuffer.setFramebufferAttachmentSizes(t.canvasWidth,t.canvasHeight),t.pickingFrameBuffer.needsDraw=!0}}t.findNearestElements=function(a,s,l,u){return FZe(t,a,s)};{var n=t.invalidateCachedZSortedEles;t.invalidateCachedZSortedEles=function(){n.call(t),t.pickingFrameBuffer.needsDraw=!0}}{var i=t.notify;t.notify=function(a,s){i.call(t,a,s),a==="viewport"||a==="bounds"?t.pickingFrameBuffer.needsDraw=!0:a==="background"&&t.eleDrawing.invalidate(s,{type:"node-body"})}}}function RZe(t){var e=t.data.contexts[t.WEBGL];e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}function NZe(t){var e=o(function(n){n.save(),n.setTransform(1,0,0,1,0,0),n.clearRect(0,0,t.canvasWidth,t.canvasHeight),n.restore()},"clear");e(t.data.contexts[t.NODE]),e(t.data.contexts[t.DRAG])}function MZe(t){var e=t.canvasWidth,r=t.canvasHeight,n=wB(t),i=n.pan,a=n.zoom,s=Gb();DS(s,s,[i.x,i.y]),TB(s,s,[a,a]);var l=Gb();TZe(l,e,r);var u=Gb();return wZe(u,l,s),u}function Lge(t,e){var r=t.canvasWidth,n=t.canvasHeight,i=wB(t),a=i.pan,s=i.zoom;e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,r,n),e.translate(a.x,a.y),e.scale(s,s)}function IZe(t,e){t.drawSelectionRectangle(e,function(r){return Lge(t,r)})}function OZe(t){var e=t.data.contexts[t.NODE];e.save(),Lge(t,e),e.strokeStyle="rgba(0, 0, 0, 0.3)",e.beginPath(),e.moveTo(-1e3,0),e.lineTo(1e3,0),e.stroke(),e.beginPath(),e.moveTo(0,-1e3),e.lineTo(0,1e3),e.stroke(),e.restore()}function PZe(t){var e=o(function(i,a,s){for(var l=i.atlasManager.getRenderTypeOpts(a),u=t.data.contexts[t.NODE],h=.125,f=l.atlasCollection.atlases,d=0;d<f.length;d++){var p=f[d],m=p.canvas,g=m.width,y=m.height,v=g*d,x=m.height*s;u.save(),u.scale(h,h),u.drawImage(m,v,x),u.strokeStyle="black",u.rect(v,x,g,y),u.stroke(),u.restore()}},"draw"),r=0;e(t.eleDrawing,"node-body",r++),e(t.eleDrawing,"node-label",r++)}function BZe(t,e,r,n,i){var a,s,l,u,h=wB(t),f=h.pan,d=h.zoom;if(n===void 0||i===void 0){var p=NP(t,f,d,e,r),m=_i(p,2),g=m[0],y=m[1],v=6;a=g-v/2,s=y-v/2,l=v,u=v}else{var x=NP(t,f,d,e,r),b=_i(x,2),w=b[0],C=b[1],T=NP(t,f,d,n,i),E=_i(T,2),A=E[0],S=E[1];a=w,s=S,l=Math.abs(A-w),u=Math.abs(S-C)}if(l===0||u===0)return[];var _=t.data.contexts[t.WEBGL];_.bindFramebuffer(_.FRAMEBUFFER,t.pickingFrameBuffer),t.pickingFrameBuffer.needsDraw&&(_.viewport(0,0,_.canvas.width,_.canvas.height),Rge(t,null,Vb.PICKING),t.pickingFrameBuffer.needsDraw=!1);var I=l*u,D=new Uint8Array(I*4);_.readPixels(a,s,l,u,_.RGBA,_.UNSIGNED_BYTE,D),_.bindFramebuffer(_.FRAMEBUFFER,null);for(var k=new Set,L=0;L<I;L++){var R=D.slice(L*4,L*4+4),O=gZe(R)-1;O>=0&&k.add(O)}return k}function FZe(t,e,r){var n=BZe(t,e,r),i=t.getCachedZSortedEles(),a,s,l=mo(n),u;try{for(l.s();!(u=l.n()).done;){var h=u.value,f=i[h];if(!a&&f.isNode()&&(a=f),!s&&f.isEdge()&&(s=f),a&&s)break}}catch(d){l.e(d)}finally{l.f()}return[a,s].filter(Boolean)}function Rge(t,e,r){var n,i;t.webglDebug&&(i=[],n=performance.now());var a=t.eleDrawing,s=0;if(r.screen&&t.data.canvasNeedsRedraw[t.SELECT_BOX]&&IZe(t,e),t.data.canvasNeedsRedraw[t.NODE]||r.picking){var l=o(function(k,L){L+=1,k.isNode()?(a.drawTexture(k,L,"node-underlay"),a.drawTexture(k,L,"node-body"),a.drawTexture(k,L,"node-label"),a.drawTexture(k,L,"node-overlay")):(a.drawEdgeLine(k,L),a.drawEdgeArrow(k,L,"source"),a.drawEdgeArrow(k,L,"target"),a.drawTexture(k,L,"edge-label"))},"draw"),u=t.data.contexts[t.WEBGL];r.screen?(u.clearColor(0,0,0,0),u.enable(u.BLEND),u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA)):u.disable(u.BLEND),u.clear(u.COLOR_BUFFER_BIT|u.DEPTH_BUFFER_BIT),u.viewport(0,0,u.canvas.width,u.canvas.height);var h=MZe(t),f=t.getCachedZSortedEles();if(s=f.length,a.startFrame(h,i,r),r.screen){for(var d=0;d<f.nondrag.length;d++)l(f.nondrag[d],d);for(var p=0;p<f.drag.length;p++)l(f.drag[p],-1)}else if(r.picking)for(var m=0;m<f.length;m++)l(f[m],m);a.endFrame(),t.data.gc&&(console.log("Garbage Collect!"),t.data.gc=!1,a.gc()),r.screen&&t.webglDebugShowAtlases&&(OZe(t),PZe(t)),t.data.canvasNeedsRedraw[t.NODE]=!1,t.data.canvasNeedsRedraw[t.DRAG]=!1}if(t.webglDebug){var g=performance.now(),y=!0,v=0,x=0,b=mo(i),w;try{for(b.s();!(w=b.n()).done;){var C=w.value;v++,x+=C.count}}catch(D){b.e(D)}finally{b.f()}var T=Math.ceil(g-n),E="".concat(s," elements, ").concat(x," rectangles, ").concat(v," batches");if(y)console.log("WebGL (".concat(r.name,") - ").concat(E));else{console.log("WebGL render (".concat(r.name,") - frame time ").concat(T,"ms")),console.log(" ".concat(E)),console.log("Texture Atlases Used:");var A=a.getAtlasDebugInfo(),S=mo(A),_;try{for(S.s();!(_=S.n()).done;){var I=_.value;console.log(" ".concat(I.type,": ").concat(I.keyCount," keys, ").concat(I.atlasCount," atlases"))}}catch(D){S.e(D)}finally{S.f()}console.log("")}}}function $Ze(t,e){for(var r=atob(t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return new Blob([n],{type:e})}function Y0e(t){var e=t.indexOf(",");return t.substr(e+1)}function Mge(t,e,r){var n=o(function(){return e.toDataURL(r,t.quality)},"getB64Uri");switch(t.output){case"blob-promise":return new ey(function(i,a){try{e.toBlob(function(s){s!=null?i(s):a(new Error("`canvas.toBlob()` sent a null value in its callback"))},r,t.quality)}catch(s){a(s)}});case"blob":return $Ze(Y0e(n()),r);case"base64":return Y0e(n());case"base64uri":default:return n()}}function Oge(t){var e=this,r=e.cy.window(),n=r.document;t.webgl&&(Er.CANVAS_LAYERS=e.CANVAS_LAYERS=4,console.log("webgl rendering enabled")),e.data={canvases:new Array(Er.CANVAS_LAYERS),contexts:new Array(Er.CANVAS_LAYERS),canvasNeedsRedraw:new Array(Er.CANVAS_LAYERS),bufferCanvases:new Array(Er.BUFFER_COUNT),bufferContexts:new Array(Er.CANVAS_LAYERS)};var i="-webkit-tap-highlight-color",a="rgba(0,0,0,0)";e.data.canvasContainer=n.createElement("div");var s=e.data.canvasContainer.style;e.data.canvasContainer.style[i]=a,s.position="relative",s.zIndex="0",s.overflow="hidden";var l=t.cy.container();l.appendChild(e.data.canvasContainer),l.style[i]=a;var u={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};iWe()&&(u["-ms-touch-action"]="none",u["touch-action"]="none");for(var h=0;h<Er.CANVAS_LAYERS;h++){var f=e.data.canvases[h]=n.createElement("canvas"),d=Er.CANVAS_TYPES[h];e.data.contexts[h]=f.getContext(d),e.data.contexts[h]||ai("Could not create canvas of type "+d),Object.keys(u).forEach(function(K){f.style[K]=u[K]}),f.style.position="absolute",f.setAttribute("data-id","layer"+h),f.style.zIndex=String(Er.CANVAS_LAYERS-h),e.data.canvasContainer.appendChild(f),e.data.canvasNeedsRedraw[h]=!1}e.data.topCanvas=e.data.canvases[0],e.data.canvases[Er.NODE].setAttribute("data-id","layer"+Er.NODE+"-node"),e.data.canvases[Er.SELECT_BOX].setAttribute("data-id","layer"+Er.SELECT_BOX+"-selectbox"),e.data.canvases[Er.DRAG].setAttribute("data-id","layer"+Er.DRAG+"-drag"),e.data.canvases[Er.WEBGL]&&e.data.canvases[Er.WEBGL].setAttribute("data-id","layer"+Er.WEBGL+"-webgl");for(var h=0;h<Er.BUFFER_COUNT;h++)e.data.bufferCanvases[h]=n.createElement("canvas"),e.data.bufferContexts[h]=e.data.bufferCanvases[h].getContext("2d"),e.data.bufferCanvases[h].style.position="absolute",e.data.bufferCanvases[h].setAttribute("data-id","buffer"+h),e.data.bufferCanvases[h].style.zIndex=String(-h-1),e.data.bufferCanvases[h].style.visibility="hidden";e.pathsEnabled=!0;var p=Hs(),m=o(function(X){return{x:(X.x1+X.x2)/2,y:(X.y1+X.y2)/2}},"getBoxCenter"),g=o(function(X){return{x:-X.w/2,y:-X.h/2}},"getCenterOffset"),y=o(function(X){var te=X[0]._private,J=te.oldBackgroundTimestamp===te.backgroundTimestamp;return!J},"backgroundTimestampHasChanged"),v=o(function(X){return X[0]._private.nodeKey},"getStyleKey"),x=o(function(X){return X[0]._private.labelStyleKey},"getLabelKey"),b=o(function(X){return X[0]._private.sourceLabelStyleKey},"getSourceLabelKey"),w=o(function(X){return X[0]._private.targetLabelStyleKey},"getTargetLabelKey"),C=o(function(X,te,J,se,ue){return e.drawElement(X,te,J,!1,!1,ue)},"drawElement"),T=o(function(X,te,J,se,ue){return e.drawElementText(X,te,J,se,"main",ue)},"drawLabel"),E=o(function(X,te,J,se,ue){return e.drawElementText(X,te,J,se,"source",ue)},"drawSourceLabel"),A=o(function(X,te,J,se,ue){return e.drawElementText(X,te,J,se,"target",ue)},"drawTargetLabel"),S=o(function(X){return X.boundingBox(),X[0]._private.bodyBounds},"getElementBox"),_=o(function(X){return X.boundingBox(),X[0]._private.labelBounds.main||p},"getLabelBox"),I=o(function(X){return X.boundingBox(),X[0]._private.labelBounds.source||p},"getSourceLabelBox"),D=o(function(X){return X.boundingBox(),X[0]._private.labelBounds.target||p},"getTargetLabelBox"),k=o(function(X,te){return te},"isLabelVisibleAtScale"),L=o(function(X){return m(S(X))},"getElementRotationPoint"),R=o(function(X,te,J){var se=X?X+"-":"";return{x:te.x+J.pstyle(se+"text-margin-x").pfValue,y:te.y+J.pstyle(se+"text-margin-y").pfValue}},"addTextMargin"),O=o(function(X,te,J){var se=X[0]._private.rscratch;return{x:se[te],y:se[J]}},"getRsPt"),M=o(function(X){return R("",O(X,"labelX","labelY"),X)},"getLabelRotationPoint"),B=o(function(X){return R("source",O(X,"sourceLabelX","sourceLabelY"),X)},"getSourceLabelRotationPoint"),F=o(function(X){return R("target",O(X,"targetLabelX","targetLabelY"),X)},"getTargetLabelRotationPoint"),P=o(function(X){return g(S(X))},"getElementRotationOffset"),z=o(function(X){return g(I(X))},"getSourceLabelRotationOffset"),$=o(function(X){return g(D(X))},"getTargetLabelRotationOffset"),H=o(function(X){var te=_(X),J=g(_(X));if(X.isNode()){switch(X.pstyle("text-halign").value){case"left":J.x=-te.w-(te.leftPad||0);break;case"right":J.x=-(te.rightPad||0);break}switch(X.pstyle("text-valign").value){case"top":J.y=-te.h-(te.topPad||0);break;case"bottom":J.y=-(te.botPad||0);break}}return J},"getLabelRotationOffset"),Q=e.data.eleTxrCache=new Fb(e,{getKey:v,doesEleInvalidateKey:y,drawElement:C,getBoundingBox:S,getRotationPoint:L,getRotationOffset:P,allowEdgeTxrCaching:!1,allowParentTxrCaching:!1}),j=e.data.lblTxrCache=new Fb(e,{getKey:x,drawElement:T,getBoundingBox:_,getRotationPoint:M,getRotationOffset:H,isVisible:k}),ie=e.data.slbTxrCache=new Fb(e,{getKey:b,drawElement:E,getBoundingBox:I,getRotationPoint:B,getRotationOffset:z,isVisible:k}),ne=e.data.tlbTxrCache=new Fb(e,{getKey:w,drawElement:A,getBoundingBox:D,getRotationPoint:F,getRotationOffset:$,isVisible:k}),le=e.data.lyrTxrCache=new wge(e);e.onUpdateEleCalcs(o(function(X,te){Q.invalidateElements(te),j.invalidateElements(te),ie.invalidateElements(te),ne.invalidateElements(te),le.invalidateElements(te);for(var J=0;J<te.length;J++){var se=te[J]._private;se.oldBackgroundTimestamp=se.backgroundTimestamp}},"invalidateTextureCaches"));var he=o(function(X){for(var te=0;te<X.length;te++)le.enqueueElementRefinement(X[te].ele)},"refineInLayers");Q.onDequeue(he),j.onDequeue(he),ie.onDequeue(he),ne.onDequeue(he),t.webgl&&e.initWebgl(t,{getStyleKey:v,getLabelKey:x,drawElement:C,drawLabel:T,getElementBox:S,getLabelBox:_,getElementRotationPoint:L,getElementRotationOffset:P,getLabelRotationPoint:M,getLabelRotationOffset:H})}function Fge(t,e,r){var n=r,i=o(function(S){un("Can not register `"+e+"` for `"+t+"` since `"+S+"` already exists in the prototype and can not be overridden")},"overrideErr");if(t==="core"){if(Jb.prototype[e])return i(e);Jb.prototype[e]=r}else if(t==="collection"){if(ka.prototype[e])return i(e);ka.prototype[e]=r}else if(t==="layout"){for(var a=o(function(S){this.options=S,r.call(this,S),Ur(this._private)||(this._private={}),this._private.cy=S.cy,this._private.listeners=[],this.createEmitter()},"Layout"),s=a.prototype=Object.create(r.prototype),l=[],u=0;u<l.length;u++){var h=l[u];s[h]=s[h]||function(){return this}}s.start&&!s.run?s.run=function(){return this.start(),this}:!s.start&&s.run&&(s.start=function(){return this.run(),this});var f=r.prototype.stop;s.stop=function(){var A=this.options;if(A&&A.animate){var S=this.animations;if(S)for(var _=0;_<S.length;_++)S[_].stop()}return f?f.call(this):this.emit("layoutstop"),this},s.destroy||(s.destroy=function(){return this}),s.cy=function(){return this._private.cy};var d=o(function(S){return S._private.cy},"getCy"),p={addEventFields:o(function(S,_){_.layout=S,_.cy=d(S),_.target=S},"addEventFields"),bubble:o(function(){return!0},"bubble"),parent:o(function(S){return d(S)},"parent")};rr(s,{createEmitter:o(function(){return this._private.emitter=new $S(p,this),this},"createEmitter"),emitter:o(function(){return this._private.emitter},"emitter"),on:o(function(S,_){return this.emitter().on(S,_),this},"on"),one:o(function(S,_){return this.emitter().one(S,_),this},"one"),once:o(function(S,_){return this.emitter().one(S,_),this},"once"),removeListener:o(function(S,_){return this.emitter().removeListener(S,_),this},"removeListener"),removeAllListeners:o(function(){return this.emitter().removeAllListeners(),this},"removeAllListeners"),emit:o(function(S,_){return this.emitter().emit(S,_),this},"emit")}),cn.eventAliasesOn(s),n=a}else if(t==="renderer"&&e!=="null"&&e!=="base"){var m=$ge("renderer","base"),g=m.prototype,y=r,v=r.prototype,x=o(function(){m.apply(this,arguments),y.apply(this,arguments)},"Renderer"),b=x.prototype;for(var w in g){var C=g[w],T=v[w]!=null;if(T)return i(w);b[w]=C}for(var E in v)b[E]=v[E];g.clientFunctions.forEach(function(A){b[A]=b[A]||function(){ai("Renderer does not implement `renderer."+A+"()` on its prototype")}}),n=x}else if(t==="__proto__"||t==="constructor"||t==="prototype")return ai(t+" is an illegal type to be registered, possibly lead to prototype pollutions");return rme({map:Pge,keys:[t,e],value:n})}function $ge(t,e){return nme({map:Pge,keys:[t,e]})}function HZe(t,e,r,n,i){return rme({map:Bge,keys:[t,e,r,n],value:i})}function WZe(t,e,r,n){return nme({map:Bge,keys:[t,e,r,n]})}var Ui,Lpe,jHe,K0e,KHe,QHe,e4,Zt,si,En,Ur,ZHe,Ct,JHe,vS,go,t4,Q0e,JP,Z0e,eWe,Af,tWe,rWe,nWe,iWe,Ub,eB,LS,J0e,Rpe,Hi,aWe,sWe,oWe,lWe,cWe,uWe,eme,hWe,rr,fWe,dWe,pWe,mWe,tme,gWe,rme,nme,zp,Ib,xWe,bWe,wWe,TWe,RS,kWe,xP,EWe,CWe,AWe,DWe,LWe,j1,ime,RWe,NWe,Ab,IWe,OWe,PWe,FWe,$We,zWe,Npe,ame,UWe,HWe,r4,Mpe,qWe,YWe,XWe,jWe,Ipe,QWe,ZWe,JWe,n4,bP,sme,tqe,xS,Qu,V1,ome,Ob,lme,Hb,Wb,rqe,wf,j6,nqe,_f,cme,iqe,Ope,aqe,sqe,tB,ume,bS,Ppe,rB,ai,hme,un,oqe,Yc,lqe,fme,cqe,dme,la,Df,nB,uqe,Gl,kf,hqe,Xc,fqe,dqe,J1,NS,Bpe,qb,pqe,i4,mqe,gqe,yqe,vqe,xqe,bqe,wqe,Tqe,kqe,Eqe,Sqe,wP,Cqe,Aqe,MS,pme,U1,_qe,Dqe,Lqe,Rqe,Nqe,K6,iB,mme,Gp,Op,Mqe,oa,W1,Iqe,Yb,Hs,Oqe,Pqe,Bqe,gme,Fqe,cS,uS,Fpe,aB,K1,$qe,yme,vme,zqe,Gqe,Vqe,Uqe,Hqe,Wqe,Us,Zu,qqe,wS,TS,Yqe,$p,Pb,TP,Ef,Xb,Xqe,Q6,gs,xme,PP,Vp,bme,sB,jqe,BP,Kqe,Qqe,$pe,q1,zpe,Y1,Zqe,FP,Jqe,eYe,tYe,rYe,wme,nYe,iYe,aYe,sYe,oYe,lYe,cYe,Gpe,uYe,hYe,Tme,Vpe,Upe,fYe,dYe,_b,Q1,pYe,oB,kS,kP,kme,Eme,mYe,gYe,yYe,Hpe,Wpe,vYe,xYe,bYe,wYe,TYe,qpe,kYe,EYe,SYe,CYe,Ype,Z6,AYe,_Ye,Xpe,DYe,LYe,RYe,NYe,MYe,IYe,jpe,OYe,Kpe,PYe,BYe,FYe,J6,$Ye,eS,zYe,Sme,Cme,Ame,_me,Ju,Qpe,Dme,Zpe,Jpe,GYe,ey,$P,Up,VYe,UYe,OS,HYe,WYe,YYe,XYe,jYe,KYe,QYe,JYe,eXe,EP,e0e,rXe,nXe,iXe,sXe,oXe,lXe,cXe,uXe,hXe,fXe,dXe,mXe,yXe,lB,xXe,jb,wXe,kXe,EXe,SXe,CXe,_Xe,DXe,LXe,NXe,MXe,OXe,t0e,BXe,Lme,PS,zXe,GXe,UXe,WXe,YXe,jXe,KXe,QXe,ZXe,eje,rje,BS,aje,oje,cje,hje,Rme,fje,dje,pje,gje,yje,vje,xje,Nme,Mme,wje,r0e,n0e,Tje,Ome,Pme,Sje,uB,_je,Lje,Rje,i0e,Mje,Ije,Oje,Bje,Fje,$je,Gje,Uje,Wje,Yje,jje,Kje,Qje,cn,Zje,hS,Vr,mn,$t,zP,Jje,eKe,tKe,B1,Tf,GP,rKe,nKe,iKe,aKe,sKe,Bme,oKe,lKe,hB,cKe,fi,zn,uKe,hKe,fKe,Lf,Rf,Sf,tl,Z1,Kb,zme,pKe,FS,Vl,Gme,Vme,a0e,mKe,X1,Of,el,zl,Pp,Db,tS,CP,gKe,yKe,Ume,Hme,s0e,Qb,o0e,l0e,vKe,Bb,a4,Wme,xKe,bKe,wKe,TKe,kKe,EKe,SKe,CKe,AKe,c0e,_Ke,DKe,LKe,qme,Yme,RKe,Xme,u0e,NKe,Nf,jme,h0e,MKe,IKe,nS,Kme,Qme,Qr,OKe,Zme,ES,PKe,BKe,fS,Ta,iy,FKe,$Ke,zKe,GKe,Cf,$a,d0e,p0e,m0e,ka,Mn,VKe,HKe,Nn,dS,YKe,XKe,iS,ege,VP,pS,jKe,KKe,UP,mS,Ga,$b,QKe,s4,pB,jc,VS,mB,wa,US,Fa,za,ZKe,JKe,Hp,Zb,Jb,SS,eQe,tQe,z1,T0e,rQe,nQe,_P,iQe,aQe,sQe,oQe,lQe,cQe,ige,uQe,hQe,fQe,k0e,dQe,pQe,CS,mQe,gQe,yQe,vQe,xQe,bQe,E0e,wQe,TQe,kQe,EQe,SQe,S0e,C0e,yB,qp,AS,HP,WP,qc,Jo,A0e,_0e,Fp,gS,Ku,Mp,Bp,Wc,G1,aS,cge,uge,qP,YP,D0e,L0e,CQe,AQe,Va,o4,xB,Kc,dge,pge,DQe,mge,R0e,N0e,WS,qS,gge,yge,sy,eh,l4,M0e,LQe,vge,oy,DP,xge,RQe,I0e,sS,yS,XP,bge,NQe,MQe,IQe,OQe,PQe,BQe,FQe,$Qe,zQe,GQe,VQe,UQe,HQe,H1,WQe,Fb,qi,qQe,zb,_S,YQe,XQe,jQe,KQe,QQe,ZQe,JQe,eZe,O0e,tZe,P0e,rZe,wge,Ea,B0e,nZe,Tge,F0e,Qc,lZe,cZe,uZe,hZe,fZe,LP,th,kge,bB,Yp,ly,Ege,ys,dZe,Nb,G0e,Vb,Mb,kZe,EZe,CZe,MP,V0e,U0e,IP,AZe,_Ze,Dge,Pf,W0e,q0e,jP,KP,Nge,Ip,c4,Ige,zZe,Er,GZe,VZe,UZe,Pge,Bge,QP,zge,Wp,qZe,rl,kB=N(()=>{"use strict";o(Wi,"_typeof");o(Mf,"_classCallCheck");o(Dpe,"_defineProperties");o(If,"_createClass");o(X0e,"_defineProperty$1");o(_i,"_slicedToArray");o(j0e,"_toConsumableArray");o(UHe,"_arrayWithoutHoles");o(HHe,"_arrayWithHoles");o(WHe,"_iterableToArray");o(qHe,"_iterableToArrayLimit");o(ZP,"_unsupportedIterableToArray");o(OP,"_arrayLikeToArray");o(YHe,"_nonIterableSpread");o(XHe,"_nonIterableRest");o(mo,"_createForOfIteratorHelper");Ui=typeof window>"u"?null:window,Lpe=Ui?Ui.navigator:null;Ui&&Ui.document;jHe=Wi(""),K0e=Wi({}),KHe=Wi(function(){}),QHe=typeof HTMLElement>"u"?"undefined":Wi(HTMLElement),e4=o(function(e){return e&&e.instanceString&&si(e.instanceString)?e.instanceString():null},"instanceStr"),Zt=o(function(e){return e!=null&&Wi(e)==jHe},"string"),si=o(function(e){return e!=null&&Wi(e)===KHe},"fn"),En=o(function(e){return!go(e)&&(Array.isArray?Array.isArray(e):e!=null&&e instanceof Array)},"array"),Ur=o(function(e){return e!=null&&Wi(e)===K0e&&!En(e)&&e.constructor===Object},"plainObject"),ZHe=o(function(e){return e!=null&&Wi(e)===K0e},"object"),Ct=o(function(e){return e!=null&&Wi(e)===Wi(1)&&!isNaN(e)},"number"),JHe=o(function(e){return Ct(e)&&Math.floor(e)===e},"integer"),vS=o(function(e){if(QHe!=="undefined")return e!=null&&e instanceof HTMLElement},"htmlElement"),go=o(function(e){return t4(e)||Q0e(e)},"elementOrCollection"),t4=o(function(e){return e4(e)==="collection"&&e._private.single},"element"),Q0e=o(function(e){return e4(e)==="collection"&&!e._private.single},"collection"),JP=o(function(e){return e4(e)==="core"},"core"),Z0e=o(function(e){return e4(e)==="stylesheet"},"stylesheet"),eWe=o(function(e){return e4(e)==="event"},"event"),Af=o(function(e){return e==null?!0:!!(e===""||e.match(/^\s+$/))},"emptyString"),tWe=o(function(e){return typeof HTMLElement>"u"?!1:e instanceof HTMLElement},"domElement"),rWe=o(function(e){return Ur(e)&&Ct(e.x1)&&Ct(e.x2)&&Ct(e.y1)&&Ct(e.y2)},"boundingBox"),nWe=o(function(e){return ZHe(e)&&si(e.then)},"promise"),iWe=o(function(){return Lpe&&Lpe.userAgent.match(/msie|trident|edge/i)},"ms"),Ub=o(function(e,r){r||(r=o(function(){if(arguments.length===1)return arguments[0];if(arguments.length===0)return"undefined";for(var a=[],s=0;s<arguments.length;s++)a.push(arguments[s]);return a.join("$")},"keyFn"));var n=o(function i(){var a=this,s=arguments,l,u=r.apply(a,s),h=i.cache;return(l=h[u])||(l=h[u]=e.apply(a,s)),l},"memoizedFn");return n.cache={},n},"memoize"),eB=Ub(function(t){return t.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()})}),LS=Ub(function(t){return t.replace(/(-\w)/g,function(e){return e[1].toUpperCase()})}),J0e=Ub(function(t,e){return t+e[0].toUpperCase()+e.substring(1)},function(t,e){return t+"$"+e}),Rpe=o(function(e){return Af(e)?e:e.charAt(0).toUpperCase()+e.substring(1)},"capitalize"),Hi="(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))",aWe="rgb[a]?\\(("+Hi+"[%]?)\\s*,\\s*("+Hi+"[%]?)\\s*,\\s*("+Hi+"[%]?)(?:\\s*,\\s*("+Hi+"))?\\)",sWe="rgb[a]?\\((?:"+Hi+"[%]?)\\s*,\\s*(?:"+Hi+"[%]?)\\s*,\\s*(?:"+Hi+"[%]?)(?:\\s*,\\s*(?:"+Hi+"))?\\)",oWe="hsl[a]?\\(("+Hi+")\\s*,\\s*("+Hi+"[%])\\s*,\\s*("+Hi+"[%])(?:\\s*,\\s*("+Hi+"))?\\)",lWe="hsl[a]?\\((?:"+Hi+")\\s*,\\s*(?:"+Hi+"[%])\\s*,\\s*(?:"+Hi+"[%])(?:\\s*,\\s*(?:"+Hi+"))?\\)",cWe="\\#[0-9a-fA-F]{3}",uWe="\\#[0-9a-fA-F]{6}",eme=o(function(e,r){return e<r?-1:e>r?1:0},"ascending"),hWe=o(function(e,r){return-1*eme(e,r)},"descending"),rr=Object.assign!=null?Object.assign.bind(Object):function(t){for(var e=arguments,r=1;r<e.length;r++){var n=e[r];if(n!=null)for(var i=Object.keys(n),a=0;a<i.length;a++){var s=i[a];t[s]=n[s]}}return t},fWe=o(function(e){if(!(!(e.length===4||e.length===7)||e[0]!=="#")){var r=e.length===4,n,i,a,s=16;return r?(n=parseInt(e[1]+e[1],s),i=parseInt(e[2]+e[2],s),a=parseInt(e[3]+e[3],s)):(n=parseInt(e[1]+e[2],s),i=parseInt(e[3]+e[4],s),a=parseInt(e[5]+e[6],s)),[n,i,a]}},"hex2tuple"),dWe=o(function(e){var r,n,i,a,s,l,u,h;function f(g,y,v){return v<0&&(v+=1),v>1&&(v-=1),v<1/6?g+(y-g)*6*v:v<1/2?y:v<2/3?g+(y-g)*(2/3-v)*6:g}o(f,"hue2rgb");var d=new RegExp("^"+oWe+"$").exec(e);if(d){if(n=parseInt(d[1]),n<0?n=(360- -1*n%360)%360:n>360&&(n=n%360),n/=360,i=parseFloat(d[2]),i<0||i>100||(i=i/100,a=parseFloat(d[3]),a<0||a>100)||(a=a/100,s=d[4],s!==void 0&&(s=parseFloat(s),s<0||s>1)))return;if(i===0)l=u=h=Math.round(a*255);else{var p=a<.5?a*(1+i):a+i-a*i,m=2*a-p;l=Math.round(255*f(m,p,n+1/3)),u=Math.round(255*f(m,p,n)),h=Math.round(255*f(m,p,n-1/3))}r=[l,u,h,s]}return r},"hsl2tuple"),pWe=o(function(e){var r,n=new RegExp("^"+aWe+"$").exec(e);if(n){r=[];for(var i=[],a=1;a<=3;a++){var s=n[a];if(s[s.length-1]==="%"&&(i[a]=!0),s=parseFloat(s),i[a]&&(s=s/100*255),s<0||s>255)return;r.push(Math.floor(s))}var l=i[1]||i[2]||i[3],u=i[1]&&i[2]&&i[3];if(l&&!u)return;var h=n[4];if(h!==void 0){if(h=parseFloat(h),h<0||h>1)return;r.push(h)}}return r},"rgb2tuple"),mWe=o(function(e){return gWe[e.toLowerCase()]},"colorname2tuple"),tme=o(function(e){return(En(e)?e:null)||mWe(e)||fWe(e)||pWe(e)||dWe(e)},"color2tuple"),gWe={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},rme=o(function(e){for(var r=e.map,n=e.keys,i=n.length,a=0;a<i;a++){var s=n[a];if(Ur(s))throw Error("Tried to set map with object key");a<n.length-1?(r[s]==null&&(r[s]={}),r=r[s]):r[s]=e.value}},"setMap"),nme=o(function(e){for(var r=e.map,n=e.keys,i=n.length,a=0;a<i;a++){var s=n[a];if(Ur(s))throw Error("Tried to get map with object key");if(r=r[s],r==null)return r}return r},"getMap");o(yWe,"isObject");zp=yWe,Ib=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};o(vWe,"createCommonjsModule");xWe=typeof Ib=="object"&&Ib&&Ib.Object===Object&&Ib,bWe=xWe,wWe=typeof self=="object"&&self&&self.Object===Object&&self,TWe=bWe||wWe||Function("return this")(),RS=TWe,kWe=o(function(){return RS.Date.now()},"now"),xP=kWe,EWe=/\s/;o(SWe,"trimmedEndIndex");CWe=SWe,AWe=/^\s+/;o(_We,"baseTrim");DWe=_We,LWe=RS.Symbol,j1=LWe,ime=Object.prototype,RWe=ime.hasOwnProperty,NWe=ime.toString,Ab=j1?j1.toStringTag:void 0;o(MWe,"getRawTag");IWe=MWe,OWe=Object.prototype,PWe=OWe.toString;o(BWe,"objectToString");FWe=BWe,$We="[object Null]",zWe="[object Undefined]",Npe=j1?j1.toStringTag:void 0;o(GWe,"baseGetTag");ame=GWe;o(VWe,"isObjectLike");UWe=VWe,HWe="[object Symbol]";o(WWe,"isSymbol");r4=WWe,Mpe=NaN,qWe=/^[-+]0x[0-9a-f]+$/i,YWe=/^0b[01]+$/i,XWe=/^0o[0-7]+$/i,jWe=parseInt;o(KWe,"toNumber");Ipe=KWe,QWe="Expected a function",ZWe=Math.max,JWe=Math.min;o(eqe,"debounce");n4=eqe,bP=Ui?Ui.performance:null,sme=bP&&bP.now?function(){return bP.now()}:function(){return Date.now()},tqe=function(){if(Ui){if(Ui.requestAnimationFrame)return function(t){Ui.requestAnimationFrame(t)};if(Ui.mozRequestAnimationFrame)return function(t){Ui.mozRequestAnimationFrame(t)};if(Ui.webkitRequestAnimationFrame)return function(t){Ui.webkitRequestAnimationFrame(t)};if(Ui.msRequestAnimationFrame)return function(t){Ui.msRequestAnimationFrame(t)}}return function(t){t&&setTimeout(function(){t(sme())},1e3/60)}}(),xS=o(function(e){return tqe(e)},"requestAnimationFrame"),Qu=sme,V1=9261,ome=65599,Ob=5381,lme=o(function(e){for(var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:V1,n=r,i;i=e.next(),!i.done;)n=n*ome+i.value|0;return n},"hashIterableInts"),Hb=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:V1;return r*ome+e|0},"hashInt"),Wb=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Ob;return(r<<5)+r+e|0},"hashIntAlt"),rqe=o(function(e,r){return e*2097152+r},"combineHashes"),wf=o(function(e){return e[0]*2097152+e[1]},"combineHashesArray"),j6=o(function(e,r){return[Hb(e[0],r[0]),Wb(e[1],r[1])]},"hashArrays"),nqe=o(function(e,r){var n={value:0,done:!1},i=0,a=e.length,s={next:o(function(){return i<a?n.value=e[i++]:n.done=!0,n},"next")};return lme(s,r)},"hashIntsArray"),_f=o(function(e,r){var n={value:0,done:!1},i=0,a=e.length,s={next:o(function(){return i<a?n.value=e.charCodeAt(i++):n.done=!0,n},"next")};return lme(s,r)},"hashString"),cme=o(function(){return iqe(arguments)},"hashStrings"),iqe=o(function(e){for(var r,n=0;n<e.length;n++){var i=e[n];n===0?r=_f(i):r=_f(i,r)}return r},"hashStringsArray"),Ope=!0,aqe=console.warn!=null,sqe=console.trace!=null,tB=Number.MAX_SAFE_INTEGER||9007199254740991,ume=o(function(){return!0},"trueify"),bS=o(function(){return!1},"falsify"),Ppe=o(function(){return 0},"zeroify"),rB=o(function(){},"noop"),ai=o(function(e){throw new Error(e)},"error"),hme=o(function(e){if(e!==void 0)Ope=!!e;else return Ope},"warnings"),un=o(function(e){hme()&&(aqe?console.warn(e):(console.log(e),sqe&&console.trace()))},"warn"),oqe=o(function(e){return rr({},e)},"clone"),Yc=o(function(e){return e==null?e:En(e)?e.slice():Ur(e)?oqe(e):e},"copy"),lqe=o(function(e){return e.slice()},"copyArray"),fme=o(function(e,r){for(r=e="";e++<36;r+=e*51&52?(e^15?8^Math.random()*(e^20?16:4):4).toString(16):"-");return r},"uuid"),cqe={},dme=o(function(){return cqe},"staticEmptyObject"),la=o(function(e){var r=Object.keys(e);return function(n){for(var i={},a=0;a<r.length;a++){var s=r[a],l=n?.[s];i[s]=l===void 0?e[s]:l}return i}},"defaults"),Df=o(function(e,r,n){for(var i=e.length-1;i>=0&&!(e[i]===r&&(e.splice(i,1),n));i--);},"removeFromArray"),nB=o(function(e){e.splice(0,e.length)},"clearArray"),uqe=o(function(e,r){for(var n=0;n<r.length;n++){var i=r[n];e.push(i)}},"push"),Gl=o(function(e,r,n){return n&&(r=J0e(n,r)),e[r]},"getPrefixedProperty"),kf=o(function(e,r,n,i){n&&(r=J0e(n,r)),e[r]=i},"setPrefixedProperty"),hqe=function(){function t(){Mf(this,t),this._obj={}}return o(t,"ObjectMap"),If(t,[{key:"set",value:o(function(r,n){return this._obj[r]=n,this},"set")},{key:"delete",value:o(function(r){return this._obj[r]=void 0,this},"_delete")},{key:"clear",value:o(function(){this._obj={}},"clear")},{key:"has",value:o(function(r){return this._obj[r]!==void 0},"has")},{key:"get",value:o(function(r){return this._obj[r]},"get")}]),t}(),Xc=typeof Map<"u"?Map:hqe,fqe="undefined",dqe=function(){function t(e){if(Mf(this,t),this._obj=Object.create(null),this.size=0,e!=null){var r;e.instanceString!=null&&e.instanceString()===this.instanceString()?r=e.toArray():r=e;for(var n=0;n<r.length;n++)this.add(r[n])}}return o(t,"ObjectSet"),If(t,[{key:"instanceString",value:o(function(){return"set"},"instanceString")},{key:"add",value:o(function(r){var n=this._obj;n[r]!==1&&(n[r]=1,this.size++)},"add")},{key:"delete",value:o(function(r){var n=this._obj;n[r]===1&&(n[r]=0,this.size--)},"_delete")},{key:"clear",value:o(function(){this._obj=Object.create(null)},"clear")},{key:"has",value:o(function(r){return this._obj[r]===1},"has")},{key:"toArray",value:o(function(){var r=this;return Object.keys(this._obj).filter(function(n){return r.has(n)})},"toArray")},{key:"forEach",value:o(function(r,n){return this.toArray().forEach(r,n)},"forEach")}]),t}(),J1=(typeof Set>"u"?"undefined":Wi(Set))!==fqe?Set:dqe,NS=o(function(e,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(e===void 0||r===void 0||!JP(e)){ai("An element must have a core reference and parameters set");return}var i=r.group;if(i==null&&(r.data&&r.data.source!=null&&r.data.target!=null?i="edges":i="nodes"),i!=="nodes"&&i!=="edges"){ai("An element must be of type `nodes` or `edges`; you specified `"+i+"`");return}this.length=1,this[0]=this;var a=this._private={cy:e,single:!0,data:r.data||{},position:r.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:i,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!r.selected,selectable:r.selectable===void 0?!0:!!r.selectable,locked:!!r.locked,grabbed:!1,grabbable:r.grabbable===void 0?!0:!!r.grabbable,pannable:r.pannable===void 0?i==="edges":!!r.pannable,active:!1,classes:new J1,animation:{current:[],queue:[]},rscratch:{},scratch:r.scratch||{},edges:[],children:[],parent:r.parent&&r.parent.isNode()?r.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(a.position.x==null&&(a.position.x=0),a.position.y==null&&(a.position.y=0),r.renderedPosition){var s=r.renderedPosition,l=e.pan(),u=e.zoom();a.position={x:(s.x-l.x)/u,y:(s.y-l.y)/u}}var h=[];En(r.classes)?h=r.classes:Zt(r.classes)&&(h=r.classes.split(/\s+/));for(var f=0,d=h.length;f<d;f++){var p=h[f];!p||p===""||a.classes.add(p)}this.createEmitter();var m=r.style||r.css;m&&(un("Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead."),this.style(m)),(n===void 0||n)&&this.restore()},"Element"),Bpe=o(function(e){return e={bfs:e.bfs||!e.dfs,dfs:e.dfs||!e.bfs},o(function(n,i,a){var s;Ur(n)&&!go(n)&&(s=n,n=s.roots||s.root,i=s.visit,a=s.directed),a=arguments.length===2&&!si(i)?i:a,i=si(i)?i:function(){};for(var l=this._private.cy,u=n=Zt(n)?this.filter(n):n,h=[],f=[],d={},p={},m={},g=0,y,v=this.byGroup(),x=v.nodes,b=v.edges,w=0;w<u.length;w++){var C=u[w],T=C.id();C.isNode()&&(h.unshift(C),e.bfs&&(m[T]=!0,f.push(C)),p[T]=0)}for(var E=o(function(){var L=e.bfs?h.shift():h.pop(),R=L.id();if(e.dfs){if(m[R])return"continue";m[R]=!0,f.push(L)}var O=p[R],M=d[R],B=M!=null?M.source():null,F=M!=null?M.target():null,P=M==null?void 0:L.same(B)?F[0]:B[0],z=void 0;if(z=i(L,M,P,g++,O),z===!0)return y=L,"break";if(z===!1)return"break";for(var $=L.connectedEdges().filter(function(ne){return(!a||ne.source().same(L))&&b.has(ne)}),H=0;H<$.length;H++){var Q=$[H],j=Q.connectedNodes().filter(function(ne){return!ne.same(L)&&x.has(ne)}),ie=j.id();j.length!==0&&!m[ie]&&(j=j[0],h.push(j),e.bfs&&(m[ie]=!0,f.push(j)),d[ie]=Q,p[ie]=p[R]+1)}},"_loop");h.length!==0;){var A=E();if(A!=="continue"&&A==="break")break}for(var S=l.collection(),_=0;_<f.length;_++){var I=f[_],D=d[I.id()];D!=null&&S.push(D),S.push(I)}return{path:l.collection(S),found:l.collection(y)}},"searchFn")},"defineSearch"),qb={breadthFirstSearch:Bpe({bfs:!0}),depthFirstSearch:Bpe({dfs:!0})};qb.bfs=qb.breadthFirstSearch;qb.dfs=qb.depthFirstSearch;pqe=vWe(function(t,e){(function(){var r,n,i,a,s,l,u,h,f,d,p,m,g,y,v;i=Math.floor,d=Math.min,n=o(function(x,b){return x<b?-1:x>b?1:0},"defaultCmp"),f=o(function(x,b,w,C,T){var E;if(w==null&&(w=0),T==null&&(T=n),w<0)throw new Error("lo must be non-negative");for(C==null&&(C=x.length);w<C;)E=i((w+C)/2),T(b,x[E])<0?C=E:w=E+1;return[].splice.apply(x,[w,w-w].concat(b)),b},"insort"),l=o(function(x,b,w){return w==null&&(w=n),x.push(b),y(x,0,x.length-1,w)},"heappush"),s=o(function(x,b){var w,C;return b==null&&(b=n),w=x.pop(),x.length?(C=x[0],x[0]=w,v(x,0,b)):C=w,C},"heappop"),h=o(function(x,b,w){var C;return w==null&&(w=n),C=x[0],x[0]=b,v(x,0,w),C},"heapreplace"),u=o(function(x,b,w){var C;return w==null&&(w=n),x.length&&w(x[0],b)<0&&(C=[x[0],b],b=C[0],x[0]=C[1],v(x,0,w)),b},"heappushpop"),a=o(function(x,b){var w,C,T,E,A,S;for(b==null&&(b=n),E=function(){S=[];for(var _=0,I=i(x.length/2);0<=I?_<I:_>I;0<=I?_++:_--)S.push(_);return S}.apply(this).reverse(),A=[],C=0,T=E.length;C<T;C++)w=E[C],A.push(v(x,w,b));return A},"heapify"),g=o(function(x,b,w){var C;if(w==null&&(w=n),C=x.indexOf(b),C!==-1)return y(x,0,C,w),v(x,C,w)},"updateItem"),p=o(function(x,b,w){var C,T,E,A,S;if(w==null&&(w=n),T=x.slice(0,b),!T.length)return T;for(a(T,w),S=x.slice(b),E=0,A=S.length;E<A;E++)C=S[E],u(T,C,w);return T.sort(w).reverse()},"nlargest"),m=o(function(x,b,w){var C,T,E,A,S,_,I,D,k;if(w==null&&(w=n),b*10<=x.length){if(E=x.slice(0,b).sort(w),!E.length)return E;for(T=E[E.length-1],I=x.slice(b),A=0,_=I.length;A<_;A++)C=I[A],w(C,T)<0&&(f(E,C,0,null,w),E.pop(),T=E[E.length-1]);return E}for(a(x,w),k=[],S=0,D=d(b,x.length);0<=D?S<D:S>D;0<=D?++S:--S)k.push(s(x,w));return k},"nsmallest"),y=o(function(x,b,w,C){var T,E,A;for(C==null&&(C=n),T=x[w];w>b;){if(A=w-1>>1,E=x[A],C(T,E)<0){x[w]=E,w=A;continue}break}return x[w]=T},"_siftdown"),v=o(function(x,b,w){var C,T,E,A,S;for(w==null&&(w=n),T=x.length,S=b,E=x[b],C=2*b+1;C<T;)A=C+1,A<T&&!(w(x[C],x[A])<0)&&(C=A),x[b]=x[C],b=C,C=2*b+1;return x[b]=E,y(x,S,b,w)},"_siftup"),r=function(){x.push=l,x.pop=s,x.replace=h,x.pushpop=u,x.heapify=a,x.updateItem=g,x.nlargest=p,x.nsmallest=m;function x(b){this.cmp=b??n,this.nodes=[]}return o(x,"Heap"),x.prototype.push=function(b){return l(this.nodes,b,this.cmp)},x.prototype.pop=function(){return s(this.nodes,this.cmp)},x.prototype.peek=function(){return this.nodes[0]},x.prototype.contains=function(b){return this.nodes.indexOf(b)!==-1},x.prototype.replace=function(b){return h(this.nodes,b,this.cmp)},x.prototype.pushpop=function(b){return u(this.nodes,b,this.cmp)},x.prototype.heapify=function(){return a(this.nodes,this.cmp)},x.prototype.updateItem=function(b){return g(this.nodes,b,this.cmp)},x.prototype.clear=function(){return this.nodes=[]},x.prototype.empty=function(){return this.nodes.length===0},x.prototype.size=function(){return this.nodes.length},x.prototype.clone=function(){var b;return b=new x,b.nodes=this.nodes.slice(0),b},x.prototype.toArray=function(){return this.nodes.slice(0)},x.prototype.insert=x.prototype.push,x.prototype.top=x.prototype.peek,x.prototype.front=x.prototype.peek,x.prototype.has=x.prototype.contains,x.prototype.copy=x.prototype.clone,x}(),function(x,b){return t.exports=b()}(this,function(){return r})}).call(Ib)}),i4=pqe,mqe=la({root:null,weight:o(function(e){return 1},"weight"),directed:!1}),gqe={dijkstra:o(function(e){if(!Ur(e)){var r=arguments;e={root:r[0],weight:r[1],directed:r[2]}}var n=mqe(e),i=n.root,a=n.weight,s=n.directed,l=this,u=a,h=Zt(i)?this.filter(i)[0]:i[0],f={},d={},p={},m=this.byGroup(),g=m.nodes,y=m.edges;y.unmergeBy(function(O){return O.isLoop()});for(var v=o(function(M){return f[M.id()]},"getDist"),x=o(function(M,B){f[M.id()]=B,b.updateItem(M)},"setDist"),b=new i4(function(O,M){return v(O)-v(M)}),w=0;w<g.length;w++){var C=g[w];f[C.id()]=C.same(h)?0:1/0,b.push(C)}for(var T=o(function(M,B){for(var F=(s?M.edgesTo(B):M.edgesWith(B)).intersect(y),P=1/0,z,$=0;$<F.length;$++){var H=F[$],Q=u(H);(Q<P||!z)&&(P=Q,z=H)}return{edge:z,dist:P}},"distBetween");b.size()>0;){var E=b.pop(),A=v(E),S=E.id();if(p[S]=A,A!==1/0)for(var _=E.neighborhood().intersect(g),I=0;I<_.length;I++){var D=_[I],k=D.id(),L=T(E,D),R=A+L.dist;R<v(D)&&(x(D,R),d[k]={node:E,edge:L.edge})}}return{distanceTo:o(function(M){var B=Zt(M)?g.filter(M)[0]:M[0];return p[B.id()]},"distanceTo"),pathTo:o(function(M){var B=Zt(M)?g.filter(M)[0]:M[0],F=[],P=B,z=P.id();if(B.length>0)for(F.unshift(B);d[z];){var $=d[z];F.unshift($.edge),F.unshift($.node),P=$.node,z=P.id()}return l.spawn(F)},"pathTo")}},"dijkstra")},yqe={kruskal:o(function(e){e=e||function(w){return 1};for(var r=this.byGroup(),n=r.nodes,i=r.edges,a=n.length,s=new Array(a),l=n,u=o(function(C){for(var T=0;T<s.length;T++){var E=s[T];if(E.has(C))return T}},"findSetIndex"),h=0;h<a;h++)s[h]=this.spawn(n[h]);for(var f=i.sort(function(w,C){return e(w)-e(C)}),d=0;d<f.length;d++){var p=f[d],m=p.source()[0],g=p.target()[0],y=u(m),v=u(g),x=s[y],b=s[v];y!==v&&(l.merge(p),x.merge(b),s.splice(v,1))}return l},"kruskal")},vqe=la({root:null,goal:null,weight:o(function(e){return 1},"weight"),heuristic:o(function(e){return 0},"heuristic"),directed:!1}),xqe={aStar:o(function(e){var r=this.cy(),n=vqe(e),i=n.root,a=n.goal,s=n.heuristic,l=n.directed,u=n.weight;i=r.collection(i)[0],a=r.collection(a)[0];var h=i.id(),f=a.id(),d={},p={},m={},g=new i4(function(z,$){return p[z.id()]-p[$.id()]}),y=new J1,v={},x={},b=o(function($,H){g.push($),y.add(H)},"addToOpenSet"),w,C,T=o(function(){w=g.pop(),C=w.id(),y.delete(C)},"popFromOpenSet"),E=o(function($){return y.has($)},"isInOpenSet");b(i,h),d[h]=0,p[h]=s(i);for(var A=0;g.size()>0;){if(T(),A++,C===f){for(var S=[],_=a,I=f,D=x[I];S.unshift(_),D!=null&&S.unshift(D),_=v[I],_!=null;)I=_.id(),D=x[I];return{found:!0,distance:d[C],path:this.spawn(S),steps:A}}m[C]=!0;for(var k=w._private.edges,L=0;L<k.length;L++){var R=k[L];if(this.hasElementWithId(R.id())&&!(l&&R.data("source")!==C)){var O=R.source(),M=R.target(),B=O.id()!==C?O:M,F=B.id();if(this.hasElementWithId(F)&&!m[F]){var P=d[C]+u(R);if(!E(F)){d[F]=P,p[F]=P+s(B),b(B,F),v[F]=w,x[F]=R;continue}P<d[F]&&(d[F]=P,p[F]=P+s(B),v[F]=w,x[F]=R)}}}}return{found:!1,distance:void 0,path:void 0,steps:A}},"aStar")},bqe=la({weight:o(function(e){return 1},"weight"),directed:!1}),wqe={floydWarshall:o(function(e){for(var r=this.cy(),n=bqe(e),i=n.weight,a=n.directed,s=i,l=this.byGroup(),u=l.nodes,h=l.edges,f=u.length,d=f*f,p=o(function(Q){return u.indexOf(Q)},"indexOf"),m=o(function(Q){return u[Q]},"atIndex"),g=new Array(d),y=0;y<d;y++){var v=y%f,x=(y-v)/f;x===v?g[y]=0:g[y]=1/0}for(var b=new Array(d),w=new Array(d),C=0;C<h.length;C++){var T=h[C],E=T.source()[0],A=T.target()[0];if(E!==A){var S=p(E),_=p(A),I=S*f+_,D=s(T);if(g[I]>D&&(g[I]=D,b[I]=_,w[I]=T),!a){var k=_*f+S;!a&&g[k]>D&&(g[k]=D,b[k]=S,w[k]=T)}}}for(var L=0;L<f;L++)for(var R=0;R<f;R++)for(var O=R*f+L,M=0;M<f;M++){var B=R*f+M,F=L*f+M;g[O]+g[F]<g[B]&&(g[B]=g[O]+g[F],b[B]=b[O])}var P=o(function(Q){return(Zt(Q)?r.filter(Q):Q)[0]},"getArgEle"),z=o(function(Q){return p(P(Q))},"indexOfArgEle"),$={distance:o(function(Q,j){var ie=z(Q),ne=z(j);return g[ie*f+ne]},"distance"),path:o(function(Q,j){var ie=z(Q),ne=z(j),le=m(ie);if(ie===ne)return le.collection();if(b[ie*f+ne]==null)return r.collection();var he=r.collection(),K=ie,X;for(he.merge(le);ie!==ne;)K=ie,ie=b[ie*f+ne],X=w[K*f+ie],he.merge(X),he.merge(m(ie));return he},"path")};return $},"floydWarshall")},Tqe=la({weight:o(function(e){return 1},"weight"),directed:!1,root:null}),kqe={bellmanFord:o(function(e){var r=this,n=Tqe(e),i=n.weight,a=n.directed,s=n.root,l=i,u=this,h=this.cy(),f=this.byGroup(),d=f.edges,p=f.nodes,m=p.length,g=new Xc,y=!1,v=[];s=h.collection(s)[0],d.unmergeBy(function(ce){return ce.isLoop()});for(var x=d.length,b=o(function(ae){var Oe=g.get(ae.id());return Oe||(Oe={},g.set(ae.id(),Oe)),Oe},"getInfo"),w=o(function(ae){return(Zt(ae)?h.$(ae):ae)[0]},"getNodeFromTo"),C=o(function(ae){return b(w(ae)).dist},"distanceTo"),T=o(function(ae){for(var Oe=arguments.length>1&&arguments[1]!==void 0?arguments[1]:s,ge=w(ae),ze=[],He=ge;;){if(He==null)return r.spawn();var $e=b(He),Re=$e.edge,Ie=$e.pred;if(ze.unshift(He[0]),He.same(Oe)&&ze.length>0)break;Re!=null&&ze.unshift(Re),He=Ie}return u.spawn(ze)},"pathTo"),E=0;E<m;E++){var A=p[E],S=b(A);A.same(s)?S.dist=0:S.dist=1/0,S.pred=null,S.edge=null}for(var _=!1,I=o(function(ae,Oe,ge,ze,He,$e){var Re=ze.dist+$e;Re<He.dist&&!ge.same(ze.edge)&&(He.dist=Re,He.pred=ae,He.edge=ge,_=!0)},"checkForEdgeReplacement"),D=1;D<m;D++){_=!1;for(var k=0;k<x;k++){var L=d[k],R=L.source(),O=L.target(),M=l(L),B=b(R),F=b(O);I(R,O,L,B,F,M),a||I(O,R,L,F,B,M)}if(!_)break}if(_)for(var P=[],z=0;z<x;z++){var $=d[z],H=$.source(),Q=$.target(),j=l($),ie=b(H).dist,ne=b(Q).dist;if(ie+j<ne||!a&&ne+j<ie)if(y||(un("Graph contains a negative weight cycle for Bellman-Ford"),y=!0),e.findNegativeWeightCycles!==!1){var le=[];ie+j<ne&&le.push(H),!a&&ne+j<ie&&le.push(Q);for(var he=le.length,K=0;K<he;K++){var X=le[K],te=[X];te.push(b(X).edge);for(var J=b(X).pred;te.indexOf(J)===-1;)te.push(J),te.push(b(J).edge),J=b(J).pred;te=te.slice(te.indexOf(J));for(var se=te[0].id(),ue=0,Z=2;Z<te.length;Z+=2)te[Z].id()<se&&(se=te[Z].id(),ue=Z);te=te.slice(ue).concat(te.slice(0,ue)),te.push(te[0]);var Se=te.map(function(ce){return ce.id()}).join(",");P.indexOf(Se)===-1&&(v.push(u.spawn(te)),P.push(Se))}}else break}return{distanceTo:C,pathTo:T,hasNegativeWeightCycle:y,negativeWeightCycles:v}},"bellmanFord")},Eqe=Math.sqrt(2),Sqe=o(function(e,r,n){n.length===0&&ai("Karger-Stein must be run on a connected (sub)graph");for(var i=n[e],a=i[1],s=i[2],l=r[a],u=r[s],h=n,f=h.length-1;f>=0;f--){var d=h[f],p=d[1],m=d[2];(r[p]===l&&r[m]===u||r[p]===u&&r[m]===l)&&h.splice(f,1)}for(var g=0;g<h.length;g++){var y=h[g];y[1]===u?(h[g]=y.slice(),h[g][1]=l):y[2]===u&&(h[g]=y.slice(),h[g][2]=l)}for(var v=0;v<r.length;v++)r[v]===u&&(r[v]=l);return h},"collapse"),wP=o(function(e,r,n,i){for(;n>i;){var a=Math.floor(Math.random()*r.length);r=Sqe(a,e,r),n--}return r},"contractUntil"),Cqe={kargerStein:o(function(){var e=this,r=this.byGroup(),n=r.nodes,i=r.edges;i.unmergeBy(function(F){return F.isLoop()});var a=n.length,s=i.length,l=Math.ceil(Math.pow(Math.log(a)/Math.LN2,2)),u=Math.floor(a/Eqe);if(a<2){ai("At least 2 nodes are required for Karger-Stein algorithm");return}for(var h=[],f=0;f<s;f++){var d=i[f];h.push([f,n.indexOf(d.source()),n.indexOf(d.target())])}for(var p=1/0,m=[],g=new Array(a),y=new Array(a),v=new Array(a),x=o(function(P,z){for(var $=0;$<a;$++)z[$]=P[$]},"copyNodesMap"),b=0;b<=l;b++){for(var w=0;w<a;w++)y[w]=w;var C=wP(y,h.slice(),a,u),T=C.slice();x(y,v);var E=wP(y,C,u,2),A=wP(v,T,u,2);E.length<=A.length&&E.length<p?(p=E.length,m=E,x(y,g)):A.length<=E.length&&A.length<p&&(p=A.length,m=A,x(v,g))}for(var S=this.spawn(m.map(function(F){return i[F[0]]})),_=this.spawn(),I=this.spawn(),D=g[0],k=0;k<g.length;k++){var L=g[k],R=n[k];L===D?_.merge(R):I.merge(R)}var O=o(function(P){var z=e.spawn();return P.forEach(function($){z.merge($),$.connectedEdges().forEach(function(H){e.contains(H)&&!S.contains(H)&&z.merge(H)})}),z},"constructComponent"),M=[O(_),O(I)],B={cut:S,components:M,partition1:_,partition2:I};return B},"kargerStein")},Aqe=o(function(e){return{x:e.x,y:e.y}},"copyPosition"),MS=o(function(e,r,n){return{x:e.x*r+n.x,y:e.y*r+n.y}},"modelToRenderedPosition"),pme=o(function(e,r,n){return{x:(e.x-n.x)/r,y:(e.y-n.y)/r}},"renderedToModelPosition"),U1=o(function(e){return{x:e[0],y:e[1]}},"array2point"),_qe=o(function(e){for(var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=1/0,a=r;a<n;a++){var s=e[a];isFinite(s)&&(i=Math.min(s,i))}return i},"min"),Dqe=o(function(e){for(var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=-1/0,a=r;a<n;a++){var s=e[a];isFinite(s)&&(i=Math.max(s,i))}return i},"max"),Lqe=o(function(e){for(var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=0,a=0,s=r;s<n;s++){var l=e[s];isFinite(l)&&(i+=l,a++)}return i/a},"mean"),Rqe=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,a=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,s=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;i?e=e.slice(r,n):(n<e.length&&e.splice(n,e.length-n),r>0&&e.splice(0,r));for(var l=0,u=e.length-1;u>=0;u--){var h=e[u];s?isFinite(h)||(e[u]=-1/0,l++):e.splice(u,1)}a&&e.sort(function(p,m){return p-m});var f=e.length,d=Math.floor(f/2);return f%2!==0?e[d+1+l]:(e[d-1+l]+e[d+l])/2},"median"),Nqe=o(function(e){return Math.PI*e/180},"deg2rad"),K6=o(function(e,r){return Math.atan2(r,e)-Math.PI/2},"getAngleFromDisp"),iB=Math.log2||function(t){return Math.log(t)/Math.log(2)},mme=o(function(e){return e>0?1:e<0?-1:0},"signum"),Gp=o(function(e,r){return Math.sqrt(Op(e,r))},"dist"),Op=o(function(e,r){var n=r.x-e.x,i=r.y-e.y;return n*n+i*i},"sqdist"),Mqe=o(function(e){for(var r=e.length,n=0,i=0;i<r;i++)n+=e[i];for(var a=0;a<r;a++)e[a]=e[a]/n;return e},"inPlaceSumNormalize"),oa=o(function(e,r,n,i){return(1-i)*(1-i)*e+2*(1-i)*i*r+i*i*n},"qbezierAt"),W1=o(function(e,r,n,i){return{x:oa(e.x,r.x,n.x,i),y:oa(e.y,r.y,n.y,i)}},"qbezierPtAt"),Iqe=o(function(e,r,n,i){var a={x:r.x-e.x,y:r.y-e.y},s=Gp(e,r),l={x:a.x/s,y:a.y/s};return n=n??0,i=i??n*s,{x:e.x+l.x*i,y:e.y+l.y*i}},"lineAt"),Yb=o(function(e,r,n){return Math.max(e,Math.min(n,r))},"bound"),Hs=o(function(e){if(e==null)return{x1:1/0,y1:1/0,x2:-1/0,y2:-1/0,w:0,h:0};if(e.x1!=null&&e.y1!=null){if(e.x2!=null&&e.y2!=null&&e.x2>=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(e.w!=null&&e.h!=null&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},"makeBoundingBox"),Oqe=o(function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},"copyBoundingBox"),Pqe=o(function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},"clearBoundingBox"),Bqe=o(function(e,r,n){return{x1:e.x1+r,x2:e.x2+r,y1:e.y1+n,y2:e.y2+n,w:e.w,h:e.h}},"shiftBoundingBox"),gme=o(function(e,r){e.x1=Math.min(e.x1,r.x1),e.x2=Math.max(e.x2,r.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,r.y1),e.y2=Math.max(e.y2,r.y2),e.h=e.y2-e.y1},"updateBoundingBox"),Fqe=o(function(e,r,n){e.x1=Math.min(e.x1,r),e.x2=Math.max(e.x2,r),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},"expandBoundingBoxByPoint"),cS=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return e.x1-=r,e.x2+=r,e.y1-=r,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},"expandBoundingBox"),uS=o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[0],n,i,a,s;if(r.length===1)n=i=a=s=r[0];else if(r.length===2)n=a=r[0],s=i=r[1];else if(r.length===4){var l=_i(r,4);n=l[0],i=l[1],a=l[2],s=l[3]}return e.x1-=s,e.x2+=i,e.y1-=n,e.y2+=a,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},"expandBoundingBoxSides"),Fpe=o(function(e,r){e.x1=r.x1,e.y1=r.y1,e.x2=r.x2,e.y2=r.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},"assignBoundingBox"),aB=o(function(e,r){return!(e.x1>r.x2||r.x1>e.x2||e.x2<r.x1||r.x2<e.x1||e.y2<r.y1||r.y2<e.y1||e.y1>r.y2||r.y1>e.y2)},"boundingBoxesIntersect"),K1=o(function(e,r,n){return e.x1<=r&&r<=e.x2&&e.y1<=n&&n<=e.y2},"inBoundingBox"),$qe=o(function(e,r){return K1(e,r.x,r.y)},"pointInBoundingBox"),yme=o(function(e,r){return K1(e,r.x1,r.y1)&&K1(e,r.x2,r.y2)},"boundingBoxInBoundingBox"),vme=o(function(e,r,n,i,a,s,l){var u=arguments.length>7&&arguments[7]!==void 0?arguments[7]:"auto",h=u==="auto"?Vp(a,s):u,f=a/2,d=s/2;h=Math.min(h,f,d);var p=h!==f,m=h!==d,g;if(p){var y=n-f+h-l,v=i-d-l,x=n+f-h+l,b=v;if(g=Ef(e,r,n,i,y,v,x,b,!1),g.length>0)return g}if(m){var w=n+f+l,C=i-d+h-l,T=w,E=i+d-h+l;if(g=Ef(e,r,n,i,w,C,T,E,!1),g.length>0)return g}if(p){var A=n-f+h-l,S=i+d+l,_=n+f-h+l,I=S;if(g=Ef(e,r,n,i,A,S,_,I,!1),g.length>0)return g}if(m){var D=n-f-l,k=i-d+h-l,L=D,R=i+d-h+l;if(g=Ef(e,r,n,i,D,k,L,R,!1),g.length>0)return g}var O;{var M=n-f+h,B=i-d+h;if(O=Pb(e,r,n,i,M,B,h+l),O.length>0&&O[0]<=M&&O[1]<=B)return[O[0],O[1]]}{var F=n+f-h,P=i-d+h;if(O=Pb(e,r,n,i,F,P,h+l),O.length>0&&O[0]>=F&&O[1]<=P)return[O[0],O[1]]}{var z=n+f-h,$=i+d-h;if(O=Pb(e,r,n,i,z,$,h+l),O.length>0&&O[0]>=z&&O[1]>=$)return[O[0],O[1]]}{var H=n-f+h,Q=i+d-h;if(O=Pb(e,r,n,i,H,Q,h+l),O.length>0&&O[0]<=H&&O[1]>=Q)return[O[0],O[1]]}return[]},"roundRectangleIntersectLine"),zqe=o(function(e,r,n,i,a,s,l){var u=l,h=Math.min(n,a),f=Math.max(n,a),d=Math.min(i,s),p=Math.max(i,s);return h-u<=e&&e<=f+u&&d-u<=r&&r<=p+u},"inLineVicinity"),Gqe=o(function(e,r,n,i,a,s,l,u,h){var f={x1:Math.min(n,l,a)-h,x2:Math.max(n,l,a)+h,y1:Math.min(i,u,s)-h,y2:Math.max(i,u,s)+h};return!(e<f.x1||e>f.x2||r<f.y1||r>f.y2)},"inBezierVicinity"),Vqe=o(function(e,r,n,i){n-=i;var a=r*r-4*e*n;if(a<0)return[];var s=Math.sqrt(a),l=2*e,u=(-r+s)/l,h=(-r-s)/l;return[u,h]},"solveQuadratic"),Uqe=o(function(e,r,n,i,a){var s=1e-5;e===0&&(e=s),r/=e,n/=e,i/=e;var l,u,h,f,d,p,m,g;if(u=(3*n-r*r)/9,h=-(27*i)+r*(9*n-2*(r*r)),h/=54,l=u*u*u+h*h,a[1]=0,m=r/3,l>0){d=h+Math.sqrt(l),d=d<0?-Math.pow(-d,1/3):Math.pow(d,1/3),p=h-Math.sqrt(l),p=p<0?-Math.pow(-p,1/3):Math.pow(p,1/3),a[0]=-m+d+p,m+=(d+p)/2,a[4]=a[2]=-m,m=Math.sqrt(3)*(-p+d)/2,a[3]=m,a[5]=-m;return}if(a[5]=a[3]=0,l===0){g=h<0?-Math.pow(-h,1/3):Math.pow(h,1/3),a[0]=-m+2*g,a[4]=a[2]=-(g+m);return}u=-u,f=u*u*u,f=Math.acos(h/Math.sqrt(f)),g=2*Math.sqrt(u),a[0]=-m+g*Math.cos(f/3),a[2]=-m+g*Math.cos((f+2*Math.PI)/3),a[4]=-m+g*Math.cos((f+4*Math.PI)/3)},"solveCubic"),Hqe=o(function(e,r,n,i,a,s,l,u){var h=1*n*n-4*n*a+2*n*l+4*a*a-4*a*l+l*l+i*i-4*i*s+2*i*u+4*s*s-4*s*u+u*u,f=1*9*n*a-3*n*n-3*n*l-6*a*a+3*a*l+9*i*s-3*i*i-3*i*u-6*s*s+3*s*u,d=1*3*n*n-6*n*a+n*l-n*e+2*a*a+2*a*e-l*e+3*i*i-6*i*s+i*u-i*r+2*s*s+2*s*r-u*r,p=1*n*a-n*n+n*e-a*e+i*s-i*i+i*r-s*r,m=[];Uqe(h,f,d,p,m);for(var g=1e-7,y=[],v=0;v<6;v+=2)Math.abs(m[v+1])<g&&m[v]>=0&&m[v]<=1&&y.push(m[v]);y.push(1),y.push(0);for(var x=-1,b,w,C,T=0;T<y.length;T++)b=Math.pow(1-y[T],2)*n+2*(1-y[T])*y[T]*a+y[T]*y[T]*l,w=Math.pow(1-y[T],2)*i+2*(1-y[T])*y[T]*s+y[T]*y[T]*u,C=Math.pow(b-e,2)+Math.pow(w-r,2),x>=0?C<x&&(x=C):x=C;return x},"sqdistToQuadraticBezier"),Wqe=o(function(e,r,n,i,a,s){var l=[e-n,r-i],u=[a-n,s-i],h=u[0]*u[0]+u[1]*u[1],f=l[0]*l[0]+l[1]*l[1],d=l[0]*u[0]+l[1]*u[1],p=d*d/h;return d<0?f:p>h?(e-a)*(e-a)+(r-s)*(r-s):f-p},"sqdistToFiniteLine"),Us=o(function(e,r,n){for(var i,a,s,l,u,h=0,f=0;f<n.length/2;f++)if(i=n[f*2],a=n[f*2+1],f+1<n.length/2?(s=n[(f+1)*2],l=n[(f+1)*2+1]):(s=n[(f+1-n.length/2)*2],l=n[(f+1-n.length/2)*2+1]),!(i==e&&s==e))if(i>=e&&e>=s||i<=e&&e<=s)u=(e-i)/(s-i)*(l-a)+a,u>r&&h++;else continue;return h%2!==0},"pointInsidePolygonPoints"),Zu=o(function(e,r,n,i,a,s,l,u,h){var f=new Array(n.length),d;u[0]!=null?(d=Math.atan(u[1]/u[0]),u[0]<0?d=d+Math.PI/2:d=-d-Math.PI/2):d=u;for(var p=Math.cos(-d),m=Math.sin(-d),g=0;g<f.length/2;g++)f[g*2]=s/2*(n[g*2]*p-n[g*2+1]*m),f[g*2+1]=l/2*(n[g*2+1]*p+n[g*2]*m),f[g*2]+=i,f[g*2+1]+=a;var y;if(h>0){var v=TS(f,-h);y=wS(v)}else y=f;return Us(e,r,y)},"pointInsidePolygon"),qqe=o(function(e,r,n,i,a,s,l,u){for(var h=new Array(n.length*2),f=0;f<u.length;f++){var d=u[f];h[f*4+0]=d.startX,h[f*4+1]=d.startY,h[f*4+2]=d.stopX,h[f*4+3]=d.stopY;var p=Math.pow(d.cx-e,2)+Math.pow(d.cy-r,2);if(p<=Math.pow(d.radius,2))return!0}return Us(e,r,h)},"pointInsideRoundPolygon"),wS=o(function(e){for(var r=new Array(e.length/2),n,i,a,s,l,u,h,f,d=0;d<e.length/4;d++){n=e[d*4],i=e[d*4+1],a=e[d*4+2],s=e[d*4+3],d<e.length/4-1?(l=e[(d+1)*4],u=e[(d+1)*4+1],h=e[(d+1)*4+2],f=e[(d+1)*4+3]):(l=e[0],u=e[1],h=e[2],f=e[3]);var p=Ef(n,i,a,s,l,u,h,f,!0);r[d*2]=p[0],r[d*2+1]=p[1]}return r},"joinLines"),TS=o(function(e,r){for(var n=new Array(e.length*2),i,a,s,l,u=0;u<e.length/2;u++){i=e[u*2],a=e[u*2+1],u<e.length/2-1?(s=e[(u+1)*2],l=e[(u+1)*2+1]):(s=e[0],l=e[1]);var h=l-a,f=-(s-i),d=Math.sqrt(h*h+f*f),p=h/d,m=f/d;n[u*4]=i+p*r,n[u*4+1]=a+m*r,n[u*4+2]=s+p*r,n[u*4+3]=l+m*r}return n},"expandPolygon"),Yqe=o(function(e,r,n,i,a,s){var l=n-e,u=i-r;l/=a,u/=s;var h=Math.sqrt(l*l+u*u),f=h-1;if(f<0)return[];var d=f/h;return[(n-e)*d+e,(i-r)*d+r]},"intersectLineEllipse"),$p=o(function(e,r,n,i,a,s,l){return e-=a,r-=s,e/=n/2+l,r/=i/2+l,e*e+r*r<=1},"checkInEllipse"),Pb=o(function(e,r,n,i,a,s,l){var u=[n-e,i-r],h=[e-a,r-s],f=u[0]*u[0]+u[1]*u[1],d=2*(h[0]*u[0]+h[1]*u[1]),p=h[0]*h[0]+h[1]*h[1]-l*l,m=d*d-4*f*p;if(m<0)return[];var g=(-d+Math.sqrt(m))/(2*f),y=(-d-Math.sqrt(m))/(2*f),v=Math.min(g,y),x=Math.max(g,y),b=[];if(v>=0&&v<=1&&b.push(v),x>=0&&x<=1&&b.push(x),b.length===0)return[];var w=b[0]*u[0]+e,C=b[0]*u[1]+r;if(b.length>1){if(b[0]==b[1])return[w,C];var T=b[1]*u[0]+e,E=b[1]*u[1]+r;return[w,C,T,E]}else return[w,C]},"intersectLineCircle"),TP=o(function(e,r,n){return r<=e&&e<=n||n<=e&&e<=r?e:e<=r&&r<=n||n<=r&&r<=e?r:n},"midOfThree"),Ef=o(function(e,r,n,i,a,s,l,u,h){var f=e-a,d=n-e,p=l-a,m=r-s,g=i-r,y=u-s,v=p*m-y*f,x=d*m-g*f,b=y*d-p*g;if(b!==0){var w=v/b,C=x/b,T=.001,E=0-T,A=1+T;return E<=w&&w<=A&&E<=C&&C<=A?[e+w*d,r+w*g]:h?[e+w*d,r+w*g]:[]}else return v===0||x===0?TP(e,n,l)===l?[l,u]:TP(e,n,a)===a?[a,s]:TP(a,l,n)===n?[n,i]:[]:[]},"finiteLinesIntersect"),Xb=o(function(e,r,n,i,a,s,l,u){var h=[],f,d=new Array(n.length),p=!0;s==null&&(p=!1);var m;if(p){for(var g=0;g<d.length/2;g++)d[g*2]=n[g*2]*s+i,d[g*2+1]=n[g*2+1]*l+a;if(u>0){var y=TS(d,-u);m=wS(y)}else m=d}else m=n;for(var v,x,b,w,C=0;C<m.length/2;C++)v=m[C*2],x=m[C*2+1],C<m.length/2-1?(b=m[(C+1)*2],w=m[(C+1)*2+1]):(b=m[0],w=m[1]),f=Ef(e,r,i,a,v,x,b,w),f.length!==0&&h.push(f[0],f[1]);return h},"polygonIntersectLine"),Xqe=o(function(e,r,n,i,a,s,l,u,h){var f=[],d,p=new Array(n.length*2);h.forEach(function(b,w){w===0?(p[p.length-2]=b.startX,p[p.length-1]=b.startY):(p[w*4-2]=b.startX,p[w*4-1]=b.startY),p[w*4]=b.stopX,p[w*4+1]=b.stopY,d=Pb(e,r,i,a,b.cx,b.cy,b.radius),d.length!==0&&f.push(d[0],d[1])});for(var m=0;m<p.length/4;m++)d=Ef(e,r,i,a,p[m*4],p[m*4+1],p[m*4+2],p[m*4+3],!1),d.length!==0&&f.push(d[0],d[1]);if(f.length>2){for(var g=[f[0],f[1]],y=Math.pow(g[0]-e,2)+Math.pow(g[1]-r,2),v=1;v<f.length/2;v++){var x=Math.pow(f[v*2]-e,2)+Math.pow(f[v*2+1]-r,2);x<=y&&(g[0]=f[v*2],g[1]=f[v*2+1],y=x)}return g}return f},"roundPolygonIntersectLine"),Q6=o(function(e,r,n){var i=[e[0]-r[0],e[1]-r[1]],a=Math.sqrt(i[0]*i[0]+i[1]*i[1]),s=(a-n)/a;return s<0&&(s=1e-5),[r[0]+s*i[0],r[1]+s*i[1]]},"shortenIntersection"),gs=o(function(e,r){var n=PP(e,r);return n=xme(n),n},"generateUnitNgonPointsFitToSquare"),xme=o(function(e){for(var r,n,i=e.length/2,a=1/0,s=1/0,l=-1/0,u=-1/0,h=0;h<i;h++)r=e[2*h],n=e[2*h+1],a=Math.min(a,r),l=Math.max(l,r),s=Math.min(s,n),u=Math.max(u,n);for(var f=2/(l-a),d=2/(u-s),p=0;p<i;p++)r=e[2*p]=e[2*p]*f,n=e[2*p+1]=e[2*p+1]*d,a=Math.min(a,r),l=Math.max(l,r),s=Math.min(s,n),u=Math.max(u,n);if(s<-1)for(var m=0;m<i;m++)n=e[2*m+1]=e[2*m+1]+(-1-s);return e},"fitPolygonToSquare"),PP=o(function(e,r){var n=1/e*2*Math.PI,i=e%2===0?Math.PI/2+n/2:Math.PI/2;i+=r;for(var a=new Array(e*2),s,l=0;l<e;l++)s=l*n+i,a[2*l]=Math.cos(s),a[2*l+1]=Math.sin(-s);return a},"generateUnitNgonPoints"),Vp=o(function(e,r){return Math.min(e/4,r/4,8)},"getRoundRectangleRadius"),bme=o(function(e,r){return Math.min(e/10,r/10,8)},"getRoundPolygonRadius"),sB=o(function(){return 8},"getCutRectangleCornerLength"),jqe=o(function(e,r,n){return[e-2*r+n,2*(r-e),e]},"bezierPtsToQuadCoeff"),BP=o(function(e,r){return{heightOffset:Math.min(15,.05*r),widthOffset:Math.min(100,.25*e),ctrlPtOffsetPct:.05}},"getBarrelCurveConstants"),Kqe=la({dampingFactor:.8,precision:1e-6,iterations:200,weight:o(function(e){return 1},"weight")}),Qqe={pageRank:o(function(e){for(var r=Kqe(e),n=r.dampingFactor,i=r.precision,a=r.iterations,s=r.weight,l=this._private.cy,u=this.byGroup(),h=u.nodes,f=u.edges,d=h.length,p=d*d,m=f.length,g=new Array(p),y=new Array(d),v=(1-n)/d,x=0;x<d;x++){for(var b=0;b<d;b++){var w=x*d+b;g[w]=0}y[x]=0}for(var C=0;C<m;C++){var T=f[C],E=T.data("source"),A=T.data("target");if(E!==A){var S=h.indexOfId(E),_=h.indexOfId(A),I=s(T),D=_*d+S;g[D]+=I,y[S]+=I}}for(var k=1/d+v,L=0;L<d;L++)if(y[L]===0)for(var R=0;R<d;R++){var O=R*d+L;g[O]=k}else for(var M=0;M<d;M++){var B=M*d+L;g[B]=g[B]/y[L]+v}for(var F=new Array(d),P=new Array(d),z,$=0;$<d;$++)F[$]=1;for(var H=0;H<a;H++){for(var Q=0;Q<d;Q++)P[Q]=0;for(var j=0;j<d;j++)for(var ie=0;ie<d;ie++){var ne=j*d+ie;P[j]+=g[ne]*F[ie]}Mqe(P),z=F,F=P,P=z;for(var le=0,he=0;he<d;he++){var K=z[he]-F[he];le+=K*K}if(le<i)break}var X={rank:o(function(J){return J=l.collection(J)[0],F[h.indexOf(J)]},"rank")};return X},"pageRank")},$pe=la({root:null,weight:o(function(e){return 1},"weight"),directed:!1,alpha:0}),q1={degreeCentralityNormalized:o(function(e){e=$pe(e);var r=this.cy(),n=this.nodes(),i=n.length;if(e.directed){for(var f={},d={},p=0,m=0,g=0;g<i;g++){var y=n[g],v=y.id();e.root=y;var x=this.degreeCentrality(e);p<x.indegree&&(p=x.indegree),m<x.outdegree&&(m=x.outdegree),f[v]=x.indegree,d[v]=x.outdegree}return{indegree:o(function(w){return p==0?0:(Zt(w)&&(w=r.filter(w)),f[w.id()]/p)},"indegree"),outdegree:o(function(w){return m===0?0:(Zt(w)&&(w=r.filter(w)),d[w.id()]/m)},"outdegree")}}else{for(var a={},s=0,l=0;l<i;l++){var u=n[l];e.root=u;var h=this.degreeCentrality(e);s<h.degree&&(s=h.degree),a[u.id()]=h.degree}return{degree:o(function(w){return s===0?0:(Zt(w)&&(w=r.filter(w)),a[w.id()]/s)},"degree")}}},"degreeCentralityNormalized"),degreeCentrality:o(function(e){e=$pe(e);var r=this.cy(),n=this,i=e,a=i.root,s=i.weight,l=i.directed,u=i.alpha;if(a=r.collection(a)[0],l){for(var m=a.connectedEdges(),g=m.filter(function(E){return E.target().same(a)&&n.has(E)}),y=m.filter(function(E){return E.source().same(a)&&n.has(E)}),v=g.length,x=y.length,b=0,w=0,C=0;C<g.length;C++)b+=s(g[C]);for(var T=0;T<y.length;T++)w+=s(y[T]);return{indegree:Math.pow(v,1-u)*Math.pow(b,u),outdegree:Math.pow(x,1-u)*Math.pow(w,u)}}else{for(var h=a.connectedEdges().intersection(n),f=h.length,d=0,p=0;p<h.length;p++)d+=s(h[p]);return{degree:Math.pow(f,1-u)*Math.pow(d,u)}}},"degreeCentrality")};q1.dc=q1.degreeCentrality;q1.dcn=q1.degreeCentralityNormalised=q1.degreeCentralityNormalized;zpe=la({harmonic:!0,weight:o(function(){return 1},"weight"),directed:!1,root:null}),Y1={closenessCentralityNormalized:o(function(e){for(var r=zpe(e),n=r.harmonic,i=r.weight,a=r.directed,s=this.cy(),l={},u=0,h=this.nodes(),f=this.floydWarshall({weight:i,directed:a}),d=0;d<h.length;d++){for(var p=0,m=h[d],g=0;g<h.length;g++)if(d!==g){var y=f.distance(m,h[g]);n?p+=1/y:p+=y}n||(p=1/p),u<p&&(u=p),l[m.id()]=p}return{closeness:o(function(x){return u==0?0:(Zt(x)?x=s.filter(x)[0].id():x=x.id(),l[x]/u)},"closeness")}},"closenessCentralityNormalized"),closenessCentrality:o(function(e){var r=zpe(e),n=r.root,i=r.weight,a=r.directed,s=r.harmonic;n=this.filter(n)[0];for(var l=this.dijkstra({root:n,weight:i,directed:a}),u=0,h=this.nodes(),f=0;f<h.length;f++){var d=h[f];if(!d.same(n)){var p=l.distanceTo(d);s?u+=1/p:u+=p}}return s?u:1/u},"closenessCentrality")};Y1.cc=Y1.closenessCentrality;Y1.ccn=Y1.closenessCentralityNormalised=Y1.closenessCentralityNormalized;Zqe=la({weight:null,directed:!1}),FP={betweennessCentrality:o(function(e){for(var r=Zqe(e),n=r.directed,i=r.weight,a=i!=null,s=this.cy(),l=this.nodes(),u={},h={},f=0,d={set:o(function(w,C){h[w]=C,C>f&&(f=C)},"set"),get:o(function(w){return h[w]},"get")},p=0;p<l.length;p++){var m=l[p],g=m.id();n?u[g]=m.outgoers().nodes():u[g]=m.openNeighborhood().nodes(),d.set(g,0)}for(var y=o(function(w){for(var C=l[w].id(),T=[],E={},A={},S={},_=new i4(function(ie,ne){return S[ie]-S[ne]}),I=0;I<l.length;I++){var D=l[I].id();E[D]=[],A[D]=0,S[D]=1/0}for(A[C]=1,S[C]=0,_.push(C);!_.empty();){var k=_.pop();if(T.push(k),a)for(var L=0;L<u[k].length;L++){var R=u[k][L],O=s.getElementById(k),M=void 0;O.edgesTo(R).length>0?M=O.edgesTo(R)[0]:M=R.edgesTo(O)[0];var B=i(M);R=R.id(),S[R]>S[k]+B&&(S[R]=S[k]+B,_.nodes.indexOf(R)<0?_.push(R):_.updateItem(R),A[R]=0,E[R]=[]),S[R]==S[k]+B&&(A[R]=A[R]+A[k],E[R].push(k))}else for(var F=0;F<u[k].length;F++){var P=u[k][F].id();S[P]==1/0&&(_.push(P),S[P]=S[k]+1),S[P]==S[k]+1&&(A[P]=A[P]+A[k],E[P].push(k))}}for(var z={},$=0;$<l.length;$++)z[l[$].id()]=0;for(;T.length>0;){for(var H=T.pop(),Q=0;Q<E[H].length;Q++){var j=E[H][Q];z[j]=z[j]+A[j]/A[H]*(1+z[H])}H!=l[w].id()&&d.set(H,d.get(H)+z[H])}},"_loop"),v=0;v<l.length;v++)y(v);var x={betweenness:o(function(w){var C=s.collection(w).id();return d.get(C)},"betweenness"),betweennessNormalized:o(function(w){if(f==0)return 0;var C=s.collection(w).id();return d.get(C)/f},"betweennessNormalized")};return x.betweennessNormalised=x.betweennessNormalized,x},"betweennessCentrality")};FP.bc=FP.betweennessCentrality;Jqe=la({expandFactor:2,inflateFactor:2,multFactor:1,maxIterations:20,attributes:[function(t){return 1}]}),eYe=o(function(e){return Jqe(e)},"setOptions"),tYe=o(function(e,r){for(var n=0,i=0;i<r.length;i++)n+=r[i](e);return n},"getSimilarity"),rYe=o(function(e,r,n){for(var i=0;i<r;i++)e[i*r+i]=n},"addLoops"),wme=o(function(e,r){for(var n,i=0;i<r;i++){n=0;for(var a=0;a<r;a++)n+=e[a*r+i];for(var s=0;s<r;s++)e[s*r+i]=e[s*r+i]/n}},"normalize"),nYe=o(function(e,r,n){for(var i=new Array(n*n),a=0;a<n;a++){for(var s=0;s<n;s++)i[a*n+s]=0;for(var l=0;l<n;l++)for(var u=0;u<n;u++)i[a*n+u]+=e[a*n+l]*r[l*n+u]}return i},"mmult"),iYe=o(function(e,r,n){for(var i=e.slice(0),a=1;a<n;a++)e=nYe(e,i,r);return e},"expand"),aYe=o(function(e,r,n){for(var i=new Array(r*r),a=0;a<r*r;a++)i[a]=Math.pow(e[a],n);return wme(i,r),i},"inflate"),sYe=o(function(e,r,n,i){for(var a=0;a<n;a++){var s=Math.round(e[a]*Math.pow(10,i))/Math.pow(10,i),l=Math.round(r[a]*Math.pow(10,i))/Math.pow(10,i);if(s!==l)return!1}return!0},"hasConverged"),oYe=o(function(e,r,n,i){for(var a=[],s=0;s<r;s++){for(var l=[],u=0;u<r;u++)Math.round(e[s*r+u]*1e3)/1e3>0&&l.push(n[u]);l.length!==0&&a.push(i.collection(l))}return a},"assign"),lYe=o(function(e,r){for(var n=0;n<e.length;n++)if(!r[n]||e[n].id()!==r[n].id())return!1;return!0},"isDuplicate"),cYe=o(function(e){for(var r=0;r<e.length;r++)for(var n=0;n<e.length;n++)r!=n&&lYe(e[r],e[n])&&e.splice(n,1);return e},"removeDuplicates"),Gpe=o(function(e){for(var r=this.nodes(),n=this.edges(),i=this.cy(),a=eYe(e),s={},l=0;l<r.length;l++)s[r[l].id()]=l;for(var u=r.length,h=u*u,f=new Array(h),d,p=0;p<h;p++)f[p]=0;for(var m=0;m<n.length;m++){var g=n[m],y=s[g.source().id()],v=s[g.target().id()],x=tYe(g,a.attributes);f[y*u+v]+=x,f[v*u+y]+=x}rYe(f,u,a.multFactor),wme(f,u);for(var b=!0,w=0;b&&w<a.maxIterations;)b=!1,d=iYe(f,u,a.expandFactor),f=aYe(d,u,a.inflateFactor),sYe(f,d,h,4)||(b=!0),w++;var C=oYe(f,u,r,i);return C=cYe(C),C},"markovClustering"),uYe={markovClustering:Gpe,mcl:Gpe},hYe=o(function(e){return e},"identity"),Tme=o(function(e,r){return Math.abs(r-e)},"absDiff"),Vpe=o(function(e,r,n){return e+Tme(r,n)},"addAbsDiff"),Upe=o(function(e,r,n){return e+Math.pow(n-r,2)},"addSquaredDiff"),fYe=o(function(e){return Math.sqrt(e)},"sqrt"),dYe=o(function(e,r,n){return Math.max(e,Tme(r,n))},"maxAbsDiff"),_b=o(function(e,r,n,i,a){for(var s=arguments.length>5&&arguments[5]!==void 0?arguments[5]:hYe,l=i,u,h,f=0;f<e;f++)u=r(f),h=n(f),l=a(l,u,h);return s(l)},"getDistance"),Q1={euclidean:o(function(e,r,n){return e>=2?_b(e,r,n,0,Upe,fYe):_b(e,r,n,0,Vpe)},"euclidean"),squaredEuclidean:o(function(e,r,n){return _b(e,r,n,0,Upe)},"squaredEuclidean"),manhattan:o(function(e,r,n){return _b(e,r,n,0,Vpe)},"manhattan"),max:o(function(e,r,n){return _b(e,r,n,-1/0,dYe)},"max")};Q1["squared-euclidean"]=Q1.squaredEuclidean;Q1.squaredeuclidean=Q1.squaredEuclidean;o(IS,"clusteringDistance");pYe=la({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),oB=o(function(e){return pYe(e)},"setOptions"),kS=o(function(e,r,n,i,a){var s=a!=="kMedoids",l=s?function(d){return n[d]}:function(d){return i[d](n)},u=o(function(p){return i[p](r)},"getQ"),h=n,f=r;return IS(e,i.length,l,u,h,f)},"getDist"),kP=o(function(e,r,n){for(var i=n.length,a=new Array(i),s=new Array(i),l=new Array(r),u=null,h=0;h<i;h++)a[h]=e.min(n[h]).value,s[h]=e.max(n[h]).value;for(var f=0;f<r;f++){u=[];for(var d=0;d<i;d++)u[d]=Math.random()*(s[d]-a[d])+a[d];l[f]=u}return l},"randomCentroids"),kme=o(function(e,r,n,i,a){for(var s=1/0,l=0,u=0;u<r.length;u++){var h=kS(n,e,r[u],i,a);h<s&&(s=h,l=u)}return l},"classify"),Eme=o(function(e,r,n){for(var i=[],a=null,s=0;s<r.length;s++)a=r[s],n[a.id()]===e&&i.push(a);return i},"buildCluster"),mYe=o(function(e,r,n){return Math.abs(r-e)<=n},"haveValuesConverged"),gYe=o(function(e,r,n){for(var i=0;i<e.length;i++)for(var a=0;a<e[i].length;a++){var s=Math.abs(e[i][a]-r[i][a]);if(s>n)return!1}return!0},"haveMatricesConverged"),yYe=o(function(e,r,n){for(var i=0;i<n;i++)if(e===r[i])return!0;return!1},"seenBefore"),Hpe=o(function(e,r){var n=new Array(r);if(e.length<50)for(var i=0;i<r;i++){for(var a=e[Math.floor(Math.random()*e.length)];yYe(a,n,i);)a=e[Math.floor(Math.random()*e.length)];n[i]=a}else for(var s=0;s<r;s++)n[s]=e[Math.floor(Math.random()*e.length)];return n},"randomMedoids"),Wpe=o(function(e,r,n){for(var i=0,a=0;a<r.length;a++)i+=kS("manhattan",r[a],e,n,"kMedoids");return i},"findCost"),vYe=o(function(e){var r=this.cy(),n=this.nodes(),i=null,a=oB(e),s=new Array(a.k),l={},u;a.testMode?typeof a.testCentroids=="number"?(a.testCentroids,u=kP(n,a.k,a.attributes)):Wi(a.testCentroids)==="object"?u=a.testCentroids:u=kP(n,a.k,a.attributes):u=kP(n,a.k,a.attributes);for(var h=!0,f=0;h&&f<a.maxIterations;){for(var d=0;d<n.length;d++)i=n[d],l[i.id()]=kme(i,u,a.distance,a.attributes,"kMeans");h=!1;for(var p=0;p<a.k;p++){var m=Eme(p,n,l);if(m.length!==0){for(var g=a.attributes.length,y=u[p],v=new Array(g),x=new Array(g),b=0;b<g;b++){x[b]=0;for(var w=0;w<m.length;w++)i=m[w],x[b]+=a.attributes[b](i);v[b]=x[b]/m.length,mYe(v[b],y[b],a.sensitivityThreshold)||(h=!0)}u[p]=v,s[p]=r.collection(m)}}f++}return s},"kMeans"),xYe=o(function(e){var r=this.cy(),n=this.nodes(),i=null,a=oB(e),s=new Array(a.k),l,u={},h,f=new Array(a.k);a.testMode?typeof a.testCentroids=="number"||(Wi(a.testCentroids)==="object"?l=a.testCentroids:l=Hpe(n,a.k)):l=Hpe(n,a.k);for(var d=!0,p=0;d&&p<a.maxIterations;){for(var m=0;m<n.length;m++)i=n[m],u[i.id()]=kme(i,l,a.distance,a.attributes,"kMedoids");d=!1;for(var g=0;g<l.length;g++){var y=Eme(g,n,u);if(y.length!==0){f[g]=Wpe(l[g],y,a.attributes);for(var v=0;v<y.length;v++)h=Wpe(y[v],y,a.attributes),h<f[g]&&(f[g]=h,l[g]=y[v],d=!0);s[g]=r.collection(y)}}p++}return s},"kMedoids"),bYe=o(function(e,r,n,i,a){for(var s,l,u=0;u<r.length;u++)for(var h=0;h<e.length;h++)i[u][h]=Math.pow(n[u][h],a.m);for(var f=0;f<e.length;f++)for(var d=0;d<a.attributes.length;d++){s=0,l=0;for(var p=0;p<r.length;p++)s+=i[p][f]*a.attributes[d](r[p]),l+=i[p][f];e[f][d]=s/l}},"updateCentroids"),wYe=o(function(e,r,n,i,a){for(var s=0;s<e.length;s++)r[s]=e[s].slice();for(var l,u,h,f=2/(a.m-1),d=0;d<n.length;d++)for(var p=0;p<i.length;p++){l=0;for(var m=0;m<n.length;m++)u=kS(a.distance,i[p],n[d],a.attributes,"cmeans"),h=kS(a.distance,i[p],n[m],a.attributes,"cmeans"),l+=Math.pow(u/h,f);e[p][d]=1/l}},"updateMembership"),TYe=o(function(e,r,n,i){for(var a=new Array(n.k),s=0;s<a.length;s++)a[s]=[];for(var l,u,h=0;h<r.length;h++){l=-1/0,u=-1;for(var f=0;f<r[0].length;f++)r[h][f]>l&&(l=r[h][f],u=f);a[u].push(e[h])}for(var d=0;d<a.length;d++)a[d]=i.collection(a[d]);return a},"assign"),qpe=o(function(e){var r=this.cy(),n=this.nodes(),i=oB(e),a,s,l,u,h;u=new Array(n.length);for(var f=0;f<n.length;f++)u[f]=new Array(i.k);l=new Array(n.length);for(var d=0;d<n.length;d++)l[d]=new Array(i.k);for(var p=0;p<n.length;p++){for(var m=0,g=0;g<i.k;g++)l[p][g]=Math.random(),m+=l[p][g];for(var y=0;y<i.k;y++)l[p][y]=l[p][y]/m}s=new Array(i.k);for(var v=0;v<i.k;v++)s[v]=new Array(i.attributes.length);h=new Array(n.length);for(var x=0;x<n.length;x++)h[x]=new Array(i.k);for(var b=!0,w=0;b&&w<i.maxIterations;)b=!1,bYe(s,n,l,h,i),wYe(l,u,s,n,i),gYe(l,u,i.sensitivityThreshold)||(b=!0),w++;return a=TYe(n,l,i,r),{clusters:a,degreeOfMembership:l}},"fuzzyCMeans"),kYe={kMeans:vYe,kMedoids:xYe,fuzzyCMeans:qpe,fcm:qpe},EYe=la({distance:"euclidean",linkage:"min",mode:"threshold",threshold:1/0,addDendrogram:!1,dendrogramDepth:0,attributes:[]}),SYe={single:"min",complete:"max"},CYe=o(function(e){var r=EYe(e),n=SYe[r.linkage];return n!=null&&(r.linkage=n),r},"setOptions"),Ype=o(function(e,r,n,i,a){for(var s=0,l=1/0,u,h=a.attributes,f=o(function(_,I){return IS(a.distance,h.length,function(D){return h[D](_)},function(D){return h[D](I)},_,I)},"getDist"),d=0;d<e.length;d++){var p=e[d].key,m=n[p][i[p]];m<l&&(s=p,l=m)}if(a.mode==="threshold"&&l>=a.threshold||a.mode==="dendrogram"&&e.length===1)return!1;var g=r[s],y=r[i[s]],v;a.mode==="dendrogram"?v={left:g,right:y,key:g.key}:v={value:g.value.concat(y.value),key:g.key},e[g.index]=v,e.splice(y.index,1),r[g.key]=v;for(var x=0;x<e.length;x++){var b=e[x];g.key===b.key?u=1/0:a.linkage==="min"?(u=n[g.key][b.key],n[g.key][b.key]>n[y.key][b.key]&&(u=n[y.key][b.key])):a.linkage==="max"?(u=n[g.key][b.key],n[g.key][b.key]<n[y.key][b.key]&&(u=n[y.key][b.key])):a.linkage==="mean"?u=(n[g.key][b.key]*g.size+n[y.key][b.key]*y.size)/(g.size+y.size):a.mode==="dendrogram"?u=f(b.value,g.value):u=f(b.value[0],g.value[0]),n[g.key][b.key]=n[b.key][g.key]=u}for(var w=0;w<e.length;w++){var C=e[w].key;if(i[C]===g.key||i[C]===y.key){for(var T=C,E=0;E<e.length;E++){var A=e[E].key;n[C][A]<n[C][T]&&(T=A)}i[C]=T}e[w].index=w}return g.key=y.key=g.index=y.index=null,!0},"mergeClosest"),Z6=o(function t(e,r,n){e&&(e.value?r.push(e.value):(e.left&&t(e.left,r),e.right&&t(e.right,r)))},"getAllChildren"),AYe=o(function t(e,r){if(!e)return"";if(e.left&&e.right){var n=t(e.left,r),i=t(e.right,r),a=r.add({group:"nodes",data:{id:n+","+i}});return r.add({group:"edges",data:{source:n,target:a.id()}}),r.add({group:"edges",data:{source:i,target:a.id()}}),a.id()}else if(e.value)return e.value.id()},"buildDendrogram"),_Ye=o(function t(e,r,n){if(!e)return[];var i=[],a=[],s=[];return r===0?(e.left&&Z6(e.left,i),e.right&&Z6(e.right,a),s=i.concat(a),[n.collection(s)]):r===1?e.value?[n.collection(e.value)]:(e.left&&Z6(e.left,i),e.right&&Z6(e.right,a),[n.collection(i),n.collection(a)]):e.value?[n.collection(e.value)]:(e.left&&(i=t(e.left,r-1,n)),e.right&&(a=t(e.right,r-1,n)),i.concat(a))},"buildClustersFromTree"),Xpe=o(function(e){for(var r=this.cy(),n=this.nodes(),i=CYe(e),a=i.attributes,s=o(function(w,C){return IS(i.distance,a.length,function(T){return a[T](w)},function(T){return a[T](C)},w,C)},"getDist"),l=[],u=[],h=[],f=[],d=0;d<n.length;d++){var p={value:i.mode==="dendrogram"?n[d]:[n[d]],key:d,index:d};l[d]=p,f[d]=p,u[d]=[],h[d]=0}for(var m=0;m<l.length;m++)for(var g=0;g<=m;g++){var y=void 0;i.mode==="dendrogram"?y=m===g?1/0:s(l[m].value,l[g].value):y=m===g?1/0:s(l[m].value[0],l[g].value[0]),u[m][g]=y,u[g][m]=y,y<u[m][h[m]]&&(h[m]=g)}for(var v=Ype(l,f,u,h,i);v;)v=Ype(l,f,u,h,i);var x;return i.mode==="dendrogram"?(x=_Ye(l[0],i.dendrogramDepth,r),i.addDendrogram&&AYe(l[0],r)):(x=new Array(l.length),l.forEach(function(b,w){b.key=b.index=null,x[w]=r.collection(b.value)})),x},"hierarchicalClustering"),DYe={hierarchicalClustering:Xpe,hca:Xpe},LYe=la({distance:"euclidean",preference:"median",damping:.8,maxIterations:1e3,minIterations:100,attributes:[]}),RYe=o(function(e){var r=e.damping,n=e.preference;.5<=r&&r<1||ai("Damping must range on [0.5, 1). Got: ".concat(r));var i=["median","mean","min","max"];return i.some(function(a){return a===n})||Ct(n)||ai("Preference must be one of [".concat(i.map(function(a){return"'".concat(a,"'")}).join(", "),"] or a number. Got: ").concat(n)),LYe(e)},"setOptions"),NYe=o(function(e,r,n,i){var a=o(function(l,u){return i[u](l)},"attr");return-IS(e,i.length,function(s){return a(r,s)},function(s){return a(n,s)},r,n)},"getSimilarity"),MYe=o(function(e,r){var n=null;return r==="median"?n=Rqe(e):r==="mean"?n=Lqe(e):r==="min"?n=_qe(e):r==="max"?n=Dqe(e):n=r,n},"getPreference"),IYe=o(function(e,r,n){for(var i=[],a=0;a<e;a++)r[a*e+a]+n[a*e+a]>0&&i.push(a);return i},"findExemplars"),jpe=o(function(e,r,n){for(var i=[],a=0;a<e;a++){for(var s=-1,l=-1/0,u=0;u<n.length;u++){var h=n[u];r[a*e+h]>l&&(s=h,l=r[a*e+h])}s>0&&i.push(s)}for(var f=0;f<n.length;f++)i[n[f]]=n[f];return i},"assignClusters"),OYe=o(function(e,r,n){for(var i=jpe(e,r,n),a=0;a<n.length;a++){for(var s=[],l=0;l<i.length;l++)i[l]===n[a]&&s.push(l);for(var u=-1,h=-1/0,f=0;f<s.length;f++){for(var d=0,p=0;p<s.length;p++)d+=r[s[p]*e+s[f]];d>h&&(u=f,h=d)}n[a]=s[u]}return i=jpe(e,r,n),i},"assign"),Kpe=o(function(e){for(var r=this.cy(),n=this.nodes(),i=RYe(e),a={},s=0;s<n.length;s++)a[n[s].id()]=s;var l,u,h,f,d,p;l=n.length,u=l*l,h=new Array(u);for(var m=0;m<u;m++)h[m]=-1/0;for(var g=0;g<l;g++)for(var y=0;y<l;y++)g!==y&&(h[g*l+y]=NYe(i.distance,n[g],n[y],i.attributes));f=MYe(h,i.preference);for(var v=0;v<l;v++)h[v*l+v]=f;d=new Array(u);for(var x=0;x<u;x++)d[x]=0;p=new Array(u);for(var b=0;b<u;b++)p[b]=0;for(var w=new Array(l),C=new Array(l),T=new Array(l),E=0;E<l;E++)w[E]=0,C[E]=0,T[E]=0;for(var A=new Array(l*i.minIterations),S=0;S<A.length;S++)A[S]=0;var _;for(_=0;_<i.maxIterations;_++){for(var I=0;I<l;I++){for(var D=-1/0,k=-1/0,L=-1,R=0,O=0;O<l;O++)w[O]=d[I*l+O],R=p[I*l+O]+h[I*l+O],R>=D?(k=D,D=R,L=O):R>k&&(k=R);for(var M=0;M<l;M++)d[I*l+M]=(1-i.damping)*(h[I*l+M]-D)+i.damping*w[M];d[I*l+L]=(1-i.damping)*(h[I*l+L]-k)+i.damping*w[L]}for(var B=0;B<l;B++){for(var F=0,P=0;P<l;P++)w[P]=p[P*l+B],C[P]=Math.max(0,d[P*l+B]),F+=C[P];F-=C[B],C[B]=d[B*l+B],F+=C[B];for(var z=0;z<l;z++)p[z*l+B]=(1-i.damping)*Math.min(0,F-C[z])+i.damping*w[z];p[B*l+B]=(1-i.damping)*(F-C[B])+i.damping*w[B]}for(var $=0,H=0;H<l;H++){var Q=p[H*l+H]+d[H*l+H]>0?1:0;A[_%i.minIterations*l+H]=Q,$+=Q}if($>0&&(_>=i.minIterations-1||_==i.maxIterations-1)){for(var j=0,ie=0;ie<l;ie++){T[ie]=0;for(var ne=0;ne<i.minIterations;ne++)T[ie]+=A[ne*l+ie];(T[ie]===0||T[ie]===i.minIterations)&&j++}if(j===l)break}}for(var le=IYe(l,d,p),he=OYe(l,h,le),K={},X=0;X<le.length;X++)K[le[X]]=[];for(var te=0;te<n.length;te++){var J=a[n[te].id()],se=he[J];se!=null&&K[se].push(n[te])}for(var ue=new Array(le.length),Z=0;Z<le.length;Z++)ue[Z]=r.collection(K[le[Z]]);return ue},"affinityPropagation"),PYe={affinityPropagation:Kpe,ap:Kpe},BYe=la({root:void 0,directed:!1}),FYe={hierholzer:o(function(e){if(!Ur(e)){var r=arguments;e={root:r[0],directed:r[1]}}var n=BYe(e),i=n.root,a=n.directed,s=this,l=!1,u,h,f;i&&(f=Zt(i)?this.filter(i)[0].id():i[0].id());var d={},p={};a?s.forEach(function(b){var w=b.id();if(b.isNode()){var C=b.indegree(!0),T=b.outdegree(!0),E=C-T,A=T-C;E==1?u?l=!0:u=w:A==1?h?l=!0:h=w:(A>1||E>1)&&(l=!0),d[w]=[],b.outgoers().forEach(function(S){S.isEdge()&&d[w].push(S.id())})}else p[w]=[void 0,b.target().id()]}):s.forEach(function(b){var w=b.id();if(b.isNode()){var C=b.degree(!0);C%2&&(u?h?l=!0:h=w:u=w),d[w]=[],b.connectedEdges().forEach(function(T){return d[w].push(T.id())})}else p[w]=[b.source().id(),b.target().id()]});var m={found:!1,trail:void 0};if(l)return m;if(h&&u)if(a){if(f&&h!=f)return m;f=h}else{if(f&&h!=f&&u!=f)return m;f||(f=h)}else f||(f=s[0].id());var g=o(function(w){for(var C=w,T=[w],E,A,S;d[C].length;)E=d[C].shift(),A=p[E][0],S=p[E][1],C!=S?(d[S]=d[S].filter(function(_){return _!=E}),C=S):!a&&C!=A&&(d[A]=d[A].filter(function(_){return _!=E}),C=A),T.unshift(E),T.unshift(C);return T},"walk"),y=[],v=[];for(v=g(f);v.length!=1;)d[v[0]].length==0?(y.unshift(s.getElementById(v.shift())),y.unshift(s.getElementById(v.shift()))):v=g(v.shift()).concat(v);y.unshift(s.getElementById(v.shift()));for(var x in d)if(d[x].length)return m;return m.found=!0,m.trail=this.spawn(y,!0),m},"hierholzer")},J6=o(function(){var e=this,r={},n=0,i=0,a=[],s=[],l={},u=o(function(p,m){for(var g=s.length-1,y=[],v=e.spawn();s[g].x!=p||s[g].y!=m;)y.push(s.pop().edge),g--;y.push(s.pop().edge),y.forEach(function(x){var b=x.connectedNodes().intersection(e);v.merge(x),b.forEach(function(w){var C=w.id(),T=w.connectedEdges().intersection(e);v.merge(w),r[C].cutVertex?v.merge(T.filter(function(E){return E.isLoop()})):v.merge(T)})}),a.push(v)},"buildComponent"),h=o(function d(p,m,g){p===g&&(i+=1),r[m]={id:n,low:n++,cutVertex:!1};var y=e.getElementById(m).connectedEdges().intersection(e);if(y.size()===0)a.push(e.spawn(e.getElementById(m)));else{var v,x,b,w;y.forEach(function(C){v=C.source().id(),x=C.target().id(),b=v===m?x:v,b!==g&&(w=C.id(),l[w]||(l[w]=!0,s.push({x:m,y:b,edge:C})),b in r?r[m].low=Math.min(r[m].low,r[b].id):(d(p,b,m),r[m].low=Math.min(r[m].low,r[b].low),r[m].id<=r[b].low&&(r[m].cutVertex=!0,u(m,b))))})}},"biconnectedSearch");e.forEach(function(d){if(d.isNode()){var p=d.id();p in r||(i=0,h(p,p),r[p].cutVertex=i>1)}});var f=Object.keys(r).filter(function(d){return r[d].cutVertex}).map(function(d){return e.getElementById(d)});return{cut:e.spawn(f),components:a}},"hopcroftTarjanBiconnected"),$Ye={hopcroftTarjanBiconnected:J6,htbc:J6,htb:J6,hopcroftTarjanBiconnectedComponents:J6},eS=o(function(){var e=this,r={},n=0,i=[],a=[],s=e.spawn(e),l=o(function u(h){a.push(h),r[h]={index:n,low:n++,explored:!1};var f=e.getElementById(h).connectedEdges().intersection(e);if(f.forEach(function(y){var v=y.target().id();v!==h&&(v in r||u(v),r[v].explored||(r[h].low=Math.min(r[h].low,r[v].low)))}),r[h].index===r[h].low){for(var d=e.spawn();;){var p=a.pop();if(d.merge(e.getElementById(p)),r[p].low=r[h].index,r[p].explored=!0,p===h)break}var m=d.edgesWith(d),g=d.merge(m);i.push(g),s=s.difference(g)}},"stronglyConnectedSearch");return e.forEach(function(u){if(u.isNode()){var h=u.id();h in r||l(h)}}),{cut:s,components:i}},"tarjanStronglyConnected"),zYe={tarjanStronglyConnected:eS,tsc:eS,tscc:eS,tarjanStronglyConnectedComponents:eS},Sme={};[qb,gqe,yqe,xqe,wqe,kqe,Cqe,Qqe,q1,Y1,FP,uYe,kYe,DYe,PYe,FYe,$Ye,zYe].forEach(function(t){rr(Sme,t)});Cme=0,Ame=1,_me=2,Ju=o(function t(e){if(!(this instanceof t))return new t(e);this.id="Thenable/1.0.7",this.state=Cme,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},typeof e=="function"&&e.call(this,this.fulfill.bind(this),this.reject.bind(this))},"api");Ju.prototype={fulfill:o(function(e){return Qpe(this,Ame,"fulfillValue",e)},"fulfill"),reject:o(function(e){return Qpe(this,_me,"rejectReason",e)},"reject"),then:o(function(e,r){var n=this,i=new Ju;return n.onFulfilled.push(Jpe(e,i,"fulfill")),n.onRejected.push(Jpe(r,i,"reject")),Dme(n),i.proxy},"then")};Qpe=o(function(e,r,n,i){return e.state===Cme&&(e.state=r,e[n]=i,Dme(e)),e},"deliver"),Dme=o(function(e){e.state===Ame?Zpe(e,"onFulfilled",e.fulfillValue):e.state===_me&&Zpe(e,"onRejected",e.rejectReason)},"execute"),Zpe=o(function(e,r,n){if(e[r].length!==0){var i=e[r];e[r]=[];var a=o(function(){for(var l=0;l<i.length;l++)i[l](n)},"func");typeof setImmediate=="function"?setImmediate(a):setTimeout(a,0)}},"execute_handlers"),Jpe=o(function(e,r,n){return function(i){if(typeof e!="function")r[n].call(r,i);else{var a;try{a=e(i)}catch(s){r.reject(s);return}GYe(r,a)}}},"resolver"),GYe=o(function t(e,r){if(e===r||e.proxy===r){e.reject(new TypeError("cannot resolve promise with itself"));return}var n;if(Wi(r)==="object"&&r!==null||typeof r=="function")try{n=r.then}catch(a){e.reject(a);return}if(typeof n=="function"){var i=!1;try{n.call(r,function(a){i||(i=!0,a===r?e.reject(new TypeError("circular thenable chain")):t(e,a))},function(a){i||(i=!0,e.reject(a))})}catch(a){i||e.reject(a)}return}e.fulfill(r)},"resolve");Ju.all=function(t){return new Ju(function(e,r){for(var n=new Array(t.length),i=0,a=o(function(u,h){n[u]=h,i++,i===t.length&&e(n)},"fulfill"),s=0;s<t.length;s++)(function(l){var u=t[l],h=u!=null&&u.then!=null;if(h)u.then(function(d){a(l,d)},function(d){r(d)});else{var f=u;a(l,f)}})(s)})};Ju.resolve=function(t){return new Ju(function(e,r){e(t)})};Ju.reject=function(t){return new Ju(function(e,r){r(t)})};ey=typeof Promise<"u"?Promise:Ju,$P=o(function(e,r,n){var i=JP(e),a=!i,s=this._private=rr({duration:1e3},r,n);if(s.target=e,s.style=s.style||s.css,s.started=!1,s.playing=!1,s.hooked=!1,s.applying=!1,s.progress=0,s.completes=[],s.frames=[],s.complete&&si(s.complete)&&s.completes.push(s.complete),a){var l=e.position();s.startPosition=s.startPosition||{x:l.x,y:l.y},s.startStyle=s.startStyle||e.cy().style().getAnimationStartStyle(e,s.style)}if(i){var u=e.pan();s.startPan={x:u.x,y:u.y},s.startZoom=e.zoom()}this.length=1,this[0]=this},"Animation"),Up=$P.prototype;rr(Up,{instanceString:o(function(){return"animation"},"instanceString"),hook:o(function(){var e=this._private;if(!e.hooked){var r,n=e.target._private.animation;e.queue?r=n.queue:r=n.current,r.push(this),go(e.target)&&e.target.cy().addToAnimationPool(e.target),e.hooked=!0}return this},"hook"),play:o(function(){var e=this._private;return e.progress===1&&(e.progress=0),e.playing=!0,e.started=!1,e.stopped=!1,this.hook(),this},"play"),playing:o(function(){return this._private.playing},"playing"),apply:o(function(){var e=this._private;return e.applying=!0,e.started=!1,e.stopped=!1,this.hook(),this},"apply"),applying:o(function(){return this._private.applying},"applying"),pause:o(function(){var e=this._private;return e.playing=!1,e.started=!1,this},"pause"),stop:o(function(){var e=this._private;return e.playing=!1,e.started=!1,e.stopped=!0,this},"stop"),rewind:o(function(){return this.progress(0)},"rewind"),fastforward:o(function(){return this.progress(1)},"fastforward"),time:o(function(e){var r=this._private;return e===void 0?r.progress*r.duration:this.progress(e/r.duration)},"time"),progress:o(function(e){var r=this._private,n=r.playing;return e===void 0?r.progress:(n&&this.pause(),r.progress=e,r.started=!1,n&&this.play(),this)},"progress"),completed:o(function(){return this._private.progress===1},"completed"),reverse:o(function(){var e=this._private,r=e.playing;r&&this.pause(),e.progress=1-e.progress,e.started=!1;var n=o(function(h,f){var d=e[h];d!=null&&(e[h]=e[f],e[f]=d)},"swap");if(n("zoom","startZoom"),n("pan","startPan"),n("position","startPosition"),e.style)for(var i=0;i<e.style.length;i++){var a=e.style[i],s=a.name,l=e.startStyle[s];e.startStyle[s]=a,e.style[i]=l}return r&&this.play(),this},"reverse"),promise:o(function(e){var r=this._private,n;switch(e){case"frame":n=r.frames;break;default:case"complete":case"completed":n=r.completes}return new ey(function(i,a){n.push(function(){i()})})},"promise")});Up.complete=Up.completed;Up.run=Up.play;Up.running=Up.playing;VYe={animated:o(function(){return o(function(){var r=this,n=r.length!==void 0,i=n?r:[r],a=this._private.cy||this;if(!a.styleEnabled())return!1;var s=i[0];if(s)return s._private.animation.current.length>0},"animatedImpl")},"animated"),clearQueue:o(function(){return o(function(){var r=this,n=r.length!==void 0,i=n?r:[r],a=this._private.cy||this;if(!a.styleEnabled())return this;for(var s=0;s<i.length;s++){var l=i[s];l._private.animation.queue=[]}return this},"clearQueueImpl")},"clearQueue"),delay:o(function(){return o(function(r,n){var i=this._private.cy||this;return i.styleEnabled()?this.animate({delay:r,duration:r,complete:n}):this},"delayImpl")},"delay"),delayAnimation:o(function(){return o(function(r,n){var i=this._private.cy||this;return i.styleEnabled()?this.animation({delay:r,duration:r,complete:n}):this},"delayAnimationImpl")},"delayAnimation"),animation:o(function(){return o(function(r,n){var i=this,a=i.length!==void 0,s=a?i:[i],l=this._private.cy||this,u=!a,h=!u;if(!l.styleEnabled())return this;var f=l.style();r=rr({},r,n);var d=Object.keys(r).length===0;if(d)return new $P(s[0],r);switch(r.duration===void 0&&(r.duration=400),r.duration){case"slow":r.duration=600;break;case"fast":r.duration=200;break}if(h&&(r.style=f.getPropsList(r.style||r.css),r.css=void 0),h&&r.renderedPosition!=null){var p=r.renderedPosition,m=l.pan(),g=l.zoom();r.position=pme(p,g,m)}if(u&&r.panBy!=null){var y=r.panBy,v=l.pan();r.pan={x:v.x+y.x,y:v.y+y.y}}var x=r.center||r.centre;if(u&&x!=null){var b=l.getCenterPan(x.eles,r.zoom);b!=null&&(r.pan=b)}if(u&&r.fit!=null){var w=r.fit,C=l.getFitViewport(w.eles||w.boundingBox,w.padding);C!=null&&(r.pan=C.pan,r.zoom=C.zoom)}if(u&&Ur(r.zoom)){var T=l.getZoomedViewport(r.zoom);T!=null?(T.zoomed&&(r.zoom=T.zoom),T.panned&&(r.pan=T.pan)):r.zoom=null}return new $P(s[0],r)},"animationImpl")},"animation"),animate:o(function(){return o(function(r,n){var i=this,a=i.length!==void 0,s=a?i:[i],l=this._private.cy||this;if(!l.styleEnabled())return this;n&&(r=rr({},r,n));for(var u=0;u<s.length;u++){var h=s[u],f=h.animated()&&(r.queue===void 0||r.queue),d=h.animation(r,f?{queue:!0}:void 0);d.play()}return this},"animateImpl")},"animate"),stop:o(function(){return o(function(r,n){var i=this,a=i.length!==void 0,s=a?i:[i],l=this._private.cy||this;if(!l.styleEnabled())return this;for(var u=0;u<s.length;u++){for(var h=s[u],f=h._private,d=f.animation.current,p=0;p<d.length;p++){var m=d[p],g=m._private;n&&(g.duration=0)}r&&(f.animation.queue=[]),n||(f.animation.current=[])}return l.notify("draw"),this},"stopImpl")},"stop")},UYe=Array.isArray,OS=UYe,HYe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,WYe=/^\w*$/;o(qYe,"isKey");YYe=qYe,XYe="[object AsyncFunction]",jYe="[object Function]",KYe="[object GeneratorFunction]",QYe="[object Proxy]";o(ZYe,"isFunction");JYe=ZYe,eXe=RS["__core-js_shared__"],EP=eXe,e0e=function(){var t=/[^.]+$/.exec(EP&&EP.keys&&EP.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();o(tXe,"isMasked");rXe=tXe,nXe=Function.prototype,iXe=nXe.toString;o(aXe,"toSource");sXe=aXe,oXe=/[\\^$.*+?()[\]{}|]/g,lXe=/^\[object .+?Constructor\]$/,cXe=Function.prototype,uXe=Object.prototype,hXe=cXe.toString,fXe=uXe.hasOwnProperty,dXe=RegExp("^"+hXe.call(fXe).replace(oXe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");o(pXe,"baseIsNative");mXe=pXe;o(gXe,"getValue$1");yXe=gXe;o(vXe,"getNative");lB=vXe,xXe=lB(Object,"create"),jb=xXe;o(bXe,"hashClear");wXe=bXe;o(TXe,"hashDelete");kXe=TXe,EXe="__lodash_hash_undefined__",SXe=Object.prototype,CXe=SXe.hasOwnProperty;o(AXe,"hashGet");_Xe=AXe,DXe=Object.prototype,LXe=DXe.hasOwnProperty;o(RXe,"hashHas");NXe=RXe,MXe="__lodash_hash_undefined__";o(IXe,"hashSet");OXe=IXe;o(ty,"Hash");ty.prototype.clear=wXe;ty.prototype.delete=kXe;ty.prototype.get=_Xe;ty.prototype.has=NXe;ty.prototype.set=OXe;t0e=ty;o(PXe,"listCacheClear");BXe=PXe;o(FXe,"eq");Lme=FXe;o($Xe,"assocIndexOf");PS=$Xe,zXe=Array.prototype,GXe=zXe.splice;o(VXe,"listCacheDelete");UXe=VXe;o(HXe,"listCacheGet");WXe=HXe;o(qXe,"listCacheHas");YXe=qXe;o(XXe,"listCacheSet");jXe=XXe;o(ry,"ListCache");ry.prototype.clear=BXe;ry.prototype.delete=UXe;ry.prototype.get=WXe;ry.prototype.has=YXe;ry.prototype.set=jXe;KXe=ry,QXe=lB(RS,"Map"),ZXe=QXe;o(JXe,"mapCacheClear");eje=JXe;o(tje,"isKeyable");rje=tje;o(nje,"getMapData");BS=nje;o(ije,"mapCacheDelete");aje=ije;o(sje,"mapCacheGet");oje=sje;o(lje,"mapCacheHas");cje=lje;o(uje,"mapCacheSet");hje=uje;o(ny,"MapCache");ny.prototype.clear=eje;ny.prototype.delete=aje;ny.prototype.get=oje;ny.prototype.has=cje;ny.prototype.set=hje;Rme=ny,fje="Expected a function";o(cB,"memoize");cB.Cache=Rme;dje=cB,pje=500;o(mje,"memoizeCapped");gje=mje,yje=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,vje=/\\(\\)?/g,xje=gje(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(yje,function(r,n,i,a){e.push(i?a.replace(vje,"$1"):n||r)}),e}),Nme=xje;o(bje,"arrayMap");Mme=bje,wje=1/0,r0e=j1?j1.prototype:void 0,n0e=r0e?r0e.toString:void 0;o(Ime,"baseToString");Tje=Ime;o(kje,"toString$1");Ome=kje;o(Eje,"castPath");Pme=Eje,Sje=1/0;o(Cje,"toKey");uB=Cje;o(Aje,"baseGet");_je=Aje;o(Dje,"get");Lje=Dje,Rje=function(){try{var t=lB(Object,"defineProperty");return t({},"",{}),t}catch{}}(),i0e=Rje;o(Nje,"baseAssignValue");Mje=Nje,Ije=Object.prototype,Oje=Ije.hasOwnProperty;o(Pje,"assignValue");Bje=Pje,Fje=9007199254740991,$je=/^(?:0|[1-9]\d*)$/;o(zje,"isIndex");Gje=zje;o(Vje,"baseSet");Uje=Vje;o(Hje,"set");Wje=Hje;o(qje,"copyArray");Yje=qje;o(Xje,"toPath");jje=Xje,Kje={data:o(function(e){var r={field:"data",bindingEvent:"data",allowBinding:!1,allowSetting:!1,allowGetting:!1,settingEvent:"data",settingTriggersEvent:!1,triggerFnName:"trigger",immutableKeys:{},updateStyle:!1,beforeGet:o(function(i){},"beforeGet"),beforeSet:o(function(i,a){},"beforeSet"),onSet:o(function(i){},"onSet"),canSet:o(function(i){return!0},"canSet")};return e=rr({},r,e),o(function(i,a){var s=e,l=this,u=l.length!==void 0,h=u?l:[l],f=u?l[0]:l;if(Zt(i)){var d=i.indexOf(".")!==-1,p=d&&jje(i);if(s.allowGetting&&a===void 0){var m;return f&&(s.beforeGet(f),p&&f._private[s.field][i]===void 0?m=Lje(f._private[s.field],p):m=f._private[s.field][i]),m}else if(s.allowSetting&&a!==void 0){var g=!s.immutableKeys[i];if(g){var y=X0e({},i,a);s.beforeSet(l,y);for(var v=0,x=h.length;v<x;v++){var b=h[v];s.canSet(b)&&(p&&f._private[s.field][i]===void 0?Wje(b._private[s.field],p,a):b._private[s.field][i]=a)}s.updateStyle&&l.updateStyle(),s.onSet(l),s.settingTriggersEvent&&l[s.triggerFnName](s.settingEvent)}}}else if(s.allowSetting&&Ur(i)){var w=i,C,T,E=Object.keys(w);s.beforeSet(l,w);for(var A=0;A<E.length;A++){C=E[A],T=w[C];var S=!s.immutableKeys[C];if(S)for(var _=0;_<h.length;_++){var I=h[_];s.canSet(I)&&(I._private[s.field][C]=T)}}s.updateStyle&&l.updateStyle(),s.onSet(l),s.settingTriggersEvent&&l[s.triggerFnName](s.settingEvent)}else if(s.allowBinding&&si(i)){var D=i;l.on(s.bindingEvent,D)}else if(s.allowGetting&&i===void 0){var k;return f&&(s.beforeGet(f),k=f._private[s.field]),k}return l},"dataImpl")},"data"),removeData:o(function(e){var r={field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!1,immutableKeys:{}};return e=rr({},r,e),o(function(i){var a=e,s=this,l=s.length!==void 0,u=l?s:[s];if(Zt(i)){for(var h=i.split(/\s+/),f=h.length,d=0;d<f;d++){var p=h[d];if(!Af(p)){var m=!a.immutableKeys[p];if(m)for(var g=0,y=u.length;g<y;g++)u[g]._private[a.field][p]=void 0}}a.triggerEvent&&s[a.triggerFnName](a.event)}else if(i===void 0){for(var v=0,x=u.length;v<x;v++)for(var b=u[v]._private[a.field],w=Object.keys(b),C=0;C<w.length;C++){var T=w[C],E=!a.immutableKeys[T];E&&(b[T]=void 0)}a.triggerEvent&&s[a.triggerFnName](a.event)}return s},"removeDataImpl")},"removeData")},Qje={eventAliasesOn:o(function(e){var r=e;r.addListener=r.listen=r.bind=r.on,r.unlisten=r.unbind=r.off=r.removeListener,r.trigger=r.emit,r.pon=r.promiseOn=function(n,i){var a=this,s=Array.prototype.slice.call(arguments,0);return new ey(function(l,u){var h=o(function(m){a.off.apply(a,d),l(m)},"callback"),f=s.concat([h]),d=f.concat([]);a.on.apply(a,f)})}},"eventAliasesOn")},cn={};[VYe,Kje,Qje].forEach(function(t){rr(cn,t)});Zje={animate:cn.animate(),animation:cn.animation(),animated:cn.animated(),clearQueue:cn.clearQueue(),delay:cn.delay(),delayAnimation:cn.delayAnimation(),stop:cn.stop()},hS={classes:o(function(e){var r=this;if(e===void 0){var n=[];return r[0]._private.classes.forEach(function(g){return n.push(g)}),n}else En(e)||(e=(e||"").match(/\S+/g)||[]);for(var i=[],a=new J1(e),s=0;s<r.length;s++){for(var l=r[s],u=l._private,h=u.classes,f=!1,d=0;d<e.length;d++){var p=e[d],m=h.has(p);if(!m){f=!0;break}}f||(f=h.size!==e.length),f&&(u.classes=a,i.push(l))}return i.length>0&&this.spawn(i).updateStyle().emit("class"),r},"classes"),addClass:o(function(e){return this.toggleClass(e,!0)},"addClass"),hasClass:o(function(e){var r=this[0];return r!=null&&r._private.classes.has(e)},"hasClass"),toggleClass:o(function(e,r){En(e)||(e=e.match(/\S+/g)||[]);for(var n=this,i=r===void 0,a=[],s=0,l=n.length;s<l;s++)for(var u=n[s],h=u._private.classes,f=!1,d=0;d<e.length;d++){var p=e[d],m=h.has(p),g=!1;r||i&&!m?(h.add(p),g=!0):(!r||i&&m)&&(h.delete(p),g=!0),!f&&g&&(a.push(u),f=!0)}return a.length>0&&this.spawn(a).updateStyle().emit("class"),n},"toggleClass"),removeClass:o(function(e){return this.toggleClass(e,!1)},"removeClass"),flashClass:o(function(e,r){var n=this;if(r==null)r=250;else if(r===0)return n;return n.addClass(e),setTimeout(function(){n.removeClass(e)},r),n},"flashClass")};hS.className=hS.classNames=hS.classes;Vr={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:`"(?:\\\\"|[^"])*"|'(?:\\\\'|[^'])*'`,number:Hi,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};Vr.variable="(?:[\\w-.]|(?:\\\\"+Vr.metaChar+"))+";Vr.className="(?:[\\w-]|(?:\\\\"+Vr.metaChar+"))+";Vr.value=Vr.string+"|"+Vr.number;Vr.id=Vr.variable;(function(){var t,e,r;for(t=Vr.comparatorOp.split("|"),r=0;r<t.length;r++)e=t[r],Vr.comparatorOp+="|@"+e;for(t=Vr.comparatorOp.split("|"),r=0;r<t.length;r++)e=t[r],!(e.indexOf("!")>=0)&&e!=="="&&(Vr.comparatorOp+="|\\!"+e)})();mn=o(function(){return{checks:[]}},"newQuery"),$t={GROUP:0,COLLECTION:1,FILTER:2,DATA_COMPARE:3,DATA_EXIST:4,DATA_BOOL:5,META_COMPARE:6,STATE:7,ID:8,CLASS:9,UNDIRECTED_EDGE:10,DIRECTED_EDGE:11,NODE_SOURCE:12,NODE_TARGET:13,NODE_NEIGHBOR:14,CHILD:15,DESCENDANT:16,PARENT:17,ANCESTOR:18,COMPOUND_SPLIT:19,TRUE:20},zP=[{selector:":selected",matches:o(function(e){return e.selected()},"matches")},{selector:":unselected",matches:o(function(e){return!e.selected()},"matches")},{selector:":selectable",matches:o(function(e){return e.selectable()},"matches")},{selector:":unselectable",matches:o(function(e){return!e.selectable()},"matches")},{selector:":locked",matches:o(function(e){return e.locked()},"matches")},{selector:":unlocked",matches:o(function(e){return!e.locked()},"matches")},{selector:":visible",matches:o(function(e){return e.visible()},"matches")},{selector:":hidden",matches:o(function(e){return!e.visible()},"matches")},{selector:":transparent",matches:o(function(e){return e.transparent()},"matches")},{selector:":grabbed",matches:o(function(e){return e.grabbed()},"matches")},{selector:":free",matches:o(function(e){return!e.grabbed()},"matches")},{selector:":removed",matches:o(function(e){return e.removed()},"matches")},{selector:":inside",matches:o(function(e){return!e.removed()},"matches")},{selector:":grabbable",matches:o(function(e){return e.grabbable()},"matches")},{selector:":ungrabbable",matches:o(function(e){return!e.grabbable()},"matches")},{selector:":animated",matches:o(function(e){return e.animated()},"matches")},{selector:":unanimated",matches:o(function(e){return!e.animated()},"matches")},{selector:":parent",matches:o(function(e){return e.isParent()},"matches")},{selector:":childless",matches:o(function(e){return e.isChildless()},"matches")},{selector:":child",matches:o(function(e){return e.isChild()},"matches")},{selector:":orphan",matches:o(function(e){return e.isOrphan()},"matches")},{selector:":nonorphan",matches:o(function(e){return e.isChild()},"matches")},{selector:":compound",matches:o(function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()},"matches")},{selector:":loop",matches:o(function(e){return e.isLoop()},"matches")},{selector:":simple",matches:o(function(e){return e.isSimple()},"matches")},{selector:":active",matches:o(function(e){return e.active()},"matches")},{selector:":inactive",matches:o(function(e){return!e.active()},"matches")},{selector:":backgrounding",matches:o(function(e){return e.backgrounding()},"matches")},{selector:":nonbackgrounding",matches:o(function(e){return!e.backgrounding()},"matches")}].sort(function(t,e){return hWe(t.selector,e.selector)}),Jje=function(){for(var t={},e,r=0;r<zP.length;r++)e=zP[r],t[e.selector]=e.matches;return t}(),eKe=o(function(e,r){return Jje[e](r)},"stateSelectorMatches"),tKe="("+zP.map(function(t){return t.selector}).join("|")+")",B1=o(function(e){return e.replace(new RegExp("\\\\("+Vr.metaChar+")","g"),function(r,n){return n})},"cleanMetaChars"),Tf=o(function(e,r,n){e[e.length-1]=n},"replaceLastQuery"),GP=[{name:"group",query:!0,regex:"("+Vr.group+")",populate:o(function(e,r,n){var i=_i(n,1),a=i[0];r.checks.push({type:$t.GROUP,value:a==="*"?a:a+"s"})},"populate")},{name:"state",query:!0,regex:tKe,populate:o(function(e,r,n){var i=_i(n,1),a=i[0];r.checks.push({type:$t.STATE,value:a})},"populate")},{name:"id",query:!0,regex:"\\#("+Vr.id+")",populate:o(function(e,r,n){var i=_i(n,1),a=i[0];r.checks.push({type:$t.ID,value:B1(a)})},"populate")},{name:"className",query:!0,regex:"\\.("+Vr.className+")",populate:o(function(e,r,n){var i=_i(n,1),a=i[0];r.checks.push({type:$t.CLASS,value:B1(a)})},"populate")},{name:"dataExists",query:!0,regex:"\\[\\s*("+Vr.variable+")\\s*\\]",populate:o(function(e,r,n){var i=_i(n,1),a=i[0];r.checks.push({type:$t.DATA_EXIST,field:B1(a)})},"populate")},{name:"dataCompare",query:!0,regex:"\\[\\s*("+Vr.variable+")\\s*("+Vr.comparatorOp+")\\s*("+Vr.value+")\\s*\\]",populate:o(function(e,r,n){var i=_i(n,3),a=i[0],s=i[1],l=i[2],u=new RegExp("^"+Vr.string+"$").exec(l)!=null;u?l=l.substring(1,l.length-1):l=parseFloat(l),r.checks.push({type:$t.DATA_COMPARE,field:B1(a),operator:s,value:l})},"populate")},{name:"dataBool",query:!0,regex:"\\[\\s*("+Vr.boolOp+")\\s*("+Vr.variable+")\\s*\\]",populate:o(function(e,r,n){var i=_i(n,2),a=i[0],s=i[1];r.checks.push({type:$t.DATA_BOOL,field:B1(s),operator:a})},"populate")},{name:"metaCompare",query:!0,regex:"\\[\\[\\s*("+Vr.meta+")\\s*("+Vr.comparatorOp+")\\s*("+Vr.number+")\\s*\\]\\]",populate:o(function(e,r,n){var i=_i(n,3),a=i[0],s=i[1],l=i[2];r.checks.push({type:$t.META_COMPARE,field:B1(a),operator:s,value:parseFloat(l)})},"populate")},{name:"nextQuery",separator:!0,regex:Vr.separator,populate:o(function(e,r){var n=e.currentSubject,i=e.edgeCount,a=e.compoundCount,s=e[e.length-1];n!=null&&(s.subject=n,e.currentSubject=null),s.edgeCount=i,s.compoundCount=a,e.edgeCount=0,e.compoundCount=0;var l=e[e.length++]=mn();return l},"populate")},{name:"directedEdge",separator:!0,regex:Vr.directedEdge,populate:o(function(e,r){if(e.currentSubject==null){var n=mn(),i=r,a=mn();return n.checks.push({type:$t.DIRECTED_EDGE,source:i,target:a}),Tf(e,r,n),e.edgeCount++,a}else{var s=mn(),l=r,u=mn();return s.checks.push({type:$t.NODE_SOURCE,source:l,target:u}),Tf(e,r,s),e.edgeCount++,u}},"populate")},{name:"undirectedEdge",separator:!0,regex:Vr.undirectedEdge,populate:o(function(e,r){if(e.currentSubject==null){var n=mn(),i=r,a=mn();return n.checks.push({type:$t.UNDIRECTED_EDGE,nodes:[i,a]}),Tf(e,r,n),e.edgeCount++,a}else{var s=mn(),l=r,u=mn();return s.checks.push({type:$t.NODE_NEIGHBOR,node:l,neighbor:u}),Tf(e,r,s),u}},"populate")},{name:"child",separator:!0,regex:Vr.child,populate:o(function(e,r){if(e.currentSubject==null){var n=mn(),i=mn(),a=e[e.length-1];return n.checks.push({type:$t.CHILD,parent:a,child:i}),Tf(e,r,n),e.compoundCount++,i}else if(e.currentSubject===r){var s=mn(),l=e[e.length-1],u=mn(),h=mn(),f=mn(),d=mn();return s.checks.push({type:$t.COMPOUND_SPLIT,left:l,right:u,subject:h}),h.checks=r.checks,r.checks=[{type:$t.TRUE}],d.checks.push({type:$t.TRUE}),u.checks.push({type:$t.PARENT,parent:d,child:f}),Tf(e,l,s),e.currentSubject=h,e.compoundCount++,f}else{var p=mn(),m=mn(),g=[{type:$t.PARENT,parent:p,child:m}];return p.checks=r.checks,r.checks=g,e.compoundCount++,m}},"populate")},{name:"descendant",separator:!0,regex:Vr.descendant,populate:o(function(e,r){if(e.currentSubject==null){var n=mn(),i=mn(),a=e[e.length-1];return n.checks.push({type:$t.DESCENDANT,ancestor:a,descendant:i}),Tf(e,r,n),e.compoundCount++,i}else if(e.currentSubject===r){var s=mn(),l=e[e.length-1],u=mn(),h=mn(),f=mn(),d=mn();return s.checks.push({type:$t.COMPOUND_SPLIT,left:l,right:u,subject:h}),h.checks=r.checks,r.checks=[{type:$t.TRUE}],d.checks.push({type:$t.TRUE}),u.checks.push({type:$t.ANCESTOR,ancestor:d,descendant:f}),Tf(e,l,s),e.currentSubject=h,e.compoundCount++,f}else{var p=mn(),m=mn(),g=[{type:$t.ANCESTOR,ancestor:p,descendant:m}];return p.checks=r.checks,r.checks=g,e.compoundCount++,m}},"populate")},{name:"subject",modifier:!0,regex:Vr.subject,populate:o(function(e,r){if(e.currentSubject!=null&&e.currentSubject!==r)return un("Redefinition of subject in selector `"+e.toString()+"`"),!1;e.currentSubject=r;var n=e[e.length-1],i=n.checks[0],a=i==null?null:i.type;a===$t.DIRECTED_EDGE?i.type=$t.NODE_TARGET:a===$t.UNDIRECTED_EDGE&&(i.type=$t.NODE_NEIGHBOR,i.node=i.nodes[1],i.neighbor=i.nodes[0],i.nodes=null)},"populate")}];GP.forEach(function(t){return t.regexObj=new RegExp("^"+t.regex)});rKe=o(function(e){for(var r,n,i,a=0;a<GP.length;a++){var s=GP[a],l=s.name,u=e.match(s.regexObj);if(u!=null){n=u,r=s,i=l;var h=u[0];e=e.substring(h.length);break}}return{expr:r,match:n,name:i,remaining:e}},"consumeExpr"),nKe=o(function(e){var r=e.match(/^\s+/);if(r){var n=r[0];e=e.substring(n.length)}return e},"consumeWhitespace"),iKe=o(function(e){var r=this,n=r.inputText=e,i=r[0]=mn();for(r.length=1,n=nKe(n);;){var a=rKe(n);if(a.expr==null)return un("The selector `"+e+"`is invalid"),!1;var s=a.match.slice(1),l=a.expr.populate(r,i,s);if(l===!1)return!1;if(l!=null&&(i=l),n=a.remaining,n.match(/^\s*$/))break}var u=r[r.length-1];r.currentSubject!=null&&(u.subject=r.currentSubject),u.edgeCount=r.edgeCount,u.compoundCount=r.compoundCount;for(var h=0;h<r.length;h++){var f=r[h];if(f.compoundCount>0&&f.edgeCount>0)return un("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(f.edgeCount>1)return un("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;f.edgeCount===1&&un("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},"parse"),aKe=o(function(){if(this.toStringCache!=null)return this.toStringCache;for(var e=o(function(f){return f??""},"clean"),r=o(function(f){return Zt(f)?'"'+f+'"':e(f)},"cleanVal"),n=o(function(f){return" "+f+" "},"space"),i=o(function(f,d){var p=f.type,m=f.value;switch(p){case $t.GROUP:{var g=e(m);return g.substring(0,g.length-1)}case $t.DATA_COMPARE:{var y=f.field,v=f.operator;return"["+y+n(e(v))+r(m)+"]"}case $t.DATA_BOOL:{var x=f.operator,b=f.field;return"["+e(x)+b+"]"}case $t.DATA_EXIST:{var w=f.field;return"["+w+"]"}case $t.META_COMPARE:{var C=f.operator,T=f.field;return"[["+T+n(e(C))+r(m)+"]]"}case $t.STATE:return m;case $t.ID:return"#"+m;case $t.CLASS:return"."+m;case $t.PARENT:case $t.CHILD:return a(f.parent,d)+n(">")+a(f.child,d);case $t.ANCESTOR:case $t.DESCENDANT:return a(f.ancestor,d)+" "+a(f.descendant,d);case $t.COMPOUND_SPLIT:{var E=a(f.left,d),A=a(f.subject,d),S=a(f.right,d);return E+(E.length>0?" ":"")+A+S}case $t.TRUE:return""}},"checkToString"),a=o(function(f,d){return f.checks.reduce(function(p,m,g){return p+(d===f&&g===0?"$":"")+i(m,d)},"")},"queryToString"),s="",l=0;l<this.length;l++){var u=this[l];s+=a(u,u.subject),this.length>1&&l<this.length-1&&(s+=", ")}return this.toStringCache=s,s},"toString"),sKe={parse:iKe,toString:aKe},Bme=o(function(e,r,n){var i,a=Zt(e),s=Ct(e),l=Zt(n),u,h,f=!1,d=!1,p=!1;switch(r.indexOf("!")>=0&&(r=r.replace("!",""),d=!0),r.indexOf("@")>=0&&(r=r.replace("@",""),f=!0),(a||l||f)&&(u=!a&&!s?"":""+e,h=""+n),f&&(e=u=u.toLowerCase(),n=h=h.toLowerCase()),r){case"*=":i=u.indexOf(h)>=0;break;case"$=":i=u.indexOf(h,u.length-h.length)>=0;break;case"^=":i=u.indexOf(h)===0;break;case"=":i=e===n;break;case">":p=!0,i=e>n;break;case">=":p=!0,i=e>=n;break;case"<":p=!0,i=e<n;break;case"<=":p=!0,i=e<=n;break;default:i=!1;break}return d&&(e!=null||!p)&&(i=!i),i},"valCmp"),oKe=o(function(e,r){switch(r){case"?":return!!e;case"!":return!e;case"^":return e===void 0}},"boolCmp"),lKe=o(function(e){return e!==void 0},"existCmp"),hB=o(function(e,r){return e.data(r)},"data"),cKe=o(function(e,r){return e[r]()},"meta"),fi=[],zn=o(function(e,r){return e.checks.every(function(n){return fi[n.type](n,r)})},"matches");fi[$t.GROUP]=function(t,e){var r=t.value;return r==="*"||r===e.group()};fi[$t.STATE]=function(t,e){var r=t.value;return eKe(r,e)};fi[$t.ID]=function(t,e){var r=t.value;return e.id()===r};fi[$t.CLASS]=function(t,e){var r=t.value;return e.hasClass(r)};fi[$t.META_COMPARE]=function(t,e){var r=t.field,n=t.operator,i=t.value;return Bme(cKe(e,r),n,i)};fi[$t.DATA_COMPARE]=function(t,e){var r=t.field,n=t.operator,i=t.value;return Bme(hB(e,r),n,i)};fi[$t.DATA_BOOL]=function(t,e){var r=t.field,n=t.operator;return oKe(hB(e,r),n)};fi[$t.DATA_EXIST]=function(t,e){var r=t.field;return t.operator,lKe(hB(e,r))};fi[$t.UNDIRECTED_EDGE]=function(t,e){var r=t.nodes[0],n=t.nodes[1],i=e.source(),a=e.target();return zn(r,i)&&zn(n,a)||zn(n,i)&&zn(r,a)};fi[$t.NODE_NEIGHBOR]=function(t,e){return zn(t.node,e)&&e.neighborhood().some(function(r){return r.isNode()&&zn(t.neighbor,r)})};fi[$t.DIRECTED_EDGE]=function(t,e){return zn(t.source,e.source())&&zn(t.target,e.target())};fi[$t.NODE_SOURCE]=function(t,e){return zn(t.source,e)&&e.outgoers().some(function(r){return r.isNode()&&zn(t.target,r)})};fi[$t.NODE_TARGET]=function(t,e){return zn(t.target,e)&&e.incomers().some(function(r){return r.isNode()&&zn(t.source,r)})};fi[$t.CHILD]=function(t,e){return zn(t.child,e)&&zn(t.parent,e.parent())};fi[$t.PARENT]=function(t,e){return zn(t.parent,e)&&e.children().some(function(r){return zn(t.child,r)})};fi[$t.DESCENDANT]=function(t,e){return zn(t.descendant,e)&&e.ancestors().some(function(r){return zn(t.ancestor,r)})};fi[$t.ANCESTOR]=function(t,e){return zn(t.ancestor,e)&&e.descendants().some(function(r){return zn(t.descendant,r)})};fi[$t.COMPOUND_SPLIT]=function(t,e){return zn(t.subject,e)&&zn(t.left,e)&&zn(t.right,e)};fi[$t.TRUE]=function(){return!0};fi[$t.COLLECTION]=function(t,e){var r=t.value;return r.has(e)};fi[$t.FILTER]=function(t,e){var r=t.value;return r(e)};uKe=o(function(e){var r=this;if(r.length===1&&r[0].checks.length===1&&r[0].checks[0].type===$t.ID)return e.getElementById(r[0].checks[0].value).collection();var n=o(function(a){for(var s=0;s<r.length;s++){var l=r[s];if(zn(l,a))return!0}return!1},"selectorFunction");return r.text()==null&&(n=o(function(){return!0},"selectorFunction")),e.filter(n)},"filter"),hKe=o(function(e){for(var r=this,n=0;n<r.length;n++){var i=r[n];if(zn(i,e))return!0}return!1},"matches"),fKe={matches:hKe,filter:uKe},Lf=o(function(e){this.inputText=e,this.currentSubject=null,this.compoundCount=0,this.edgeCount=0,this.length=0,e==null||Zt(e)&&e.match(/^\s*$/)||(go(e)?this.addQuery({checks:[{type:$t.COLLECTION,value:e.collection()}]}):si(e)?this.addQuery({checks:[{type:$t.FILTER,value:e}]}):Zt(e)?this.parse(e)||(this.invalid=!0):ai("A selector must be created from a string; found "))},"Selector"),Rf=Lf.prototype;[sKe,fKe].forEach(function(t){return rr(Rf,t)});Rf.text=function(){return this.inputText};Rf.size=function(){return this.length};Rf.eq=function(t){return this[t]};Rf.sameText=function(t){return!this.invalid&&!t.invalid&&this.text()===t.text()};Rf.addQuery=function(t){this[this.length++]=t};Rf.selector=Rf.toString;Sf={allAre:o(function(e){var r=new Lf(e);return this.every(function(n){return r.matches(n)})},"allAre"),is:o(function(e){var r=new Lf(e);return this.some(function(n){return r.matches(n)})},"is"),some:o(function(e,r){for(var n=0;n<this.length;n++){var i=r?e.apply(r,[this[n],n,this]):e(this[n],n,this);if(i)return!0}return!1},"some"),every:o(function(e,r){for(var n=0;n<this.length;n++){var i=r?e.apply(r,[this[n],n,this]):e(this[n],n,this);if(!i)return!1}return!0},"every"),same:o(function(e){if(this===e)return!0;e=this.cy().collection(e);var r=this.length,n=e.length;return r!==n?!1:r===1?this[0]===e[0]:this.every(function(i){return e.hasElementWithId(i.id())})},"same"),anySame:o(function(e){return e=this.cy().collection(e),this.some(function(r){return e.hasElementWithId(r.id())})},"anySame"),allAreNeighbors:o(function(e){e=this.cy().collection(e);var r=this.neighborhood();return e.every(function(n){return r.hasElementWithId(n.id())})},"allAreNeighbors"),contains:o(function(e){e=this.cy().collection(e);var r=this;return e.every(function(n){return r.hasElementWithId(n.id())})},"contains")};Sf.allAreNeighbours=Sf.allAreNeighbors;Sf.has=Sf.contains;Sf.equal=Sf.equals=Sf.same;tl=o(function(e,r){return o(function(i,a,s,l){var u=i,h=this,f;if(u==null?f="":go(u)&&u.length===1&&(f=u.id()),h.length===1&&f){var d=h[0]._private,p=d.traversalCache=d.traversalCache||{},m=p[r]=p[r]||[],g=_f(f),y=m[g];return y||(m[g]=e.call(h,i,a,s,l))}else return e.call(h,i,a,s,l)},"traversalCache")},"cache"),Z1={parent:o(function(e){var r=[];if(this.length===1){var n=this[0]._private.parent;if(n)return n}for(var i=0;i<this.length;i++){var a=this[i],s=a._private.parent;s&&r.push(s)}return this.spawn(r,!0).filter(e)},"parent"),parents:o(function(e){for(var r=[],n=this.parent();n.nonempty();){for(var i=0;i<n.length;i++){var a=n[i];r.push(a)}n=n.parent()}return this.spawn(r,!0).filter(e)},"parents"),commonAncestors:o(function(e){for(var r,n=0;n<this.length;n++){var i=this[n],a=i.parents();r=r||a,r=r.intersect(a)}return r.filter(e)},"commonAncestors"),orphans:o(function(e){return this.stdFilter(function(r){return r.isOrphan()}).filter(e)},"orphans"),nonorphans:o(function(e){return this.stdFilter(function(r){return r.isChild()}).filter(e)},"nonorphans"),children:tl(function(t){for(var e=[],r=0;r<this.length;r++)for(var n=this[r],i=n._private.children,a=0;a<i.length;a++)e.push(i[a]);return this.spawn(e,!0).filter(t)},"children"),siblings:o(function(e){return this.parent().children().not(this).filter(e)},"siblings"),isParent:o(function(){var e=this[0];if(e)return e.isNode()&&e._private.children.length!==0},"isParent"),isChildless:o(function(){var e=this[0];if(e)return e.isNode()&&e._private.children.length===0},"isChildless"),isChild:o(function(){var e=this[0];if(e)return e.isNode()&&e._private.parent!=null},"isChild"),isOrphan:o(function(){var e=this[0];if(e)return e.isNode()&&e._private.parent==null},"isOrphan"),descendants:o(function(e){var r=[];function n(i){for(var a=0;a<i.length;a++){var s=i[a];r.push(s),s.children().nonempty()&&n(s.children())}}return o(n,"add"),n(this.children()),this.spawn(r,!0).filter(e)},"descendants")};o(fB,"forEachCompound");o(Fme,"addChildren");Z1.forEachDown=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return fB(this,t,e,Fme)};o($me,"addParent");Z1.forEachUp=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return fB(this,t,e,$me)};o(dKe,"addParentAndChildren");Z1.forEachUpAndDown=function(t){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return fB(this,t,e,dKe)};Z1.ancestors=Z1.parents;Kb=zme={data:cn.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:cn.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:cn.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:cn.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:cn.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:cn.removeData({field:"rscratch",triggerEvent:!1}),id:o(function(){var e=this[0];if(e)return e._private.data.id},"id")};Kb.attr=Kb.data;Kb.removeAttr=Kb.removeData;pKe=zme,FS={};o(SP,"defineDegreeFunction");rr(FS,{degree:SP(function(t,e){return e.source().same(e.target())?2:1}),indegree:SP(function(t,e){return e.target().same(t)?1:0}),outdegree:SP(function(t,e){return e.source().same(t)?1:0})});o(F1,"defineDegreeBoundsFunction");rr(FS,{minDegree:F1("degree",function(t,e){return t<e}),maxDegree:F1("degree",function(t,e){return t>e}),minIndegree:F1("indegree",function(t,e){return t<e}),maxIndegree:F1("indegree",function(t,e){return t>e}),minOutdegree:F1("outdegree",function(t,e){return t<e}),maxOutdegree:F1("outdegree",function(t,e){return t>e})});rr(FS,{totalDegree:o(function(e){for(var r=0,n=this.nodes(),i=0;i<n.length;i++)r+=n[i].degree(e);return r},"totalDegree")});Vme=o(function(e,r,n){for(var i=0;i<e.length;i++){var a=e[i];if(!a.locked()){var s=a._private.position,l={x:r.x!=null?r.x-s.x:0,y:r.y!=null?r.y-s.y:0};a.isParent()&&!(l.x===0&&l.y===0)&&a.children().shift(l,n),a.dirtyBoundingBoxCache()}}},"beforePositionSet"),a0e={field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"emitAndNotify",allowGetting:!0,validKeys:["x","y"],beforeGet:o(function(e){e.updateCompoundBounds()},"beforeGet"),beforeSet:o(function(e,r){Vme(e,r,!1)},"beforeSet"),onSet:o(function(e){e.dirtyCompoundBoundsCache()},"onSet"),canSet:o(function(e){return!e.locked()},"canSet")};Vl=Gme={position:cn.data(a0e),silentPosition:cn.data(rr({},a0e,{allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!1,beforeSet:o(function(e,r){Vme(e,r,!0)},"beforeSet"),onSet:o(function(e){e.dirtyCompoundBoundsCache()},"onSet")})),positions:o(function(e,r){if(Ur(e))r?this.silentPosition(e):this.position(e);else if(si(e)){var n=e,i=this.cy();i.startBatch();for(var a=0;a<this.length;a++){var s=this[a],l=void 0;(l=n(s,a))&&(r?s.silentPosition(l):s.position(l))}i.endBatch()}return this},"positions"),silentPositions:o(function(e){return this.positions(e,!0)},"silentPositions"),shift:o(function(e,r,n){var i;if(Ur(e)?(i={x:Ct(e.x)?e.x:0,y:Ct(e.y)?e.y:0},n=r):Zt(e)&&Ct(r)&&(i={x:0,y:0},i[e]=r),i!=null){var a=this.cy();a.startBatch();for(var s=0;s<this.length;s++){var l=this[s];if(!(a.hasCompoundNodes()&&l.isChild()&&l.ancestors().anySame(this))){var u=l.position(),h={x:u.x+i.x,y:u.y+i.y};n?l.silentPosition(h):l.position(h)}}a.endBatch()}return this},"shift"),silentShift:o(function(e,r){return Ur(e)?this.shift(e,!0):Zt(e)&&Ct(r)&&this.shift(e,r,!0),this},"silentShift"),renderedPosition:o(function(e,r){var n=this[0],i=this.cy(),a=i.zoom(),s=i.pan(),l=Ur(e)?e:void 0,u=l!==void 0||r!==void 0&&Zt(e);if(n&&n.isNode())if(u)for(var h=0;h<this.length;h++){var f=this[h];r!==void 0?f.position(e,(r-s[e])/a):l!==void 0&&f.position(pme(l,a,s))}else{var d=n.position();return l=MS(d,a,s),e===void 0?l:l[e]}else if(!u)return;return this},"renderedPosition"),relativePosition:o(function(e,r){var n=this[0],i=this.cy(),a=Ur(e)?e:void 0,s=a!==void 0||r!==void 0&&Zt(e),l=i.hasCompoundNodes();if(n&&n.isNode())if(s)for(var u=0;u<this.length;u++){var h=this[u],f=l?h.parent():null,d=f&&f.length>0,p=d;d&&(f=f[0]);var m=p?f.position():{x:0,y:0};r!==void 0?h.position(e,r+m[e]):a!==void 0&&h.position({x:a.x+m.x,y:a.y+m.y})}else{var g=n.position(),y=l?n.parent():null,v=y&&y.length>0,x=v;v&&(y=y[0]);var b=x?y.position():{x:0,y:0};return a={x:g.x-b.x,y:g.y-b.y},e===void 0?a:a[e]}else if(!s)return;return this},"relativePosition")};Vl.modelPosition=Vl.point=Vl.position;Vl.modelPositions=Vl.points=Vl.positions;Vl.renderedPoint=Vl.renderedPosition;Vl.relativePoint=Vl.relativePosition;mKe=Gme;X1=Of={};Of.renderedBoundingBox=function(t){var e=this.boundingBox(t),r=this.cy(),n=r.zoom(),i=r.pan(),a=e.x1*n+i.x,s=e.x2*n+i.x,l=e.y1*n+i.y,u=e.y2*n+i.y;return{x1:a,x2:s,y1:l,y2:u,w:s-a,h:u-l}};Of.dirtyCompoundBoundsCache=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,e=this.cy();return!e.styleEnabled()||!e.hasCompoundNodes()?this:(this.forEachUp(function(r){if(r.isParent()){var n=r._private;n.compoundBoundsClean=!1,n.bbCache=null,t||r.emitAndNotify("bounds")}}),this)};Of.updateCompoundBounds=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,e=this.cy();if(!e.styleEnabled()||!e.hasCompoundNodes())return this;if(!t&&e.batching())return this;function r(s){if(!s.isParent())return;var l=s._private,u=s.children(),h=s.pstyle("compound-sizing-wrt-labels").value==="include",f={width:{val:s.pstyle("min-width").pfValue,left:s.pstyle("min-width-bias-left"),right:s.pstyle("min-width-bias-right")},height:{val:s.pstyle("min-height").pfValue,top:s.pstyle("min-height-bias-top"),bottom:s.pstyle("min-height-bias-bottom")}},d=u.boundingBox({includeLabels:h,includeOverlays:!1,useCache:!1}),p=l.position;(d.w===0||d.h===0)&&(d={w:s.pstyle("width").pfValue,h:s.pstyle("height").pfValue},d.x1=p.x-d.w/2,d.x2=p.x+d.w/2,d.y1=p.y-d.h/2,d.y2=p.y+d.h/2);function m(_,I,D){var k=0,L=0,R=I+D;return _>0&&R>0&&(k=I/R*_,L=D/R*_),{biasDiff:k,biasComplementDiff:L}}o(m,"computeBiasValues");function g(_,I,D,k){if(D.units==="%")switch(k){case"width":return _>0?D.pfValue*_:0;case"height":return I>0?D.pfValue*I:0;case"average":return _>0&&I>0?D.pfValue*(_+I)/2:0;case"min":return _>0&&I>0?_>I?D.pfValue*I:D.pfValue*_:0;case"max":return _>0&&I>0?_>I?D.pfValue*_:D.pfValue*I:0;default:return 0}else return D.units==="px"?D.pfValue:0}o(g,"computePaddingValues");var y=f.width.left.value;f.width.left.units==="px"&&f.width.val>0&&(y=y*100/f.width.val);var v=f.width.right.value;f.width.right.units==="px"&&f.width.val>0&&(v=v*100/f.width.val);var x=f.height.top.value;f.height.top.units==="px"&&f.height.val>0&&(x=x*100/f.height.val);var b=f.height.bottom.value;f.height.bottom.units==="px"&&f.height.val>0&&(b=b*100/f.height.val);var w=m(f.width.val-d.w,y,v),C=w.biasDiff,T=w.biasComplementDiff,E=m(f.height.val-d.h,x,b),A=E.biasDiff,S=E.biasComplementDiff;l.autoPadding=g(d.w,d.h,s.pstyle("padding"),s.pstyle("padding-relative-to").value),l.autoWidth=Math.max(d.w,f.width.val),p.x=(-C+d.x1+d.x2+T)/2,l.autoHeight=Math.max(d.h,f.height.val),p.y=(-A+d.y1+d.y2+S)/2}o(r,"update");for(var n=0;n<this.length;n++){var i=this[n],a=i._private;(!a.compoundBoundsClean||t)&&(r(i),e.batching()||(a.compoundBoundsClean=!0))}return this};el=o(function(e){return e===1/0||e===-1/0?0:e},"noninf"),zl=o(function(e,r,n,i,a){i-r===0||a-n===0||r==null||n==null||i==null||a==null||(e.x1=r<e.x1?r:e.x1,e.x2=i>e.x2?i:e.x2,e.y1=n<e.y1?n:e.y1,e.y2=a>e.y2?a:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},"updateBounds"),Pp=o(function(e,r){return r==null?e:zl(e,r.x1,r.y1,r.x2,r.y2)},"updateBoundsFromBox"),Db=o(function(e,r,n){return Gl(e,r,n)},"prefixedProperty"),tS=o(function(e,r,n){if(!r.cy().headless()){var i=r._private,a=i.rstyle,s=a.arrowWidth/2,l=r.pstyle(n+"-arrow-shape").value,u,h;if(l!=="none"){n==="source"?(u=a.srcX,h=a.srcY):n==="target"?(u=a.tgtX,h=a.tgtY):(u=a.midX,h=a.midY);var f=i.arrowBounds=i.arrowBounds||{},d=f[n]=f[n]||{};d.x1=u-s,d.y1=h-s,d.x2=u+s,d.y2=h+s,d.w=d.x2-d.x1,d.h=d.y2-d.y1,cS(d,1),zl(e,d.x1,d.y1,d.x2,d.y2)}}},"updateBoundsFromArrow"),CP=o(function(e,r,n){if(!r.cy().headless()){var i;n?i=n+"-":i="";var a=r._private,s=a.rstyle,l=r.pstyle(i+"label").strValue;if(l){var u=r.pstyle("text-halign"),h=r.pstyle("text-valign"),f=Db(s,"labelWidth",n),d=Db(s,"labelHeight",n),p=Db(s,"labelX",n),m=Db(s,"labelY",n),g=r.pstyle(i+"text-margin-x").pfValue,y=r.pstyle(i+"text-margin-y").pfValue,v=r.isEdge(),x=r.pstyle(i+"text-rotation"),b=r.pstyle("text-outline-width").pfValue,w=r.pstyle("text-border-width").pfValue,C=w/2,T=r.pstyle("text-background-padding").pfValue,E=2,A=d,S=f,_=S/2,I=A/2,D,k,L,R;if(v)D=p-_,k=p+_,L=m-I,R=m+I;else{switch(u.value){case"left":D=p-S,k=p;break;case"center":D=p-_,k=p+_;break;case"right":D=p,k=p+S;break}switch(h.value){case"top":L=m-A,R=m;break;case"center":L=m-I,R=m+I;break;case"bottom":L=m,R=m+A;break}}var O=g-Math.max(b,C)-T-E,M=g+Math.max(b,C)+T+E,B=y-Math.max(b,C)-T-E,F=y+Math.max(b,C)+T+E;D+=O,k+=M,L+=B,R+=F;var P=n||"main",z=a.labelBounds,$=z[P]=z[P]||{};$.x1=D,$.y1=L,$.x2=k,$.y2=R,$.w=k-D,$.h=R-L,$.leftPad=O,$.rightPad=M,$.topPad=B,$.botPad=F;var H=v&&x.strValue==="autorotate",Q=x.pfValue!=null&&x.pfValue!==0;if(H||Q){var j=H?Db(a.rstyle,"labelAngle",n):x.pfValue,ie=Math.cos(j),ne=Math.sin(j),le=(D+k)/2,he=(L+R)/2;if(!v){switch(u.value){case"left":le=k;break;case"right":le=D;break}switch(h.value){case"top":he=R;break;case"bottom":he=L;break}}var K=o(function(ce,ae){return ce=ce-le,ae=ae-he,{x:ce*ie-ae*ne+le,y:ce*ne+ae*ie+he}},"rotate"),X=K(D,L),te=K(D,R),J=K(k,L),se=K(k,R);D=Math.min(X.x,te.x,J.x,se.x),k=Math.max(X.x,te.x,J.x,se.x),L=Math.min(X.y,te.y,J.y,se.y),R=Math.max(X.y,te.y,J.y,se.y)}var ue=P+"Rot",Z=z[ue]=z[ue]||{};Z.x1=D,Z.y1=L,Z.x2=k,Z.y2=R,Z.w=k-D,Z.h=R-L,zl(e,D,L,k,R),zl(a.labelBounds.all,D,L,k,R)}return e}},"updateBoundsFromLabel"),gKe=o(function(e,r){if(!r.cy().headless()){var n=r.pstyle("outline-opacity").value,i=r.pstyle("outline-width").value;if(n>0&&i>0){var a=r.pstyle("outline-offset").value,s=r.pstyle("shape").value,l=i+a,u=(e.w+l*2)/e.w,h=(e.h+l*2)/e.h,f=0,d=0;["diamond","pentagon","round-triangle"].includes(s)?(u=(e.w+l*2.4)/e.w,d=-l/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(s)?u=(e.w+l*2.4)/e.w:s==="star"?(u=(e.w+l*2.8)/e.w,h=(e.h+l*2.6)/e.h,d=-l/3.8):s==="triangle"?(u=(e.w+l*2.8)/e.w,h=(e.h+l*2.4)/e.h,d=-l/1.4):s==="vee"&&(u=(e.w+l*4.4)/e.w,h=(e.h+l*3.8)/e.h,d=-l*.5);var p=e.h*h-e.h,m=e.w*u-e.w;if(uS(e,[Math.ceil(p/2),Math.ceil(m/2)]),f!=0||d!==0){var g=Bqe(e,f,d);gme(e,g)}}}},"updateBoundsFromOutline"),yKe=o(function(e,r){var n=e._private.cy,i=n.styleEnabled(),a=n.headless(),s=Hs(),l=e._private,u=e.isNode(),h=e.isEdge(),f,d,p,m,g,y,v=l.rstyle,x=u&&i?e.pstyle("bounds-expansion").pfValue:[0],b=o(function(Se){return Se.pstyle("display").value!=="none"},"isDisplayed"),w=!i||b(e)&&(!h||b(e.source())&&b(e.target()));if(w){var C=0,T=0;i&&r.includeOverlays&&(C=e.pstyle("overlay-opacity").value,C!==0&&(T=e.pstyle("overlay-padding").value));var E=0,A=0;i&&r.includeUnderlays&&(E=e.pstyle("underlay-opacity").value,E!==0&&(A=e.pstyle("underlay-padding").value));var S=Math.max(T,A),_=0,I=0;if(i&&(_=e.pstyle("width").pfValue,I=_/2),u&&r.includeNodes){var D=e.position();g=D.x,y=D.y;var k=e.outerWidth(),L=k/2,R=e.outerHeight(),O=R/2;f=g-L,d=g+L,p=y-O,m=y+O,zl(s,f,p,d,m),i&&r.includeOutlines&&gKe(s,e)}else if(h&&r.includeEdges)if(i&&!a){var M=e.pstyle("curve-style").strValue;if(f=Math.min(v.srcX,v.midX,v.tgtX),d=Math.max(v.srcX,v.midX,v.tgtX),p=Math.min(v.srcY,v.midY,v.tgtY),m=Math.max(v.srcY,v.midY,v.tgtY),f-=I,d+=I,p-=I,m+=I,zl(s,f,p,d,m),M==="haystack"){var B=v.haystackPts;if(B&&B.length===2){if(f=B[0].x,p=B[0].y,d=B[1].x,m=B[1].y,f>d){var F=f;f=d,d=F}if(p>m){var P=p;p=m,m=P}zl(s,f-I,p-I,d+I,m+I)}}else if(M==="bezier"||M==="unbundled-bezier"||M.endsWith("segments")||M.endsWith("taxi")){var z;switch(M){case"bezier":case"unbundled-bezier":z=v.bezierPts;break;case"segments":case"taxi":case"round-segments":case"round-taxi":z=v.linePts;break}if(z!=null)for(var $=0;$<z.length;$++){var H=z[$];f=H.x-I,d=H.x+I,p=H.y-I,m=H.y+I,zl(s,f,p,d,m)}}}else{var Q=e.source(),j=Q.position(),ie=e.target(),ne=ie.position();if(f=j.x,d=ne.x,p=j.y,m=ne.y,f>d){var le=f;f=d,d=le}if(p>m){var he=p;p=m,m=he}f-=I,d+=I,p-=I,m+=I,zl(s,f,p,d,m)}if(i&&r.includeEdges&&h&&(tS(s,e,"mid-source"),tS(s,e,"mid-target"),tS(s,e,"source"),tS(s,e,"target")),i){var K=e.pstyle("ghost").value==="yes";if(K){var X=e.pstyle("ghost-offset-x").pfValue,te=e.pstyle("ghost-offset-y").pfValue;zl(s,s.x1+X,s.y1+te,s.x2+X,s.y2+te)}}var J=l.bodyBounds=l.bodyBounds||{};Fpe(J,s),uS(J,x),cS(J,1),i&&(f=s.x1,d=s.x2,p=s.y1,m=s.y2,zl(s,f-S,p-S,d+S,m+S));var se=l.overlayBounds=l.overlayBounds||{};Fpe(se,s),uS(se,x),cS(se,1);var ue=l.labelBounds=l.labelBounds||{};ue.all!=null?Pqe(ue.all):ue.all=Hs(),i&&r.includeLabels&&(r.includeMainLabels&&CP(s,e,null),h&&(r.includeSourceLabels&&CP(s,e,"source"),r.includeTargetLabels&&CP(s,e,"target")))}return s.x1=el(s.x1),s.y1=el(s.y1),s.x2=el(s.x2),s.y2=el(s.y2),s.w=el(s.x2-s.x1),s.h=el(s.y2-s.y1),s.w>0&&s.h>0&&w&&(uS(s,x),cS(s,1)),s},"boundingBoxImpl"),Ume=o(function(e){var r=0,n=o(function(s){return(s?1:0)<<r++},"tf"),i=0;return i+=n(e.incudeNodes),i+=n(e.includeEdges),i+=n(e.includeLabels),i+=n(e.includeMainLabels),i+=n(e.includeSourceLabels),i+=n(e.includeTargetLabels),i+=n(e.includeOverlays),i+=n(e.includeOutlines),i},"getKey"),Hme=o(function(e){if(e.isEdge()){var r=e.source().position(),n=e.target().position(),i=o(function(s){return Math.round(s)},"r");return nqe([i(r.x),i(r.y),i(n.x),i(n.y)])}else return 0},"getBoundingBoxPosKey"),s0e=o(function(e,r){var n=e._private,i,a=e.isEdge(),s=r==null?o0e:Ume(r),l=s===o0e,u=Hme(e),h=n.bbCachePosKey===u,f=r.useCache&&h,d=o(function(y){return y._private.bbCache==null||y._private.styleDirty},"isDirty"),p=!f||d(e)||a&&(d(e.source())||d(e.target()));if(p?(h||e.recalculateRenderedStyle(f),i=yKe(e,Qb),n.bbCache=i,n.bbCachePosKey=u):i=n.bbCache,!l){var m=e.isNode();i=Hs(),(r.includeNodes&&m||r.includeEdges&&!m)&&(r.includeOverlays?Pp(i,n.overlayBounds):Pp(i,n.bodyBounds)),r.includeLabels&&(r.includeMainLabels&&(!a||r.includeSourceLabels&&r.includeTargetLabels)?Pp(i,n.labelBounds.all):(r.includeMainLabels&&Pp(i,n.labelBounds.mainRot),r.includeSourceLabels&&Pp(i,n.labelBounds.sourceRot),r.includeTargetLabels&&Pp(i,n.labelBounds.targetRot))),i.w=i.x2-i.x1,i.h=i.y2-i.y1}return i},"cachedBoundingBoxImpl"),Qb={includeNodes:!0,includeEdges:!0,includeLabels:!0,includeMainLabels:!0,includeSourceLabels:!0,includeTargetLabels:!0,includeOverlays:!0,includeUnderlays:!0,includeOutlines:!0,useCache:!0},o0e=Ume(Qb),l0e=la(Qb);Of.boundingBox=function(t){var e;if(this.length===1&&this[0]._private.bbCache!=null&&!this[0]._private.styleDirty&&(t===void 0||t.useCache===void 0||t.useCache===!0))t===void 0?t=Qb:t=l0e(t),e=s0e(this[0],t);else{e=Hs(),t=t||Qb;var r=l0e(t),n=this,i=n.cy(),a=i.styleEnabled();if(a)for(var s=0;s<n.length;s++){var l=n[s],u=l._private,h=Hme(l),f=u.bbCachePosKey===h,d=r.useCache&&f&&!u.styleDirty;l.recalculateRenderedStyle(d)}this.updateCompoundBounds(!t.useCache);for(var p=0;p<n.length;p++){var m=n[p];Pp(e,s0e(m,r))}}return e.x1=el(e.x1),e.y1=el(e.y1),e.x2=el(e.x2),e.y2=el(e.y2),e.w=el(e.x2-e.x1),e.h=el(e.y2-e.y1),e};Of.dirtyBoundingBoxCache=function(){for(var t=0;t<this.length;t++){var e=this[t]._private;e.bbCache=null,e.bbCachePosKey=null,e.bodyBounds=null,e.overlayBounds=null,e.labelBounds.all=null,e.labelBounds.source=null,e.labelBounds.target=null,e.labelBounds.main=null,e.labelBounds.sourceRot=null,e.labelBounds.targetRot=null,e.labelBounds.mainRot=null,e.arrowBounds.source=null,e.arrowBounds.target=null,e.arrowBounds["mid-source"]=null,e.arrowBounds["mid-target"]=null}return this.emitAndNotify("bounds"),this};Of.boundingBoxAt=function(t){var e=this.nodes(),r=this.cy(),n=r.hasCompoundNodes(),i=r.collection();if(n&&(i=e.filter(function(h){return h.isParent()}),e=e.not(i)),Ur(t)){var a=t;t=o(function(){return a},"fn")}var s=o(function(f,d){return f._private.bbAtOldPos=t(f,d)},"storeOldPos"),l=o(function(f){return f._private.bbAtOldPos},"getOldPos");r.startBatch(),e.forEach(s).silentPositions(t),n&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0));var u=Oqe(this.boundingBox({useCache:!1}));return e.silentPositions(l),n&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0)),r.endBatch(),u};X1.boundingbox=X1.bb=X1.boundingBox;X1.renderedBoundingbox=X1.renderedBoundingBox;vKe=Of;Bb=a4={};Wme=o(function(e){e.uppercaseName=Rpe(e.name),e.autoName="auto"+e.uppercaseName,e.labelName="label"+e.uppercaseName,e.outerName="outer"+e.uppercaseName,e.uppercaseOuterName=Rpe(e.outerName),Bb[e.name]=o(function(){var n=this[0],i=n._private,a=i.cy,s=a._private.styleEnabled;if(n)if(s){if(n.isParent())return n.updateCompoundBounds(),i[e.autoName]||0;var l=n.pstyle(e.name);switch(l.strValue){case"label":return n.recalculateRenderedStyle(),i.rstyle[e.labelName]||0;default:return l.pfValue}}else return 1},"dimImpl"),Bb["outer"+e.uppercaseName]=o(function(){var n=this[0],i=n._private,a=i.cy,s=a._private.styleEnabled;if(n)if(s){var l=n[e.name](),u=n.pstyle("border-width").pfValue,h=2*n.padding();return l+u+h}else return 1},"outerDimImpl"),Bb["rendered"+e.uppercaseName]=o(function(){var n=this[0];if(n){var i=n[e.name]();return i*this.cy().zoom()}},"renderedDimImpl"),Bb["rendered"+e.uppercaseOuterName]=o(function(){var n=this[0];if(n){var i=n[e.outerName]();return i*this.cy().zoom()}},"renderedOuterDimImpl")},"defineDimFns");Wme({name:"width"});Wme({name:"height"});a4.padding=function(){var t=this[0],e=t._private;return t.isParent()?(t.updateCompoundBounds(),e.autoPadding!==void 0?e.autoPadding:t.pstyle("padding").pfValue):t.pstyle("padding").pfValue};a4.paddedHeight=function(){var t=this[0];return t.height()+2*t.padding()};a4.paddedWidth=function(){var t=this[0];return t.width()+2*t.padding()};xKe=a4,bKe=o(function(e,r){if(e.isEdge())return r(e)},"ifEdge"),wKe=o(function(e,r){if(e.isEdge()){var n=e.cy();return MS(r(e),n.zoom(),n.pan())}},"ifEdgeRenderedPosition"),TKe=o(function(e,r){if(e.isEdge()){var n=e.cy(),i=n.pan(),a=n.zoom();return r(e).map(function(s){return MS(s,a,i)})}},"ifEdgeRenderedPositions"),kKe=o(function(e){return e.renderer().getControlPoints(e)},"controlPoints"),EKe=o(function(e){return e.renderer().getSegmentPoints(e)},"segmentPoints"),SKe=o(function(e){return e.renderer().getSourceEndpoint(e)},"sourceEndpoint"),CKe=o(function(e){return e.renderer().getTargetEndpoint(e)},"targetEndpoint"),AKe=o(function(e){return e.renderer().getEdgeMidpoint(e)},"midpoint"),c0e={controlPoints:{get:kKe,mult:!0},segmentPoints:{get:EKe,mult:!0},sourceEndpoint:{get:SKe},targetEndpoint:{get:CKe},midpoint:{get:AKe}},_Ke=o(function(e){return"rendered"+e[0].toUpperCase()+e.substr(1)},"renderedName"),DKe=Object.keys(c0e).reduce(function(t,e){var r=c0e[e],n=_Ke(e);return t[e]=function(){return bKe(this,r.get)},r.mult?t[n]=function(){return TKe(this,r.get)}:t[n]=function(){return wKe(this,r.get)},t},{}),LKe=rr({},mKe,vKe,xKe,DKe);qme=o(function(e,r){this.recycle(e,r)},"Event");o(Lb,"returnFalse");o(rS,"returnTrue");qme.prototype={instanceString:o(function(){return"event"},"instanceString"),recycle:o(function(e,r){if(this.isImmediatePropagationStopped=this.isPropagationStopped=this.isDefaultPrevented=Lb,e!=null&&e.preventDefault?(this.type=e.type,this.isDefaultPrevented=e.defaultPrevented?rS:Lb):e!=null&&e.type?r=e:this.type=e,r!=null&&(this.originalEvent=r.originalEvent,this.type=r.type!=null?r.type:this.type,this.cy=r.cy,this.target=r.target,this.position=r.position,this.renderedPosition=r.renderedPosition,this.namespace=r.namespace,this.layout=r.layout),this.cy!=null&&this.position!=null&&this.renderedPosition==null){var n=this.position,i=this.cy.zoom(),a=this.cy.pan();this.renderedPosition={x:n.x*i+a.x,y:n.y*i+a.y}}this.timeStamp=e&&e.timeStamp||Date.now()},"recycle"),preventDefault:o(function(){this.isDefaultPrevented=rS;var e=this.originalEvent;e&&e.preventDefault&&e.preventDefault()},"preventDefault"),stopPropagation:o(function(){this.isPropagationStopped=rS;var e=this.originalEvent;e&&e.stopPropagation&&e.stopPropagation()},"stopPropagation"),stopImmediatePropagation:o(function(){this.isImmediatePropagationStopped=rS,this.stopPropagation()},"stopImmediatePropagation"),isDefaultPrevented:Lb,isPropagationStopped:Lb,isImmediatePropagationStopped:Lb};Yme=/^([^.]+)(\.(?:[^.]+))?$/,RKe=".*",Xme={qualifierCompare:o(function(e,r){return e===r},"qualifierCompare"),eventMatches:o(function(){return!0},"eventMatches"),addEventFields:o(function(){},"addEventFields"),callbackContext:o(function(e){return e},"callbackContext"),beforeEmit:o(function(){},"beforeEmit"),afterEmit:o(function(){},"afterEmit"),bubble:o(function(){return!1},"bubble"),parent:o(function(){return null},"parent"),context:null},u0e=Object.keys(Xme),NKe={};o($S,"Emitter");Nf=$S.prototype,jme=o(function(e,r,n,i,a,s,l){si(i)&&(a=i,i=null),l&&(s==null?s=l:s=rr({},s,l));for(var u=En(n)?n:n.split(/\s+/),h=0;h<u.length;h++){var f=u[h];if(!Af(f)){var d=f.match(Yme);if(d){var p=d[1],m=d[2]?d[2]:null,g=r(e,f,p,m,i,a,s);if(g===!1)break}}}},"forEachEvent"),h0e=o(function(e,r){return e.addEventFields(e.context,r),new qme(r.type,r)},"makeEventObj"),MKe=o(function(e,r,n){if(eWe(n)){r(e,n);return}else if(Ur(n)){r(e,h0e(e,n));return}for(var i=En(n)?n:n.split(/\s+/),a=0;a<i.length;a++){var s=i[a];if(!Af(s)){var l=s.match(Yme);if(l){var u=l[1],h=l[2]?l[2]:null,f=h0e(e,{type:u,namespace:h,target:e.context});r(e,f)}}}},"forEachEventObj");Nf.on=Nf.addListener=function(t,e,r,n,i){return jme(this,function(a,s,l,u,h,f,d){si(f)&&a.listeners.push({event:s,callback:f,type:l,namespace:u,qualifier:h,conf:d})},t,e,r,n,i),this};Nf.one=function(t,e,r,n){return this.on(t,e,r,n,{one:!0})};Nf.removeListener=Nf.off=function(t,e,r,n){var i=this;this.emitting!==0&&(this.listeners=lqe(this.listeners));for(var a=this.listeners,s=o(function(h){var f=a[h];jme(i,function(d,p,m,g,y,v){if((f.type===m||t==="*")&&(!g&&f.namespace!==".*"||f.namespace===g)&&(!y||d.qualifierCompare(f.qualifier,y))&&(!v||f.callback===v))return a.splice(h,1),!1},t,e,r,n)},"_loop"),l=a.length-1;l>=0;l--)s(l);return this};Nf.removeAllListeners=function(){return this.removeListener("*")};Nf.emit=Nf.trigger=function(t,e,r){var n=this.listeners,i=n.length;return this.emitting++,En(e)||(e=[e]),MKe(this,function(a,s){r!=null&&(n=[{event:s.event,type:s.type,namespace:s.namespace,callback:r}],i=n.length);for(var l=o(function(f){var d=n[f];if(d.type===s.type&&(!d.namespace||d.namespace===s.namespace||d.namespace===RKe)&&a.eventMatches(a.context,d,s)){var p=[s];e!=null&&uqe(p,e),a.beforeEmit(a.context,d,s),d.conf&&d.conf.one&&(a.listeners=a.listeners.filter(function(y){return y!==d}));var m=a.callbackContext(a.context,d,s),g=d.callback.apply(m,p);a.afterEmit(a.context,d,s),g===!1&&(s.stopPropagation(),s.preventDefault())}},"_loop2"),u=0;u<i;u++)l(u);a.bubble(a.context)&&!s.isPropagationStopped()&&a.parent(a.context).emit(s,e)},t),this.emitting--,this};IKe={qualifierCompare:o(function(e,r){return e==null||r==null?e==null&&r==null:e.sameText(r)},"qualifierCompare"),eventMatches:o(function(e,r,n){var i=r.qualifier;return i!=null?e!==n.target&&t4(n.target)&&i.matches(n.target):!0},"eventMatches"),addEventFields:o(function(e,r){r.cy=e.cy(),r.target=e},"addEventFields"),callbackContext:o(function(e,r,n){return r.qualifier!=null?n.target:e},"callbackContext"),beforeEmit:o(function(e,r){r.conf&&r.conf.once&&r.conf.onceCollection.removeListener(r.event,r.qualifier,r.callback)},"beforeEmit"),bubble:o(function(){return!0},"bubble"),parent:o(function(e){return e.isChild()?e.parent():e.cy()},"parent")},nS=o(function(e){return Zt(e)?new Lf(e):e},"argSelector"),Kme={createEmitter:o(function(){for(var e=0;e<this.length;e++){var r=this[e],n=r._private;n.emitter||(n.emitter=new $S(IKe,r))}return this},"createEmitter"),emitter:o(function(){return this._private.emitter},"emitter"),on:o(function(e,r,n){for(var i=nS(r),a=0;a<this.length;a++){var s=this[a];s.emitter().on(e,i,n)}return this},"on"),removeListener:o(function(e,r,n){for(var i=nS(r),a=0;a<this.length;a++){var s=this[a];s.emitter().removeListener(e,i,n)}return this},"removeListener"),removeAllListeners:o(function(){for(var e=0;e<this.length;e++){var r=this[e];r.emitter().removeAllListeners()}return this},"removeAllListeners"),one:o(function(e,r,n){for(var i=nS(r),a=0;a<this.length;a++){var s=this[a];s.emitter().one(e,i,n)}return this},"one"),once:o(function(e,r,n){for(var i=nS(r),a=0;a<this.length;a++){var s=this[a];s.emitter().on(e,i,n,{once:!0,onceCollection:this})}},"once"),emit:o(function(e,r){for(var n=0;n<this.length;n++){var i=this[n];i.emitter().emit(e,r)}return this},"emit"),emitAndNotify:o(function(e,r){if(this.length!==0)return this.cy().notify(e,this),this.emit(e,r),this},"emitAndNotify")};cn.eventAliasesOn(Kme);Qme={nodes:o(function(e){return this.filter(function(r){return r.isNode()}).filter(e)},"nodes"),edges:o(function(e){return this.filter(function(r){return r.isEdge()}).filter(e)},"edges"),byGroup:o(function(){for(var e=this.spawn(),r=this.spawn(),n=0;n<this.length;n++){var i=this[n];i.isNode()?e.push(i):r.push(i)}return{nodes:e,edges:r}},"byGroup"),filter:o(function(e,r){if(e===void 0)return this;if(Zt(e)||go(e))return new Lf(e).filter(this);if(si(e)){for(var n=this.spawn(),i=this,a=0;a<i.length;a++){var s=i[a],l=r?e.apply(r,[s,a,i]):e(s,a,i);l&&n.push(s)}return n}return this.spawn()},"filter"),not:o(function(e){if(e){Zt(e)&&(e=this.filter(e));for(var r=this.spawn(),n=0;n<this.length;n++){var i=this[n],a=e.has(i);a||r.push(i)}return r}else return this},"not"),absoluteComplement:o(function(){var e=this.cy();return e.mutableElements().not(this)},"absoluteComplement"),intersect:o(function(e){if(Zt(e)){var r=e;return this.filter(r)}for(var n=this.spawn(),i=this,a=e,s=this.length<e.length,l=s?i:a,u=s?a:i,h=0;h<l.length;h++){var f=l[h];u.has(f)&&n.push(f)}return n},"intersect"),xor:o(function(e){var r=this._private.cy;Zt(e)&&(e=r.$(e));var n=this.spawn(),i=this,a=e,s=o(function(u,h){for(var f=0;f<u.length;f++){var d=u[f],p=d._private.data.id,m=h.hasElementWithId(p);m||n.push(d)}},"add");return s(i,a),s(a,i),n},"xor"),diff:o(function(e){var r=this._private.cy;Zt(e)&&(e=r.$(e));var n=this.spawn(),i=this.spawn(),a=this.spawn(),s=this,l=e,u=o(function(f,d,p){for(var m=0;m<f.length;m++){var g=f[m],y=g._private.data.id,v=d.hasElementWithId(y);v?a.merge(g):p.push(g)}},"add");return u(s,l,n),u(l,s,i),{left:n,right:i,both:a}},"diff"),add:o(function(e){var r=this._private.cy;if(!e)return this;if(Zt(e)){var n=e;e=r.mutableElements().filter(n)}for(var i=this.spawnSelf(),a=0;a<e.length;a++){var s=e[a],l=!this.has(s);l&&i.push(s)}return i},"add"),merge:o(function(e){var r=this._private,n=r.cy;if(!e)return this;if(e&&Zt(e)){var i=e;e=n.mutableElements().filter(i)}for(var a=r.map,s=0;s<e.length;s++){var l=e[s],u=l._private.data.id,h=!a.has(u);if(h){var f=this.length++;this[f]=l,a.set(u,{ele:l,index:f})}}return this},"merge"),unmergeAt:o(function(e){var r=this[e],n=r.id(),i=this._private,a=i.map;this[e]=void 0,a.delete(n);var s=e===this.length-1;if(this.length>1&&!s){var l=this.length-1,u=this[l],h=u._private.data.id;this[l]=void 0,this[e]=u,a.set(h,{ele:u,index:e})}return this.length--,this},"unmergeAt"),unmergeOne:o(function(e){e=e[0];var r=this._private,n=e._private.data.id,i=r.map,a=i.get(n);if(!a)return this;var s=a.index;return this.unmergeAt(s),this},"unmergeOne"),unmerge:o(function(e){var r=this._private.cy;if(!e)return this;if(e&&Zt(e)){var n=e;e=r.mutableElements().filter(n)}for(var i=0;i<e.length;i++)this.unmergeOne(e[i]);return this},"unmerge"),unmergeBy:o(function(e){for(var r=this.length-1;r>=0;r--){var n=this[r];e(n)&&this.unmergeAt(r)}return this},"unmergeBy"),map:o(function(e,r){for(var n=[],i=this,a=0;a<i.length;a++){var s=i[a],l=r?e.apply(r,[s,a,i]):e(s,a,i);n.push(l)}return n},"map"),reduce:o(function(e,r){for(var n=r,i=this,a=0;a<i.length;a++)n=e(n,i[a],a,i);return n},"reduce"),max:o(function(e,r){for(var n=-1/0,i,a=this,s=0;s<a.length;s++){var l=a[s],u=r?e.apply(r,[l,s,a]):e(l,s,a);u>n&&(n=u,i=l)}return{value:n,ele:i}},"max"),min:o(function(e,r){for(var n=1/0,i,a=this,s=0;s<a.length;s++){var l=a[s],u=r?e.apply(r,[l,s,a]):e(l,s,a);u<n&&(n=u,i=l)}return{value:n,ele:i}},"min")},Qr=Qme;Qr.u=Qr["|"]=Qr["+"]=Qr.union=Qr.or=Qr.add;Qr["\\"]=Qr["!"]=Qr["-"]=Qr.difference=Qr.relativeComplement=Qr.subtract=Qr.not;Qr.n=Qr["&"]=Qr["."]=Qr.and=Qr.intersection=Qr.intersect;Qr["^"]=Qr["(+)"]=Qr["(-)"]=Qr.symmetricDifference=Qr.symdiff=Qr.xor;Qr.fnFilter=Qr.filterFn=Qr.stdFilter=Qr.filter;Qr.complement=Qr.abscomp=Qr.absoluteComplement;OKe={isNode:o(function(){return this.group()==="nodes"},"isNode"),isEdge:o(function(){return this.group()==="edges"},"isEdge"),isLoop:o(function(){return this.isEdge()&&this.source()[0]===this.target()[0]},"isLoop"),isSimple:o(function(){return this.isEdge()&&this.source()[0]!==this.target()[0]},"isSimple"),group:o(function(){var e=this[0];if(e)return e._private.group},"group")},Zme=o(function(e,r){var n=e.cy(),i=n.hasCompoundNodes();function a(f){var d=f.pstyle("z-compound-depth");return d.value==="auto"?i?f.zDepth():0:d.value==="bottom"?-1:d.value==="top"?tB:0}o(a,"getDepth");var s=a(e)-a(r);if(s!==0)return s;function l(f){var d=f.pstyle("z-index-compare");return d.value==="auto"&&f.isNode()?1:0}o(l,"getEleDepth");var u=l(e)-l(r);if(u!==0)return u;var h=e.pstyle("z-index").value-r.pstyle("z-index").value;return h!==0?h:e.poolIndex()-r.poolIndex()},"zIndexSort"),ES={forEach:o(function(e,r){if(si(e))for(var n=this.length,i=0;i<n;i++){var a=this[i],s=r?e.apply(r,[a,i,this]):e(a,i,this);if(s===!1)break}return this},"forEach"),toArray:o(function(){for(var e=[],r=0;r<this.length;r++)e.push(this[r]);return e},"toArray"),slice:o(function(e,r){var n=[],i=this.length;r==null&&(r=i),e==null&&(e=0),e<0&&(e=i+e),r<0&&(r=i+r);for(var a=e;a>=0&&a<r&&a<i;a++)n.push(this[a]);return this.spawn(n)},"slice"),size:o(function(){return this.length},"size"),eq:o(function(e){return this[e]||this.spawn()},"eq"),first:o(function(){return this[0]||this.spawn()},"first"),last:o(function(){return this[this.length-1]||this.spawn()},"last"),empty:o(function(){return this.length===0},"empty"),nonempty:o(function(){return!this.empty()},"nonempty"),sort:o(function(e){if(!si(e))return this;var r=this.toArray().sort(e);return this.spawn(r)},"sort"),sortByZIndex:o(function(){return this.sort(Zme)},"sortByZIndex"),zDepth:o(function(){var e=this[0];if(e){var r=e._private,n=r.group;if(n==="nodes"){var i=r.data.parent?e.parents().size():0;return e.isParent()?i:tB-1}else{var a=r.source,s=r.target,l=a.zDepth(),u=s.zDepth();return Math.max(l,u,0)}}},"zDepth")};ES.each=ES.forEach;PKe=o(function(){var e="undefined",r=(typeof Symbol>"u"?"undefined":Wi(Symbol))!=e&&Wi(Symbol.iterator)!=e;r&&(ES[Symbol.iterator]=function(){var n=this,i={value:void 0,done:!1},a=0,s=this.length;return X0e({next:o(function(){return a<s?i.value=n[a++]:(i.value=void 0,i.done=!0),i},"next")},Symbol.iterator,function(){return this})})},"defineSymbolIterator");PKe();BKe=la({nodeDimensionsIncludeLabels:!1}),fS={layoutDimensions:o(function(e){e=BKe(e);var r;if(!this.takesUpSpace())r={w:0,h:0};else if(e.nodeDimensionsIncludeLabels){var n=this.boundingBox();r={w:n.w,h:n.h}}else r={w:this.outerWidth(),h:this.outerHeight()};return(r.w===0||r.h===0)&&(r.w=r.h=1),r},"layoutDimensions"),layoutPositions:o(function(e,r,n){var i=this.nodes().filter(function(T){return!T.isParent()}),a=this.cy(),s=r.eles,l=o(function(E){return E.id()},"getMemoizeKey"),u=Ub(n,l);e.emit({type:"layoutstart",layout:e}),e.animations=[];var h=o(function(E,A,S){var _={x:A.x1+A.w/2,y:A.y1+A.h/2},I={x:(S.x-_.x)*E,y:(S.y-_.y)*E};return{x:_.x+I.x,y:_.y+I.y}},"calculateSpacing"),f=r.spacingFactor&&r.spacingFactor!==1,d=o(function(){if(!f)return null;for(var E=Hs(),A=0;A<i.length;A++){var S=i[A],_=u(S,A);Fqe(E,_.x,_.y)}return E},"spacingBb"),p=d(),m=Ub(function(T,E){var A=u(T,E);if(f){var S=Math.abs(r.spacingFactor);A=h(S,p,A)}return r.transform!=null&&(A=r.transform(T,A)),A},l);if(r.animate){for(var g=0;g<i.length;g++){var y=i[g],v=m(y,g),x=r.animateFilter==null||r.animateFilter(y,g);if(x){var b=y.animation({position:v,duration:r.animationDuration,easing:r.animationEasing});e.animations.push(b)}else y.position(v)}if(r.fit){var w=a.animation({fit:{boundingBox:s.boundingBoxAt(m),padding:r.padding},duration:r.animationDuration,easing:r.animationEasing});e.animations.push(w)}else if(r.zoom!==void 0&&r.pan!==void 0){var C=a.animation({zoom:r.zoom,pan:r.pan,duration:r.animationDuration,easing:r.animationEasing});e.animations.push(C)}e.animations.forEach(function(T){return T.play()}),e.one("layoutready",r.ready),e.emit({type:"layoutready",layout:e}),ey.all(e.animations.map(function(T){return T.promise()})).then(function(){e.one("layoutstop",r.stop),e.emit({type:"layoutstop",layout:e})})}else i.positions(m),r.fit&&a.fit(r.eles,r.padding),r.zoom!=null&&a.zoom(r.zoom),r.pan&&a.pan(r.pan),e.one("layoutready",r.ready),e.emit({type:"layoutready",layout:e}),e.one("layoutstop",r.stop),e.emit({type:"layoutstop",layout:e});return this},"layoutPositions"),layout:o(function(e){var r=this.cy();return r.makeLayout(rr({},e,{eles:this}))},"layout")};fS.createLayout=fS.makeLayout=fS.layout;o(Jme,"styleCache");o(zS,"cacheStyleFunction");o(GS,"cachePrototypeStyleFunction");Ta={recalculateRenderedStyle:o(function(e){var r=this.cy(),n=r.renderer(),i=r.styleEnabled();return n&&i&&n.recalculateRenderedStyle(this,e),this},"recalculateRenderedStyle"),dirtyStyleCache:o(function(){var e=this.cy(),r=o(function(a){return a._private.styleCache=null},"dirty");if(e.hasCompoundNodes()){var n;n=this.spawnSelf().merge(this.descendants()).merge(this.parents()),n.merge(n.connectedEdges()),n.forEach(r)}else this.forEach(function(i){r(i),i.connectedEdges().forEach(r)});return this},"dirtyStyleCache"),updateStyle:o(function(e){var r=this._private.cy;if(!r.styleEnabled())return this;if(r.batching()){var n=r._private.batchStyleEles;return n.merge(this),this}var i=r.hasCompoundNodes(),a=this;e=!!(e||e===void 0),i&&(a=this.spawnSelf().merge(this.descendants()).merge(this.parents()));var s=a;return e?s.emitAndNotify("style"):s.emit("style"),a.forEach(function(l){return l._private.styleDirty=!0}),this},"updateStyle"),cleanStyle:o(function(){var e=this.cy();if(e.styleEnabled())for(var r=0;r<this.length;r++){var n=this[r];n._private.styleDirty&&(n._private.styleDirty=!1,e.style().apply(n))}},"cleanStyle"),parsedStyle:o(function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,n=this[0],i=n.cy();if(i.styleEnabled()&&n){n._private.styleDirty&&(n._private.styleDirty=!1,i.style().apply(n));var a=n._private.style[e];return a??(r?i.style().getDefaultProperty(e):null)}},"parsedStyle"),numericStyle:o(function(e){var r=this[0];if(r.cy().styleEnabled()&&r){var n=r.pstyle(e);return n.pfValue!==void 0?n.pfValue:n.value}},"numericStyle"),numericStyleUnits:o(function(e){var r=this[0];if(r.cy().styleEnabled()&&r)return r.pstyle(e).units},"numericStyleUnits"),renderedStyle:o(function(e){var r=this.cy();if(!r.styleEnabled())return this;var n=this[0];if(n)return r.style().getRenderedStyle(n,e)},"renderedStyle"),style:o(function(e,r){var n=this.cy();if(!n.styleEnabled())return this;var i=!1,a=n.style();if(Ur(e)){var s=e;a.applyBypass(this,s,i),this.emitAndNotify("style")}else if(Zt(e))if(r===void 0){var l=this[0];return l?a.getStylePropertyValue(l,e):void 0}else a.applyBypass(this,e,r,i),this.emitAndNotify("style");else if(e===void 0){var u=this[0];return u?a.getRawStyle(u):void 0}return this},"style"),removeStyle:o(function(e){var r=this.cy();if(!r.styleEnabled())return this;var n=!1,i=r.style(),a=this;if(e===void 0)for(var s=0;s<a.length;s++){var l=a[s];i.removeAllBypasses(l,n)}else{e=e.split(/\s+/);for(var u=0;u<a.length;u++){var h=a[u];i.removeBypasses(h,e,n)}}return this.emitAndNotify("style"),this},"removeStyle"),show:o(function(){return this.css("display","element"),this},"show"),hide:o(function(){return this.css("display","none"),this},"hide"),effectiveOpacity:o(function(){var e=this.cy();if(!e.styleEnabled())return 1;var r=e.hasCompoundNodes(),n=this[0];if(n){var i=n._private,a=n.pstyle("opacity").value;if(!r)return a;var s=i.data.parent?n.parents():null;if(s)for(var l=0;l<s.length;l++){var u=s[l],h=u.pstyle("opacity").value;a=h*a}return a}},"effectiveOpacity"),transparent:o(function(){var e=this.cy();if(!e.styleEnabled())return!1;var r=this[0],n=r.cy().hasCompoundNodes();if(r)return n?r.effectiveOpacity()===0:r.pstyle("opacity").value===0},"transparent"),backgrounding:o(function(){var e=this.cy();if(!e.styleEnabled())return!1;var r=this[0];return!!r._private.backgrounding},"backgrounding")};o(AP,"checkCompound");o(dB,"defineDerivedStateFunction");iy=zS("eleTakesUpSpace",function(t){return t.pstyle("display").value==="element"&&t.width()!==0&&(t.isNode()?t.height()!==0:!0)});Ta.takesUpSpace=GS("takesUpSpace",dB({ok:iy}));FKe=zS("eleInteractive",function(t){return t.pstyle("events").value==="yes"&&t.pstyle("visibility").value==="visible"&&iy(t)}),$Ke=zS("parentInteractive",function(t){return t.pstyle("visibility").value==="visible"&&iy(t)});Ta.interactive=GS("interactive",dB({ok:FKe,parentOk:$Ke,edgeOkViaNode:iy}));Ta.noninteractive=function(){var t=this[0];if(t)return!t.interactive()};zKe=zS("eleVisible",function(t){return t.pstyle("visibility").value==="visible"&&t.pstyle("opacity").pfValue!==0&&iy(t)}),GKe=iy;Ta.visible=GS("visible",dB({ok:zKe,edgeOkViaNode:GKe}));Ta.hidden=function(){var t=this[0];if(t)return!t.visible()};Ta.isBundledBezier=GS("isBundledBezier",function(){return this.cy().styleEnabled()?!this.removed()&&this.pstyle("curve-style").value==="bezier"&&this.takesUpSpace():!1});Ta.bypass=Ta.css=Ta.style;Ta.renderedCss=Ta.renderedStyle;Ta.removeBypass=Ta.removeCss=Ta.removeStyle;Ta.pstyle=Ta.parsedStyle;Cf={};o(f0e,"defineSwitchFunction");o(ay,"defineSwitchSet");ay({field:"locked",overrideField:o(function(e){return e.cy().autolock()?!0:void 0},"overrideField"),on:"lock",off:"unlock"});ay({field:"grabbable",overrideField:o(function(e){return e.cy().autoungrabify()||e.pannable()?!1:void 0},"overrideField"),on:"grabify",off:"ungrabify"});ay({field:"selected",ableField:"selectable",overrideAble:o(function(e){return e.cy().autounselectify()?!1:void 0},"overrideAble"),on:"select",off:"unselect"});ay({field:"selectable",overrideField:o(function(e){return e.cy().autounselectify()?!1:void 0},"overrideField"),on:"selectify",off:"unselectify"});Cf.deselect=Cf.unselect;Cf.grabbed=function(){var t=this[0];if(t)return t._private.grabbed};ay({field:"active",on:"activate",off:"unactivate"});ay({field:"pannable",on:"panify",off:"unpanify"});Cf.inactive=function(){var t=this[0];if(t)return!t._private.active};$a={},d0e=o(function(e){return o(function(n){for(var i=this,a=[],s=0;s<i.length;s++){var l=i[s];if(l.isNode()){for(var u=!1,h=l.connectedEdges(),f=0;f<h.length;f++){var d=h[f],p=d.source(),m=d.target();if(e.noIncomingEdges&&m===l&&p!==l||e.noOutgoingEdges&&p===l&&m!==l){u=!0;break}}u||a.push(l)}}return this.spawn(a,!0).filter(n)},"dagExtremityImpl")},"defineDagExtremity"),p0e=o(function(e){return function(r){for(var n=this,i=[],a=0;a<n.length;a++){var s=n[a];if(s.isNode())for(var l=s.connectedEdges(),u=0;u<l.length;u++){var h=l[u],f=h.source(),d=h.target();e.outgoing&&f===s?(i.push(h),i.push(d)):e.incoming&&d===s&&(i.push(h),i.push(f))}}return this.spawn(i,!0).filter(r)}},"defineDagOneHop"),m0e=o(function(e){return function(r){for(var n=this,i=[],a={};;){var s=e.outgoing?n.outgoers():n.incomers();if(s.length===0)break;for(var l=!1,u=0;u<s.length;u++){var h=s[u],f=h.id();a[f]||(a[f]=!0,i.push(h),l=!0)}if(!l)break;n=s}return this.spawn(i,!0).filter(r)}},"defineDagAllHops");$a.clearTraversalCache=function(){for(var t=0;t<this.length;t++)this[t]._private.traversalCache=null};rr($a,{roots:d0e({noIncomingEdges:!0}),leaves:d0e({noOutgoingEdges:!0}),outgoers:tl(p0e({outgoing:!0}),"outgoers"),successors:m0e({outgoing:!0}),incomers:tl(p0e({incoming:!0}),"incomers"),predecessors:m0e({incoming:!0})});rr($a,{neighborhood:tl(function(t){for(var e=[],r=this.nodes(),n=0;n<r.length;n++)for(var i=r[n],a=i.connectedEdges(),s=0;s<a.length;s++){var l=a[s],u=l.source(),h=l.target(),f=i===u?h:u;f.length>0&&e.push(f[0]),e.push(l[0])}return this.spawn(e,!0).filter(t)},"neighborhood"),closedNeighborhood:o(function(e){return this.neighborhood().add(this).filter(e)},"closedNeighborhood"),openNeighborhood:o(function(e){return this.neighborhood(e)},"openNeighborhood")});$a.neighbourhood=$a.neighborhood;$a.closedNeighbourhood=$a.closedNeighborhood;$a.openNeighbourhood=$a.openNeighborhood;rr($a,{source:tl(o(function(e){var r=this[0],n;return r&&(n=r._private.source||r.cy().collection()),n&&e?n.filter(e):n},"sourceImpl"),"source"),target:tl(o(function(e){var r=this[0],n;return r&&(n=r._private.target||r.cy().collection()),n&&e?n.filter(e):n},"targetImpl"),"target"),sources:g0e({attr:"source"}),targets:g0e({attr:"target"})});o(g0e,"defineSourceFunction");rr($a,{edgesWith:tl(y0e(),"edgesWith"),edgesTo:tl(y0e({thisIsSrc:!0}),"edgesTo")});o(y0e,"defineEdgesWithFunction");rr($a,{connectedEdges:tl(function(t){for(var e=[],r=this,n=0;n<r.length;n++){var i=r[n];if(i.isNode())for(var a=i._private.edges,s=0;s<a.length;s++){var l=a[s];e.push(l)}}return this.spawn(e,!0).filter(t)},"connectedEdges"),connectedNodes:tl(function(t){for(var e=[],r=this,n=0;n<r.length;n++){var i=r[n];i.isEdge()&&(e.push(i.source()[0]),e.push(i.target()[0]))}return this.spawn(e,!0).filter(t)},"connectedNodes"),parallelEdges:tl(v0e(),"parallelEdges"),codirectedEdges:tl(v0e({codirected:!0}),"codirectedEdges")});o(v0e,"defineParallelEdgesFunction");rr($a,{components:o(function(e){var r=this,n=r.cy(),i=n.collection(),a=e==null?r.nodes():e.nodes(),s=[];e!=null&&a.empty()&&(a=e.sources());var l=o(function(f,d){i.merge(f),a.unmerge(f),d.merge(f)},"visitInComponent");if(a.empty())return r.spawn();var u=o(function(){var f=n.collection();s.push(f);var d=a[0];l(d,f),r.bfs({directed:!1,roots:d,visit:o(function(m){return l(m,f)},"visit")}),f.forEach(function(p){p.connectedEdges().forEach(function(m){r.has(m)&&f.has(m.source())&&f.has(m.target())&&f.merge(m)})})},"_loop");do u();while(a.length>0);return s},"components"),component:o(function(){var e=this[0];return e.cy().mutableElements().components(e)[0]},"component")});$a.componentsOf=$a.components;ka=o(function(e,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(e===void 0){ai("A collection must have a reference to the core");return}var a=new Xc,s=!1;if(!r)r=[];else if(r.length>0&&Ur(r[0])&&!t4(r[0])){s=!0;for(var l=[],u=new J1,h=0,f=r.length;h<f;h++){var d=r[h];d.data==null&&(d.data={});var p=d.data;if(p.id==null)p.id=fme();else if(e.hasElementWithId(p.id)||u.has(p.id))continue;var m=new NS(e,d,!1);l.push(m),u.add(p.id)}r=l}this.length=0;for(var g=0,y=r.length;g<y;g++){var v=r[g][0];if(v!=null){var x=v._private.data.id;(!n||!a.has(x))&&(n&&a.set(x,{index:this.length,ele:v}),this[this.length]=v,this.length++)}}this._private={eles:this,cy:e,get map(){return this.lazyMap==null&&this.rebuildMap(),this.lazyMap},set map(b){this.lazyMap=b},rebuildMap:o(function(){for(var w=this.lazyMap=new Xc,C=this.eles,T=0;T<C.length;T++){var E=C[T];w.set(E.id(),{index:T,ele:E})}},"rebuildMap")},n&&(this._private.map=a),s&&!i&&this.restore()},"Collection"),Mn=NS.prototype=ka.prototype=Object.create(Array.prototype);Mn.instanceString=function(){return"collection"};Mn.spawn=function(t,e){return new ka(this.cy(),t,e)};Mn.spawnSelf=function(){return this.spawn(this)};Mn.cy=function(){return this._private.cy};Mn.renderer=function(){return this._private.cy.renderer()};Mn.element=function(){return this[0]};Mn.collection=function(){return Q0e(this)?this:new ka(this._private.cy,[this])};Mn.unique=function(){return new ka(this._private.cy,this,!0)};Mn.hasElementWithId=function(t){return t=""+t,this._private.map.has(t)};Mn.getElementById=function(t){t=""+t;var e=this._private.cy,r=this._private.map.get(t);return r?r.ele:new ka(e)};Mn.$id=Mn.getElementById;Mn.poolIndex=function(){var t=this._private.cy,e=t._private.elements,r=this[0]._private.data.id;return e._private.map.get(r).index};Mn.indexOf=function(t){var e=t[0]._private.data.id;return this._private.map.get(e).index};Mn.indexOfId=function(t){return t=""+t,this._private.map.get(t).index};Mn.json=function(t){var e=this.element(),r=this.cy();if(e==null&&t)return this;if(e!=null){var n=e._private;if(Ur(t)){if(r.startBatch(),t.data){e.data(t.data);var i=n.data;if(e.isEdge()){var a=!1,s={},l=t.data.source,u=t.data.target;l!=null&&l!=i.source&&(s.source=""+l,a=!0),u!=null&&u!=i.target&&(s.target=""+u,a=!0),a&&(e=e.move(s))}else{var h="parent"in t.data,f=t.data.parent;h&&(f!=null||i.parent!=null)&&f!=i.parent&&(f===void 0&&(f=null),f!=null&&(f=""+f),e=e.move({parent:f}))}}t.position&&e.position(t.position);var d=o(function(y,v,x){var b=t[y];b!=null&&b!==n[y]&&(b?e[v]():e[x]())},"checkSwitch");return d("removed","remove","restore"),d("selected","select","unselect"),d("selectable","selectify","unselectify"),d("locked","lock","unlock"),d("grabbable","grabify","ungrabify"),d("pannable","panify","unpanify"),t.classes!=null&&e.classes(t.classes),r.endBatch(),this}else if(t===void 0){var p={data:Yc(n.data),position:Yc(n.position),group:n.group,removed:n.removed,selected:n.selected,selectable:n.selectable,locked:n.locked,grabbable:n.grabbable,pannable:n.pannable,classes:null};p.classes="";var m=0;return n.classes.forEach(function(g){return p.classes+=m++===0?g:" "+g}),p}}};Mn.jsons=function(){for(var t=[],e=0;e<this.length;e++){var r=this[e],n=r.json();t.push(n)}return t};Mn.clone=function(){for(var t=this.cy(),e=[],r=0;r<this.length;r++){var n=this[r],i=n.json(),a=new NS(t,i,!1);e.push(a)}return new ka(t,e)};Mn.copy=Mn.clone;Mn.restore=function(){for(var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,r=this,n=r.cy(),i=n._private,a=[],s=[],l,u=0,h=r.length;u<h;u++){var f=r[u];e&&!f.removed()||(f.isNode()?a.push(f):s.push(f))}l=a.concat(s);var d,p=o(function(){l.splice(d,1),d--},"removeFromElements");for(d=0;d<l.length;d++){var m=l[d],g=m._private,y=g.data;if(m.clearTraversalCache(),!(!e&&!g.removed)){if(y.id===void 0)y.id=fme();else if(Ct(y.id))y.id=""+y.id;else if(Af(y.id)||!Zt(y.id)){ai("Can not create element with invalid string ID `"+y.id+"`"),p();continue}else if(n.hasElementWithId(y.id)){ai("Can not create second element with ID `"+y.id+"`"),p();continue}}var v=y.id;if(m.isNode()){var x=g.position;x.x==null&&(x.x=0),x.y==null&&(x.y=0)}if(m.isEdge()){for(var b=m,w=["source","target"],C=w.length,T=!1,E=0;E<C;E++){var A=w[E],S=y[A];Ct(S)&&(S=y[A]=""+y[A]),S==null||S===""?(ai("Can not create edge `"+v+"` with unspecified "+A),T=!0):n.hasElementWithId(S)||(ai("Can not create edge `"+v+"` with nonexistant "+A+" `"+S+"`"),T=!0)}if(T){p();continue}var _=n.getElementById(y.source),I=n.getElementById(y.target);_.same(I)?_._private.edges.push(b):(_._private.edges.push(b),I._private.edges.push(b)),b._private.source=_,b._private.target=I}g.map=new Xc,g.map.set(v,{ele:m,index:0}),g.removed=!1,e&&n.addToPool(m)}for(var D=0;D<a.length;D++){var k=a[D],L=k._private.data;Ct(L.parent)&&(L.parent=""+L.parent);var R=L.parent,O=R!=null;if(O||k._private.parent){var M=k._private.parent?n.collection().merge(k._private.parent):n.getElementById(R);if(M.empty())L.parent=void 0;else if(M[0].removed())un("Node added with missing parent, reference to parent removed"),L.parent=void 0,k._private.parent=null;else{for(var B=!1,F=M;!F.empty();){if(k.same(F)){B=!0,L.parent=void 0;break}F=F.parent()}B||(M[0]._private.children.push(k),k._private.parent=M[0],i.hasCompoundNodes=!0)}}}if(l.length>0){for(var P=l.length===r.length?r:new ka(n,l),z=0;z<P.length;z++){var $=P[z];$.isNode()||($.parallelEdges().clearTraversalCache(),$.source().clearTraversalCache(),$.target().clearTraversalCache())}var H;i.hasCompoundNodes?H=n.collection().merge(P).merge(P.connectedNodes()).merge(P.parent()):H=P,H.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(t),t?P.emitAndNotify("add"):e&&P.emit("add")}return r};Mn.removed=function(){var t=this[0];return t&&t._private.removed};Mn.inside=function(){var t=this[0];return t&&!t._private.removed};Mn.remove=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,r=this,n=[],i={},a=r._private.cy;function s(R){for(var O=R._private.edges,M=0;M<O.length;M++)u(O[M])}o(s,"addConnectedEdges");function l(R){for(var O=R._private.children,M=0;M<O.length;M++)u(O[M])}o(l,"addChildren");function u(R){var O=i[R.id()];e&&R.removed()||O||(i[R.id()]=!0,R.isNode()?(n.push(R),s(R),l(R)):n.unshift(R))}o(u,"add");for(var h=0,f=r.length;h<f;h++){var d=r[h];u(d)}function p(R,O){var M=R._private.edges;Df(M,O),R.clearTraversalCache()}o(p,"removeEdgeRef");function m(R){R.clearTraversalCache()}o(m,"removeParallelRef");var g=[];g.ids={};function y(R,O){O=O[0],R=R[0];var M=R._private.children,B=R.id();Df(M,O),O._private.parent=null,g.ids[B]||(g.ids[B]=!0,g.push(R))}o(y,"removeChildRef"),r.dirtyCompoundBoundsCache(),e&&a.removeFromPool(n);for(var v=0;v<n.length;v++){var x=n[v];if(x.isEdge()){var b=x.source()[0],w=x.target()[0];p(b,x),p(w,x);for(var C=x.parallelEdges(),T=0;T<C.length;T++){var E=C[T];m(E),E.isBundledBezier()&&E.dirtyBoundingBoxCache()}}else{var A=x.parent();A.length!==0&&y(A,x)}e&&(x._private.removed=!0)}var S=a._private.elements;a._private.hasCompoundNodes=!1;for(var _=0;_<S.length;_++){var I=S[_];if(I.isParent()){a._private.hasCompoundNodes=!0;break}}var D=new ka(this.cy(),n);D.size()>0&&(t?D.emitAndNotify("remove"):e&&D.emit("remove"));for(var k=0;k<g.length;k++){var L=g[k];(!e||!L.removed())&&L.updateStyle()}return D};Mn.move=function(t){var e=this._private.cy,r=this,n=!1,i=!1,a=o(function(g){return g==null?g:""+g},"toString");if(t.source!==void 0||t.target!==void 0){var s=a(t.source),l=a(t.target),u=s!=null&&e.hasElementWithId(s),h=l!=null&&e.hasElementWithId(l);(u||h)&&(e.batch(function(){r.remove(n,i),r.emitAndNotify("moveout");for(var m=0;m<r.length;m++){var g=r[m],y=g._private.data;g.isEdge()&&(u&&(y.source=s),h&&(y.target=l))}r.restore(n,i)}),r.emitAndNotify("move"))}else if(t.parent!==void 0){var f=a(t.parent),d=f===null||e.hasElementWithId(f);if(d){var p=f===null?void 0:f;e.batch(function(){var m=r.remove(n,i);m.emitAndNotify("moveout");for(var g=0;g<r.length;g++){var y=r[g],v=y._private.data;y.isNode()&&(v.parent=p)}m.restore(n,i)}),r.emitAndNotify("move")}}return this};[Sme,Zje,hS,Sf,Z1,pKe,FS,LKe,Kme,Qme,OKe,ES,fS,Ta,Cf,$a].forEach(function(t){rr(Mn,t)});VKe={add:o(function(e){var r,n=this;if(go(e)){var i=e;if(i._private.cy===n)r=i.restore();else{for(var a=[],s=0;s<i.length;s++){var l=i[s];a.push(l.json())}r=new ka(n,a)}}else if(En(e)){var u=e;r=new ka(n,u)}else if(Ur(e)&&(En(e.nodes)||En(e.edges))){for(var h=e,f=[],d=["nodes","edges"],p=0,m=d.length;p<m;p++){var g=d[p],y=h[g];if(En(y))for(var v=0,x=y.length;v<x;v++){var b=rr({group:g},y[v]);f.push(b)}}r=new ka(n,f)}else{var w=e;r=new NS(n,w).collection()}return r},"add"),remove:o(function(e){if(!go(e)){if(Zt(e)){var r=e;e=this.$(r)}}return e.remove()},"remove")};o(UKe,"generateCubicBezier");HKe=function(){function t(n){return-n.tension*n.x-n.friction*n.v}o(t,"springAccelerationForState");function e(n,i,a){var s={x:n.x+a.dx*i,v:n.v+a.dv*i,tension:n.tension,friction:n.friction};return{dx:s.v,dv:t(s)}}o(e,"springEvaluateStateWithDerivative");function r(n,i){var a={dx:n.v,dv:t(n)},s=e(n,i*.5,a),l=e(n,i*.5,s),u=e(n,i,l),h=1/6*(a.dx+2*(s.dx+l.dx)+u.dx),f=1/6*(a.dv+2*(s.dv+l.dv)+u.dv);return n.x=n.x+h*i,n.v=n.v+f*i,n}return o(r,"springIntegrateState"),o(function n(i,a,s){var l={x:-1,v:0,tension:null,friction:null},u=[0],h=0,f=1/1e4,d=16/1e3,p,m,g;for(i=parseFloat(i)||500,a=parseFloat(a)||20,s=s||null,l.tension=i,l.friction=a,p=s!==null,p?(h=n(i,a),m=h/s*d):m=d;g=r(g||l,m),u.push(1+g.x),h+=16,Math.abs(g.x)>f&&Math.abs(g.v)>f;);return p?function(y){return u[y*(u.length-1)|0]}:h},"springRK4Factory")}(),Nn=o(function(e,r,n,i){var a=UKe(e,r,n,i);return function(s,l,u){return s+(l-s)*a(u)}},"cubicBezier"),dS={linear:o(function(e,r,n){return e+(r-e)*n},"linear"),ease:Nn(.25,.1,.25,1),"ease-in":Nn(.42,0,1,1),"ease-out":Nn(0,0,.58,1),"ease-in-out":Nn(.42,0,.58,1),"ease-in-sine":Nn(.47,0,.745,.715),"ease-out-sine":Nn(.39,.575,.565,1),"ease-in-out-sine":Nn(.445,.05,.55,.95),"ease-in-quad":Nn(.55,.085,.68,.53),"ease-out-quad":Nn(.25,.46,.45,.94),"ease-in-out-quad":Nn(.455,.03,.515,.955),"ease-in-cubic":Nn(.55,.055,.675,.19),"ease-out-cubic":Nn(.215,.61,.355,1),"ease-in-out-cubic":Nn(.645,.045,.355,1),"ease-in-quart":Nn(.895,.03,.685,.22),"ease-out-quart":Nn(.165,.84,.44,1),"ease-in-out-quart":Nn(.77,0,.175,1),"ease-in-quint":Nn(.755,.05,.855,.06),"ease-out-quint":Nn(.23,1,.32,1),"ease-in-out-quint":Nn(.86,0,.07,1),"ease-in-expo":Nn(.95,.05,.795,.035),"ease-out-expo":Nn(.19,1,.22,1),"ease-in-out-expo":Nn(1,0,0,1),"ease-in-circ":Nn(.6,.04,.98,.335),"ease-out-circ":Nn(.075,.82,.165,1),"ease-in-out-circ":Nn(.785,.135,.15,.86),spring:o(function(e,r,n){if(n===0)return dS.linear;var i=HKe(e,r,n);return function(a,s,l){return a+(s-a)*i(l)}},"spring"),"cubic-bezier":Nn};o(x0e,"getEasedValue");o(b0e,"getValue");o($1,"ease");o(WKe,"step$1");o(Rb,"valid");o(qKe,"startAnimation");o(w0e,"stepAll");YKe={animate:cn.animate(),animation:cn.animation(),animated:cn.animated(),clearQueue:cn.clearQueue(),delay:cn.delay(),delayAnimation:cn.delayAnimation(),stop:cn.stop(),addToAnimationPool:o(function(e){var r=this;r.styleEnabled()&&r._private.aniEles.merge(e)},"addToAnimationPool"),stopAnimationLoop:o(function(){this._private.animationsRunning=!1},"stopAnimationLoop"),startAnimationLoop:o(function(){var e=this;if(e._private.animationsRunning=!0,!e.styleEnabled())return;function r(){e._private.animationsRunning&&xS(o(function(a){w0e(a,e),r()},"animationStep"))}o(r,"headlessStep");var n=e.renderer();n&&n.beforeRender?n.beforeRender(o(function(a,s){w0e(s,e)},"rendererAnimationStep"),n.beforeRenderPriorities.animations):r()},"startAnimationLoop")},XKe={qualifierCompare:o(function(e,r){return e==null||r==null?e==null&&r==null:e.sameText(r)},"qualifierCompare"),eventMatches:o(function(e,r,n){var i=r.qualifier;return i!=null?e!==n.target&&t4(n.target)&&i.matches(n.target):!0},"eventMatches"),addEventFields:o(function(e,r){r.cy=e,r.target=e},"addEventFields"),callbackContext:o(function(e,r,n){return r.qualifier!=null?n.target:e},"callbackContext")},iS=o(function(e){return Zt(e)?new Lf(e):e},"argSelector"),ege={createEmitter:o(function(){var e=this._private;return e.emitter||(e.emitter=new $S(XKe,this)),this},"createEmitter"),emitter:o(function(){return this._private.emitter},"emitter"),on:o(function(e,r,n){return this.emitter().on(e,iS(r),n),this},"on"),removeListener:o(function(e,r,n){return this.emitter().removeListener(e,iS(r),n),this},"removeListener"),removeAllListeners:o(function(){return this.emitter().removeAllListeners(),this},"removeAllListeners"),one:o(function(e,r,n){return this.emitter().one(e,iS(r),n),this},"one"),once:o(function(e,r,n){return this.emitter().one(e,iS(r),n),this},"once"),emit:o(function(e,r){return this.emitter().emit(e,r),this},"emit"),emitAndNotify:o(function(e,r){return this.emit(e),this.notify(e,r),this},"emitAndNotify")};cn.eventAliasesOn(ege);VP={png:o(function(e){var r=this._private.renderer;return e=e||{},r.png(e)},"png"),jpg:o(function(e){var r=this._private.renderer;return e=e||{},e.bg=e.bg||"#fff",r.jpg(e)},"jpg")};VP.jpeg=VP.jpg;pS={layout:o(function(e){var r=this;if(e==null){ai("Layout options must be specified to make a layout");return}if(e.name==null){ai("A `name` must be specified to make a layout");return}var n=e.name,i=r.extension("layout",n);if(i==null){ai("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?");return}var a;Zt(e.eles)?a=r.$(e.eles):a=e.eles!=null?e.eles:r.$();var s=new i(rr({},e,{cy:r,eles:a}));return s},"layout")};pS.createLayout=pS.makeLayout=pS.layout;jKe={notify:o(function(e,r){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var i=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();r!=null&&i.merge(r);return}if(n.notificationsEnabled){var a=this.renderer();this.destroyed()||!a||a.notify(e,r)}},"notify"),notifications:o(function(e){var r=this._private;return e===void 0?r.notificationsEnabled:(r.notificationsEnabled=!!e,this)},"notifications"),noNotifications:o(function(e){this.notifications(!1),e(),this.notifications(!0)},"noNotifications"),batching:o(function(){return this._private.batchCount>0},"batching"),startBatch:o(function(){var e=this._private;return e.batchCount==null&&(e.batchCount=0),e.batchCount===0&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},"startBatch"),endBatch:o(function(){var e=this._private;if(e.batchCount===0)return this;if(e.batchCount--,e.batchCount===0){e.batchStyleEles.updateStyle();var r=this.renderer();Object.keys(e.batchNotifications).forEach(function(n){var i=e.batchNotifications[n];i.empty()?r.notify(n):r.notify(n,i)})}return this},"endBatch"),batch:o(function(e){return this.startBatch(),e(),this.endBatch(),this},"batch"),batchData:o(function(e){var r=this;return this.batch(function(){for(var n=Object.keys(e),i=0;i<n.length;i++){var a=n[i],s=e[a],l=r.getElementById(a);l.data(s)}})},"batchData")},KKe=la({hideEdgesOnViewport:!1,textureOnViewport:!1,motionBlur:!1,motionBlurOpacity:.05,pixelRatio:void 0,desktopTapThreshold:4,touchTapThreshold:8,wheelSensitivity:1,debug:!1,showFps:!1,webgl:!1,webglDebug:!1,webglDebugShowAtlases:!1,webglTexSize:2048,webglTexRows:12,webglBatchSize:2048,webglTexPerBatch:14,webglBgColor:[255,255,255]}),UP={renderTo:o(function(e,r,n,i){var a=this._private.renderer;return a.renderTo(e,r,n,i),this},"renderTo"),renderer:o(function(){return this._private.renderer},"renderer"),forceRender:o(function(){return this.notify("draw"),this},"forceRender"),resize:o(function(){return this.invalidateSize(),this.emitAndNotify("resize"),this},"resize"),initRenderer:o(function(e){var r=this,n=r.extension("renderer",e.name);if(n==null){ai("Can not initialise: No such renderer `".concat(e.name,"` found. Did you forget to import it and `cytoscape.use()` it?"));return}e.wheelSensitivity!==void 0&&un("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");var i=KKe(e);i.cy=r,r._private.renderer=new n(i),this.notify("init")},"initRenderer"),destroyRenderer:o(function(){var e=this;e.notify("destroy");var r=e.container();if(r)for(r._cyreg=null;r.childNodes.length>0;)r.removeChild(r.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach(function(n){var i=n._private;i.rscratch={},i.rstyle={},i.animation.current=[],i.animation.queue=[]})},"destroyRenderer"),onRender:o(function(e){return this.on("render",e)},"onRender"),offRender:o(function(e){return this.off("render",e)},"offRender")};UP.invalidateDimensions=UP.resize;mS={collection:o(function(e,r){return Zt(e)?this.$(e):go(e)?e.collection():En(e)?(r||(r={}),new ka(this,e,r.unique,r.removed)):new ka(this)},"collection"),nodes:o(function(e){var r=this.$(function(n){return n.isNode()});return e?r.filter(e):r},"nodes"),edges:o(function(e){var r=this.$(function(n){return n.isEdge()});return e?r.filter(e):r},"edges"),$:o(function(e){var r=this._private.elements;return e?r.filter(e):r.spawnSelf()},"$"),mutableElements:o(function(){return this._private.elements},"mutableElements")};mS.elements=mS.filter=mS.$;Ga={},$b="t",QKe="f";Ga.apply=function(t){for(var e=this,r=e._private,n=r.cy,i=n.collection(),a=0;a<t.length;a++){var s=t[a],l=e.getContextMeta(s);if(!l.empty){var u=e.getContextStyle(l),h=e.applyContextStyle(l,u,s);s._private.appliedInitStyle?e.updateTransitions(s,h.diffProps):s._private.appliedInitStyle=!0;var f=e.updateStyleHints(s);f&&i.push(s)}}return i};Ga.getPropertiesDiff=function(t,e){var r=this,n=r._private.propDiffs=r._private.propDiffs||{},i=t+"-"+e,a=n[i];if(a)return a;for(var s=[],l={},u=0;u<r.length;u++){var h=r[u],f=t[u]===$b,d=e[u]===$b,p=f!==d,m=h.mappedProperties.length>0;if(p||d&&m){var g=void 0;p&&m||p?g=h.properties:m&&(g=h.mappedProperties);for(var y=0;y<g.length;y++){for(var v=g[y],x=v.name,b=!1,w=u+1;w<r.length;w++){var C=r[w],T=e[w]===$b;if(T&&(b=C.properties[v.name]!=null,b))break}!l[x]&&!b&&(l[x]=!0,s.push(x))}}}return n[i]=s,s};Ga.getContextMeta=function(t){for(var e=this,r="",n,i=t._private.styleCxtKey||"",a=0;a<e.length;a++){var s=e[a],l=s.selector&&s.selector.matches(t);l?r+=$b:r+=QKe}return n=e.getPropertiesDiff(i,r),t._private.styleCxtKey=r,{key:r,diffPropNames:n,empty:n.length===0}};Ga.getContextStyle=function(t){var e=t.key,r=this,n=this._private.contextStyles=this._private.contextStyles||{};if(n[e])return n[e];for(var i={_private:{key:e}},a=0;a<r.length;a++){var s=r[a],l=e[a]===$b;if(l)for(var u=0;u<s.properties.length;u++){var h=s.properties[u];i[h.name]=h}}return n[e]=i,i};Ga.applyContextStyle=function(t,e,r){for(var n=this,i=t.diffPropNames,a={},s=n.types,l=0;l<i.length;l++){var u=i[l],h=e[u],f=r.pstyle(u);if(!h)if(f)f.bypass?h={name:u,deleteBypassed:!0}:h={name:u,delete:!0};else continue;if(f!==h){if(h.mapped===s.fn&&f!=null&&f.mapping!=null&&f.mapping.value===h.value){var d=f.mapping,p=d.fnValue=h.value(r);if(p===d.prevFnValue)continue}var m=a[u]={prev:f};n.applyParsedProperty(r,h),m.next=r.pstyle(u),m.next&&m.next.bypass&&(m.next=m.next.bypassed)}}return{diffProps:a}};Ga.updateStyleHints=function(t){var e=t._private,r=this,n=r.propertyGroupNames,i=r.propertyGroupKeys,a=o(function(te,J,se){return r.getPropertiesHash(te,J,se)},"propHash"),s=e.styleKey;if(t.removed())return!1;var l=e.group==="nodes",u=t._private.style;n=Object.keys(u);for(var h=0;h<i.length;h++){var f=i[h];e.styleKeys[f]=[V1,Ob]}for(var d=o(function(te,J){return e.styleKeys[J][0]=Hb(te,e.styleKeys[J][0])},"updateGrKey1"),p=o(function(te,J){return e.styleKeys[J][1]=Wb(te,e.styleKeys[J][1])},"updateGrKey2"),m=o(function(te,J){d(te,J),p(te,J)},"updateGrKey"),g=o(function(te,J){for(var se=0;se<te.length;se++){var ue=te.charCodeAt(se);d(ue,J),p(ue,J)}},"updateGrKeyWStr"),y=2e9,v=o(function(te){return-128<te&&te<128&&Math.floor(te)!==te?y-(te*1024|0):te},"cleanNum"),x=0;x<n.length;x++){var b=n[x],w=u[b];if(w!=null){var C=this.properties[b],T=C.type,E=C.groupKey,A=void 0;C.hashOverride!=null?A=C.hashOverride(t,w):w.pfValue!=null&&(A=w.pfValue);var S=C.enums==null?w.value:null,_=A!=null,I=S!=null,D=_||I,k=w.units;if(T.number&&D&&!T.multiple){var L=_?A:S;m(v(L),E),!_&&k!=null&&g(k,E)}else g(w.strValue,E)}}for(var R=[V1,Ob],O=0;O<i.length;O++){var M=i[O],B=e.styleKeys[M];R[0]=Hb(B[0],R[0]),R[1]=Wb(B[1],R[1])}e.styleKey=rqe(R[0],R[1]);var F=e.styleKeys;e.labelDimsKey=wf(F.labelDimensions);var P=a(t,["label"],F.labelDimensions);if(e.labelKey=wf(P),e.labelStyleKey=wf(j6(F.commonLabel,P)),!l){var z=a(t,["source-label"],F.labelDimensions);e.sourceLabelKey=wf(z),e.sourceLabelStyleKey=wf(j6(F.commonLabel,z));var $=a(t,["target-label"],F.labelDimensions);e.targetLabelKey=wf($),e.targetLabelStyleKey=wf(j6(F.commonLabel,$))}if(l){var H=e.styleKeys,Q=H.nodeBody,j=H.nodeBorder,ie=H.nodeOutline,ne=H.backgroundImage,le=H.compound,he=H.pie,K=[Q,j,ie,ne,le,he].filter(function(X){return X!=null}).reduce(j6,[V1,Ob]);e.nodeKey=wf(K),e.hasPie=he!=null&&he[0]!==V1&&he[1]!==Ob}return s!==e.styleKey};Ga.clearStyleHints=function(t){var e=t._private;e.styleCxtKey="",e.styleKeys={},e.styleKey=null,e.labelKey=null,e.labelStyleKey=null,e.sourceLabelKey=null,e.sourceLabelStyleKey=null,e.targetLabelKey=null,e.targetLabelStyleKey=null,e.nodeKey=null,e.hasPie=null};Ga.applyParsedProperty=function(t,e){var r=this,n=e,i=t._private.style,a,s=r.types,l=r.properties[n.name].type,u=n.bypass,h=i[n.name],f=h&&h.bypass,d=t._private,p="mapping",m=o(function(Q){return Q==null?null:Q.pfValue!=null?Q.pfValue:Q.value},"getVal"),g=o(function(){var Q=m(h),j=m(n);r.checkTriggers(t,n.name,Q,j)},"checkTriggers");if(e.name==="curve-style"&&t.isEdge()&&(e.value!=="bezier"&&t.isLoop()||e.value==="haystack"&&(t.source().isParent()||t.target().isParent()))&&(n=e=this.parse(e.name,"bezier",u)),n.delete)return i[n.name]=void 0,g(),!0;if(n.deleteBypassed)return h?h.bypass?(h.bypassed=void 0,g(),!0):!1:(g(),!0);if(n.deleteBypass)return h?h.bypass?(i[n.name]=h.bypassed,g(),!0):!1:(g(),!0);var y=o(function(){un("Do not assign mappings to elements without corresponding data (i.e. ele `"+t.id()+"` has no mapping for property `"+n.name+"` with data field `"+n.field+"`); try a `["+n.field+"]` selector to limit scope to elements with `"+n.field+"` defined")},"printMappingErr");switch(n.mapped){case s.mapData:{for(var v=n.field.split("."),x=d.data,b=0;b<v.length&&x;b++){var w=v[b];x=x[w]}if(x==null)return y(),!1;var C;if(Ct(x)){var T=n.fieldMax-n.fieldMin;T===0?C=0:C=(x-n.fieldMin)/T}else return un("Do not use continuous mappers without specifying numeric data (i.e. `"+n.field+": "+x+"` for `"+t.id()+"` is non-numeric)"),!1;if(C<0?C=0:C>1&&(C=1),l.color){var E=n.valueMin[0],A=n.valueMax[0],S=n.valueMin[1],_=n.valueMax[1],I=n.valueMin[2],D=n.valueMax[2],k=n.valueMin[3]==null?1:n.valueMin[3],L=n.valueMax[3]==null?1:n.valueMax[3],R=[Math.round(E+(A-E)*C),Math.round(S+(_-S)*C),Math.round(I+(D-I)*C),Math.round(k+(L-k)*C)];a={bypass:n.bypass,name:n.name,value:R,strValue:"rgb("+R[0]+", "+R[1]+", "+R[2]+")"}}else if(l.number){var O=n.valueMin+(n.valueMax-n.valueMin)*C;a=this.parse(n.name,O,n.bypass,p)}else return!1;if(!a)return y(),!1;a.mapping=n,n=a;break}case s.data:{for(var M=n.field.split("."),B=d.data,F=0;F<M.length&&B;F++){var P=M[F];B=B[P]}if(B!=null&&(a=this.parse(n.name,B,n.bypass,p)),!a)return y(),!1;a.mapping=n,n=a;break}case s.fn:{var z=n.value,$=n.fnValue!=null?n.fnValue:z(t);if(n.prevFnValue=$,$==null)return un("Custom function mappers may not return null (i.e. `"+n.name+"` for ele `"+t.id()+"` is null)"),!1;if(a=this.parse(n.name,$,n.bypass,p),!a)return un("Custom function mappers may not return invalid values for the property type (i.e. `"+n.name+"` for ele `"+t.id()+"` is invalid)"),!1;a.mapping=Yc(n),n=a;break}case void 0:break;default:return!1}return u?(f?n.bypassed=h.bypassed:n.bypassed=h,i[n.name]=n):f?h.bypassed=n:i[n.name]=n,g(),!0};Ga.cleanElements=function(t,e){for(var r=0;r<t.length;r++){var n=t[r];if(this.clearStyleHints(n),n.dirtyCompoundBoundsCache(),n.dirtyBoundingBoxCache(),!e)n._private.style={};else for(var i=n._private.style,a=Object.keys(i),s=0;s<a.length;s++){var l=a[s],u=i[l];u!=null&&(u.bypass?u.bypassed=null:i[l]=null)}}};Ga.update=function(){var t=this._private.cy,e=t.mutableElements();e.updateStyle()};Ga.updateTransitions=function(t,e){var r=this,n=t._private,i=t.pstyle("transition-property").value,a=t.pstyle("transition-duration").pfValue,s=t.pstyle("transition-delay").pfValue;if(i.length>0&&a>0){for(var l={},u=!1,h=0;h<i.length;h++){var f=i[h],d=t.pstyle(f),p=e[f];if(p){var m=p.prev,g=m,y=p.next!=null?p.next:d,v=!1,x=void 0,b=1e-6;g&&(Ct(g.pfValue)&&Ct(y.pfValue)?(v=y.pfValue-g.pfValue,x=g.pfValue+b*v):Ct(g.value)&&Ct(y.value)?(v=y.value-g.value,x=g.value+b*v):En(g.value)&&En(y.value)&&(v=g.value[0]!==y.value[0]||g.value[1]!==y.value[1]||g.value[2]!==y.value[2],x=g.strValue),v&&(l[f]=y.strValue,this.applyBypass(t,f,x),u=!0))}}if(!u)return;n.transitioning=!0,new ey(function(w){s>0?t.delayAnimation(s).play().promise().then(w):w()}).then(function(){return t.animation({style:l,duration:a,easing:t.pstyle("transition-timing-function").value,queue:!1}).play().promise()}).then(function(){r.removeBypasses(t,i),t.emitAndNotify("style"),n.transitioning=!1})}else n.transitioning&&(this.removeBypasses(t,i),t.emitAndNotify("style"),n.transitioning=!1)};Ga.checkTrigger=function(t,e,r,n,i,a){var s=this.properties[e],l=i(s);l!=null&&l(r,n)&&a(s)};Ga.checkZOrderTrigger=function(t,e,r,n){var i=this;this.checkTrigger(t,e,r,n,function(a){return a.triggersZOrder},function(){i._private.cy.notify("zorder",t)})};Ga.checkBoundsTrigger=function(t,e,r,n){this.checkTrigger(t,e,r,n,function(i){return i.triggersBounds},function(i){t.dirtyCompoundBoundsCache(),t.dirtyBoundingBoxCache(),i.triggersBoundsOfParallelBeziers&&e==="curve-style"&&(r==="bezier"||n==="bezier")&&t.parallelEdges().forEach(function(a){a.dirtyBoundingBoxCache()}),i.triggersBoundsOfConnectedEdges&&e==="display"&&(r==="none"||n==="none")&&t.connectedEdges().forEach(function(a){a.dirtyBoundingBoxCache()})})};Ga.checkTriggers=function(t,e,r,n){t.dirtyStyleCache(),this.checkZOrderTrigger(t,e,r,n),this.checkBoundsTrigger(t,e,r,n)};s4={};s4.applyBypass=function(t,e,r,n){var i=this,a=[],s=!0;if(e==="*"||e==="**"){if(r!==void 0)for(var l=0;l<i.properties.length;l++){var u=i.properties[l],h=u.name,f=this.parse(h,r,!0);f&&a.push(f)}}else if(Zt(e)){var d=this.parse(e,r,!0);d&&a.push(d)}else if(Ur(e)){var p=e;n=r;for(var m=Object.keys(p),g=0;g<m.length;g++){var y=m[g],v=p[y];if(v===void 0&&(v=p[LS(y)]),v!==void 0){var x=this.parse(y,v,!0);x&&a.push(x)}}}else return!1;if(a.length===0)return!1;for(var b=!1,w=0;w<t.length;w++){for(var C=t[w],T={},E=void 0,A=0;A<a.length;A++){var S=a[A];if(n){var _=C.pstyle(S.name);E=T[S.name]={prev:_}}b=this.applyParsedProperty(C,Yc(S))||b,n&&(E.next=C.pstyle(S.name))}b&&this.updateStyleHints(C),n&&this.updateTransitions(C,T,s)}return b};s4.overrideBypass=function(t,e,r){e=eB(e);for(var n=0;n<t.length;n++){var i=t[n],a=i._private.style[e],s=this.properties[e].type,l=s.color,u=s.mutiple,h=a?a.pfValue!=null?a.pfValue:a.value:null;!a||!a.bypass?this.applyBypass(i,e,r):(a.value=r,a.pfValue!=null&&(a.pfValue=r),l?a.strValue="rgb("+r.join(",")+")":u?a.strValue=r.join(" "):a.strValue=""+r,this.updateStyleHints(i)),this.checkTriggers(i,e,h,r)}};s4.removeAllBypasses=function(t,e){return this.removeBypasses(t,this.propertyNames,e)};s4.removeBypasses=function(t,e,r){for(var n=!0,i=0;i<t.length;i++){for(var a=t[i],s={},l=0;l<e.length;l++){var u=e[l],h=this.properties[u],f=a.pstyle(h.name);if(!(!f||!f.bypass)){var d="",p=this.parse(u,d,!0),m=s[h.name]={prev:f};this.applyParsedProperty(a,p),m.next=a.pstyle(h.name)}}this.updateStyleHints(a),r&&this.updateTransitions(a,s,n)}};pB={};pB.getEmSizeInPixels=function(){var t=this.containerCss("font-size");return t!=null?parseFloat(t):1};pB.containerCss=function(t){var e=this._private.cy,r=e.container(),n=e.window();if(n&&r&&n.getComputedStyle)return n.getComputedStyle(r).getPropertyValue(t)};jc={};jc.getRenderedStyle=function(t,e){return e?this.getStylePropertyValue(t,e,!0):this.getRawStyle(t,!0)};jc.getRawStyle=function(t,e){var r=this;if(t=t[0],t){for(var n={},i=0;i<r.properties.length;i++){var a=r.properties[i],s=r.getStylePropertyValue(t,a.name,e);s!=null&&(n[a.name]=s,n[LS(a.name)]=s)}return n}};jc.getIndexedStyle=function(t,e,r,n){var i=t.pstyle(e)[r][n];return i??t.cy().style().getDefaultProperty(e)[r][0]};jc.getStylePropertyValue=function(t,e,r){var n=this;if(t=t[0],t){var i=n.properties[e];i.alias&&(i=i.pointsTo);var a=i.type,s=t.pstyle(i.name);if(s){var l=s.value,u=s.units,h=s.strValue;if(r&&a.number&&l!=null&&Ct(l)){var f=t.cy().zoom(),d=o(function(v){return v*f},"getRenderedValue"),p=o(function(v,x){return d(v)+x},"getValueStringWithUnits"),m=En(l),g=m?u.every(function(y){return y!=null}):u!=null;return g?m?l.map(function(y,v){return p(y,u[v])}).join(" "):p(l,u):m?l.map(function(y){return Zt(y)?y:""+d(y)}).join(" "):""+d(l)}else if(h!=null)return h}return null}};jc.getAnimationStartStyle=function(t,e){for(var r={},n=0;n<e.length;n++){var i=e[n],a=i.name,s=t.pstyle(a);s!==void 0&&(Ur(s)?s=this.parse(a,s.strValue):s=this.parse(a,s)),s&&(r[a]=s)}return r};jc.getPropsList=function(t){var e=this,r=[],n=t,i=e.properties;if(n)for(var a=Object.keys(n),s=0;s<a.length;s++){var l=a[s],u=n[l],h=i[l]||i[eB(l)],f=this.parse(h.name,u);f&&r.push(f)}return r};jc.getNonDefaultPropertiesHash=function(t,e,r){var n=r.slice(),i,a,s,l,u,h;for(u=0;u<e.length;u++)if(i=e[u],a=t.pstyle(i,!1),a!=null)if(a.pfValue!=null)n[0]=Hb(l,n[0]),n[1]=Wb(l,n[1]);else for(s=a.strValue,h=0;h<s.length;h++)l=s.charCodeAt(h),n[0]=Hb(l,n[0]),n[1]=Wb(l,n[1]);return n};jc.getPropertiesHash=jc.getNonDefaultPropertiesHash;VS={};VS.appendFromJson=function(t){for(var e=this,r=0;r<t.length;r++){var n=t[r],i=n.selector,a=n.style||n.css,s=Object.keys(a);e.selector(i);for(var l=0;l<s.length;l++){var u=s[l],h=a[u];e.css(u,h)}}return e};VS.fromJson=function(t){var e=this;return e.resetToDefault(),e.appendFromJson(t),e};VS.json=function(){for(var t=[],e=this.defaultLength;e<this.length;e++){for(var r=this[e],n=r.selector,i=r.properties,a={},s=0;s<i.length;s++){var l=i[s];a[l.name]=l.strValue}t.push({selector:n?n.toString():"core",style:a})}return t};mB={};mB.appendFromString=function(t){var e=this,r=this,n=""+t,i,a,s;n=n.replace(/[/][*](\s|.)+?[*][/]/g,"");function l(){n.length>i.length?n=n.substr(i.length):n=""}o(l,"removeSelAndBlockFromRemaining");function u(){a.length>s.length?a=a.substr(s.length):a=""}for(o(u,"removePropAndValFromRem");;){var h=n.match(/^\s*$/);if(h)break;var f=n.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!f){un("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+n);break}i=f[0];var d=f[1];if(d!=="core"){var p=new Lf(d);if(p.invalid){un("Skipping parsing of block: Invalid selector found in string stylesheet: "+d),l();continue}}var m=f[2],g=!1;a=m;for(var y=[];;){var v=a.match(/^\s*$/);if(v)break;var x=a.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!x){un("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+m),g=!0;break}s=x[0];var b=x[1],w=x[2],C=e.properties[b];if(!C){un("Skipping property: Invalid property name in: "+s),u();continue}var T=r.parse(b,w);if(!T){un("Skipping property: Invalid property definition in: "+s),u();continue}y.push({name:b,val:w}),u()}if(g){l();break}r.selector(d);for(var E=0;E<y.length;E++){var A=y[E];r.css(A.name,A.val)}l()}return r};mB.fromString=function(t){var e=this;return e.resetToDefault(),e.appendFromString(t),e};wa={};(function(){var t=Hi,e=sWe,r=lWe,n=cWe,i=uWe,a=o(function(K){return"^"+K+"\\s*\\(\\s*([\\w\\.]+)\\s*\\)$"},"data"),s=o(function(K){var X=t+"|\\w+|"+e+"|"+r+"|"+n+"|"+i;return"^"+K+"\\s*\\(([\\w\\.]+)\\s*\\,\\s*("+t+")\\s*\\,\\s*("+t+")\\s*,\\s*("+X+")\\s*\\,\\s*("+X+")\\)$"},"mapData"),l=[`^url\\s*\\(\\s*['"]?(.+?)['"]?\\s*\\)$`,"^(none)$","^(.+)$"];wa.types={time:{number:!0,min:0,units:"s|ms",implicitUnits:"ms"},percent:{number:!0,min:0,max:100,units:"%",implicitUnits:"%"},percentages:{number:!0,min:0,max:100,units:"%",implicitUnits:"%",multiple:!0},zeroOneNumber:{number:!0,min:0,max:1,unitless:!0},zeroOneNumbers:{number:!0,min:0,max:1,unitless:!0,multiple:!0},nOneOneNumber:{number:!0,min:-1,max:1,unitless:!0},nonNegativeInt:{number:!0,min:0,integer:!0,unitless:!0},nonNegativeNumber:{number:!0,min:0,unitless:!0},position:{enums:["parent","origin"]},nodeSize:{number:!0,min:0,enums:["label"]},number:{number:!0,unitless:!0},numbers:{number:!0,unitless:!0,multiple:!0},positiveNumber:{number:!0,unitless:!0,min:0,strictMin:!0},size:{number:!0,min:0},bidirectionalSize:{number:!0},bidirectionalSizeMaybePercent:{number:!0,allowPercent:!0},bidirectionalSizes:{number:!0,multiple:!0},sizeMaybePercent:{number:!0,min:0,allowPercent:!0},axisDirection:{enums:["horizontal","leftward","rightward","vertical","upward","downward","auto"]},paddingRelativeTo:{enums:["width","height","average","min","max"]},bgWH:{number:!0,min:0,allowPercent:!0,enums:["auto"],multiple:!0},bgPos:{number:!0,allowPercent:!0,multiple:!0},bgRelativeTo:{enums:["inner","include-padding"],multiple:!0},bgRepeat:{enums:["repeat","repeat-x","repeat-y","no-repeat"],multiple:!0},bgFit:{enums:["none","contain","cover"],multiple:!0},bgCrossOrigin:{enums:["anonymous","use-credentials","null"],multiple:!0},bgClip:{enums:["none","node"],multiple:!0},bgContainment:{enums:["inside","over"],multiple:!0},color:{color:!0},colors:{color:!0,multiple:!0},fill:{enums:["solid","linear-gradient","radial-gradient"]},bool:{enums:["yes","no"]},bools:{enums:["yes","no"],multiple:!0},lineStyle:{enums:["solid","dotted","dashed"]},lineCap:{enums:["butt","round","square"]},linePosition:{enums:["center","inside","outside"]},lineJoin:{enums:["round","bevel","miter"]},borderStyle:{enums:["solid","dotted","dashed","double"]},curveStyle:{enums:["bezier","unbundled-bezier","haystack","segments","straight","straight-triangle","taxi","round-segments","round-taxi"]},radiusType:{enums:["arc-radius","influence-radius"],multiple:!0},fontFamily:{regex:'^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$'},fontStyle:{enums:["italic","normal","oblique"]},fontWeight:{enums:["normal","bold","bolder","lighter","100","200","300","400","500","600","800","900",100,200,300,400,500,600,700,800,900]},textDecoration:{enums:["none","underline","overline","line-through"]},textTransform:{enums:["none","uppercase","lowercase"]},textWrap:{enums:["none","wrap","ellipsis"]},textOverflowWrap:{enums:["whitespace","anywhere"]},textBackgroundShape:{enums:["rectangle","roundrectangle","round-rectangle"]},nodeShape:{enums:["rectangle","roundrectangle","round-rectangle","cutrectangle","cut-rectangle","bottomroundrectangle","bottom-round-rectangle","barrel","ellipse","triangle","round-triangle","square","pentagon","round-pentagon","hexagon","round-hexagon","concavehexagon","concave-hexagon","heptagon","round-heptagon","octagon","round-octagon","tag","round-tag","star","diamond","round-diamond","vee","rhomboid","right-rhomboid","polygon"]},overlayShape:{enums:["roundrectangle","round-rectangle","ellipse"]},cornerRadius:{number:!0,min:0,units:"px|em",implicitUnits:"px",enums:["auto"]},compoundIncludeLabels:{enums:["include","exclude"]},arrowShape:{enums:["tee","triangle","triangle-tee","circle-triangle","triangle-cross","triangle-backcurve","vee","square","circle","diamond","chevron","none"]},arrowFill:{enums:["filled","hollow"]},arrowWidth:{number:!0,units:"%|px|em",implicitUnits:"px",enums:["match-line"]},display:{enums:["element","none"]},visibility:{enums:["hidden","visible"]},zCompoundDepth:{enums:["bottom","orphan","auto","top"]},zIndexCompare:{enums:["auto","manual"]},valign:{enums:["top","center","bottom"]},halign:{enums:["left","center","right"]},justification:{enums:["left","center","right","auto"]},text:{string:!0},data:{mapping:!0,regex:a("data")},layoutData:{mapping:!0,regex:a("layoutData")},scratch:{mapping:!0,regex:a("scratch")},mapData:{mapping:!0,regex:s("mapData")},mapLayoutData:{mapping:!0,regex:s("mapLayoutData")},mapScratch:{mapping:!0,regex:s("mapScratch")},fn:{mapping:!0,fn:!0},url:{regexes:l,singleRegexMatchValue:!0},urls:{regexes:l,singleRegexMatchValue:!0,multiple:!0},propList:{propList:!0},angle:{number:!0,units:"deg|rad",implicitUnits:"rad"},textRotation:{number:!0,units:"deg|rad",implicitUnits:"rad",enums:["none","autorotate"]},polygonPointList:{number:!0,multiple:!0,evenMultiple:!0,min:-1,max:1,unitless:!0},edgeDistances:{enums:["intersection","node-position","endpoints"]},edgeEndpoint:{number:!0,multiple:!0,units:"%|px|em|deg|rad",implicitUnits:"px",enums:["inside-to-node","outside-to-node","outside-to-node-or-label","outside-to-line","outside-to-line-or-label"],singleEnum:!0,validate:o(function(K,X){switch(K.length){case 2:return X[0]!=="deg"&&X[0]!=="rad"&&X[1]!=="deg"&&X[1]!=="rad";case 1:return Zt(K[0])||X[0]==="deg"||X[0]==="rad";default:return!1}},"validate")},easing:{regexes:["^(spring)\\s*\\(\\s*("+t+")\\s*,\\s*("+t+")\\s*\\)$","^(cubic-bezier)\\s*\\(\\s*("+t+")\\s*,\\s*("+t+")\\s*,\\s*("+t+")\\s*,\\s*("+t+")\\s*\\)$"],enums:["linear","ease","ease-in","ease-out","ease-in-out","ease-in-sine","ease-out-sine","ease-in-out-sine","ease-in-quad","ease-out-quad","ease-in-out-quad","ease-in-cubic","ease-out-cubic","ease-in-out-cubic","ease-in-quart","ease-out-quart","ease-in-out-quart","ease-in-quint","ease-out-quint","ease-in-out-quint","ease-in-expo","ease-out-expo","ease-in-out-expo","ease-in-circ","ease-out-circ","ease-in-out-circ"]},gradientDirection:{enums:["to-bottom","to-top","to-left","to-right","to-bottom-right","to-bottom-left","to-top-right","to-top-left","to-right-bottom","to-left-bottom","to-right-top","to-left-top"]},boundsExpansion:{number:!0,multiple:!0,min:0,validate:o(function(K){var X=K.length;return X===1||X===2||X===4},"validate")}};var u={zeroNonZero:o(function(K,X){return(K==null||X==null)&&K!==X||K==0&&X!=0?!0:K!=0&&X==0},"zeroNonZero"),any:o(function(K,X){return K!=X},"any"),emptyNonEmpty:o(function(K,X){var te=Af(K),J=Af(X);return te&&!J||!te&&J},"emptyNonEmpty")},h=wa.types,f=[{name:"label",type:h.text,triggersBounds:u.any,triggersZOrder:u.emptyNonEmpty},{name:"text-rotation",type:h.textRotation,triggersBounds:u.any},{name:"text-margin-x",type:h.bidirectionalSize,triggersBounds:u.any},{name:"text-margin-y",type:h.bidirectionalSize,triggersBounds:u.any}],d=[{name:"source-label",type:h.text,triggersBounds:u.any},{name:"source-text-rotation",type:h.textRotation,triggersBounds:u.any},{name:"source-text-margin-x",type:h.bidirectionalSize,triggersBounds:u.any},{name:"source-text-margin-y",type:h.bidirectionalSize,triggersBounds:u.any},{name:"source-text-offset",type:h.size,triggersBounds:u.any}],p=[{name:"target-label",type:h.text,triggersBounds:u.any},{name:"target-text-rotation",type:h.textRotation,triggersBounds:u.any},{name:"target-text-margin-x",type:h.bidirectionalSize,triggersBounds:u.any},{name:"target-text-margin-y",type:h.bidirectionalSize,triggersBounds:u.any},{name:"target-text-offset",type:h.size,triggersBounds:u.any}],m=[{name:"font-family",type:h.fontFamily,triggersBounds:u.any},{name:"font-style",type:h.fontStyle,triggersBounds:u.any},{name:"font-weight",type:h.fontWeight,triggersBounds:u.any},{name:"font-size",type:h.size,triggersBounds:u.any},{name:"text-transform",type:h.textTransform,triggersBounds:u.any},{name:"text-wrap",type:h.textWrap,triggersBounds:u.any},{name:"text-overflow-wrap",type:h.textOverflowWrap,triggersBounds:u.any},{name:"text-max-width",type:h.size,triggersBounds:u.any},{name:"text-outline-width",type:h.size,triggersBounds:u.any},{name:"line-height",type:h.positiveNumber,triggersBounds:u.any}],g=[{name:"text-valign",type:h.valign,triggersBounds:u.any},{name:"text-halign",type:h.halign,triggersBounds:u.any},{name:"color",type:h.color},{name:"text-outline-color",type:h.color},{name:"text-outline-opacity",type:h.zeroOneNumber},{name:"text-background-color",type:h.color},{name:"text-background-opacity",type:h.zeroOneNumber},{name:"text-background-padding",type:h.size,triggersBounds:u.any},{name:"text-border-opacity",type:h.zeroOneNumber},{name:"text-border-color",type:h.color},{name:"text-border-width",type:h.size,triggersBounds:u.any},{name:"text-border-style",type:h.borderStyle,triggersBounds:u.any},{name:"text-background-shape",type:h.textBackgroundShape,triggersBounds:u.any},{name:"text-justification",type:h.justification}],y=[{name:"events",type:h.bool,triggersZOrder:u.any},{name:"text-events",type:h.bool,triggersZOrder:u.any}],v=[{name:"display",type:h.display,triggersZOrder:u.any,triggersBounds:u.any,triggersBoundsOfConnectedEdges:!0},{name:"visibility",type:h.visibility,triggersZOrder:u.any},{name:"opacity",type:h.zeroOneNumber,triggersZOrder:u.zeroNonZero},{name:"text-opacity",type:h.zeroOneNumber},{name:"min-zoomed-font-size",type:h.size},{name:"z-compound-depth",type:h.zCompoundDepth,triggersZOrder:u.any},{name:"z-index-compare",type:h.zIndexCompare,triggersZOrder:u.any},{name:"z-index",type:h.number,triggersZOrder:u.any}],x=[{name:"overlay-padding",type:h.size,triggersBounds:u.any},{name:"overlay-color",type:h.color},{name:"overlay-opacity",type:h.zeroOneNumber,triggersBounds:u.zeroNonZero},{name:"overlay-shape",type:h.overlayShape,triggersBounds:u.any},{name:"overlay-corner-radius",type:h.cornerRadius}],b=[{name:"underlay-padding",type:h.size,triggersBounds:u.any},{name:"underlay-color",type:h.color},{name:"underlay-opacity",type:h.zeroOneNumber,triggersBounds:u.zeroNonZero},{name:"underlay-shape",type:h.overlayShape,triggersBounds:u.any},{name:"underlay-corner-radius",type:h.cornerRadius}],w=[{name:"transition-property",type:h.propList},{name:"transition-duration",type:h.time},{name:"transition-delay",type:h.time},{name:"transition-timing-function",type:h.easing}],C=o(function(K,X){return X.value==="label"?-K.poolIndex():X.pfValue},"nodeSizeHashOverride"),T=[{name:"height",type:h.nodeSize,triggersBounds:u.any,hashOverride:C},{name:"width",type:h.nodeSize,triggersBounds:u.any,hashOverride:C},{name:"shape",type:h.nodeShape,triggersBounds:u.any},{name:"shape-polygon-points",type:h.polygonPointList,triggersBounds:u.any},{name:"corner-radius",type:h.cornerRadius},{name:"background-color",type:h.color},{name:"background-fill",type:h.fill},{name:"background-opacity",type:h.zeroOneNumber},{name:"background-blacken",type:h.nOneOneNumber},{name:"background-gradient-stop-colors",type:h.colors},{name:"background-gradient-stop-positions",type:h.percentages},{name:"background-gradient-direction",type:h.gradientDirection},{name:"padding",type:h.sizeMaybePercent,triggersBounds:u.any},{name:"padding-relative-to",type:h.paddingRelativeTo,triggersBounds:u.any},{name:"bounds-expansion",type:h.boundsExpansion,triggersBounds:u.any}],E=[{name:"border-color",type:h.color},{name:"border-opacity",type:h.zeroOneNumber},{name:"border-width",type:h.size,triggersBounds:u.any},{name:"border-style",type:h.borderStyle},{name:"border-cap",type:h.lineCap},{name:"border-join",type:h.lineJoin},{name:"border-dash-pattern",type:h.numbers},{name:"border-dash-offset",type:h.number},{name:"border-position",type:h.linePosition}],A=[{name:"outline-color",type:h.color},{name:"outline-opacity",type:h.zeroOneNumber},{name:"outline-width",type:h.size,triggersBounds:u.any},{name:"outline-style",type:h.borderStyle},{name:"outline-offset",type:h.size,triggersBounds:u.any}],S=[{name:"background-image",type:h.urls},{name:"background-image-crossorigin",type:h.bgCrossOrigin},{name:"background-image-opacity",type:h.zeroOneNumbers},{name:"background-image-containment",type:h.bgContainment},{name:"background-image-smoothing",type:h.bools},{name:"background-position-x",type:h.bgPos},{name:"background-position-y",type:h.bgPos},{name:"background-width-relative-to",type:h.bgRelativeTo},{name:"background-height-relative-to",type:h.bgRelativeTo},{name:"background-repeat",type:h.bgRepeat},{name:"background-fit",type:h.bgFit},{name:"background-clip",type:h.bgClip},{name:"background-width",type:h.bgWH},{name:"background-height",type:h.bgWH},{name:"background-offset-x",type:h.bgPos},{name:"background-offset-y",type:h.bgPos}],_=[{name:"position",type:h.position,triggersBounds:u.any},{name:"compound-sizing-wrt-labels",type:h.compoundIncludeLabels,triggersBounds:u.any},{name:"min-width",type:h.size,triggersBounds:u.any},{name:"min-width-bias-left",type:h.sizeMaybePercent,triggersBounds:u.any},{name:"min-width-bias-right",type:h.sizeMaybePercent,triggersBounds:u.any},{name:"min-height",type:h.size,triggersBounds:u.any},{name:"min-height-bias-top",type:h.sizeMaybePercent,triggersBounds:u.any},{name:"min-height-bias-bottom",type:h.sizeMaybePercent,triggersBounds:u.any}],I=[{name:"line-style",type:h.lineStyle},{name:"line-color",type:h.color},{name:"line-fill",type:h.fill},{name:"line-cap",type:h.lineCap},{name:"line-opacity",type:h.zeroOneNumber},{name:"line-dash-pattern",type:h.numbers},{name:"line-dash-offset",type:h.number},{name:"line-outline-width",type:h.size},{name:"line-outline-color",type:h.color},{name:"line-gradient-stop-colors",type:h.colors},{name:"line-gradient-stop-positions",type:h.percentages},{name:"curve-style",type:h.curveStyle,triggersBounds:u.any,triggersBoundsOfParallelBeziers:!0},{name:"haystack-radius",type:h.zeroOneNumber,triggersBounds:u.any},{name:"source-endpoint",type:h.edgeEndpoint,triggersBounds:u.any},{name:"target-endpoint",type:h.edgeEndpoint,triggersBounds:u.any},{name:"control-point-step-size",type:h.size,triggersBounds:u.any},{name:"control-point-distances",type:h.bidirectionalSizes,triggersBounds:u.any},{name:"control-point-weights",type:h.numbers,triggersBounds:u.any},{name:"segment-distances",type:h.bidirectionalSizes,triggersBounds:u.any},{name:"segment-weights",type:h.numbers,triggersBounds:u.any},{name:"segment-radii",type:h.numbers,triggersBounds:u.any},{name:"radius-type",type:h.radiusType,triggersBounds:u.any},{name:"taxi-turn",type:h.bidirectionalSizeMaybePercent,triggersBounds:u.any},{name:"taxi-turn-min-distance",type:h.size,triggersBounds:u.any},{name:"taxi-direction",type:h.axisDirection,triggersBounds:u.any},{name:"taxi-radius",type:h.number,triggersBounds:u.any},{name:"edge-distances",type:h.edgeDistances,triggersBounds:u.any},{name:"arrow-scale",type:h.positiveNumber,triggersBounds:u.any},{name:"loop-direction",type:h.angle,triggersBounds:u.any},{name:"loop-sweep",type:h.angle,triggersBounds:u.any},{name:"source-distance-from-node",type:h.size,triggersBounds:u.any},{name:"target-distance-from-node",type:h.size,triggersBounds:u.any}],D=[{name:"ghost",type:h.bool,triggersBounds:u.any},{name:"ghost-offset-x",type:h.bidirectionalSize,triggersBounds:u.any},{name:"ghost-offset-y",type:h.bidirectionalSize,triggersBounds:u.any},{name:"ghost-opacity",type:h.zeroOneNumber}],k=[{name:"selection-box-color",type:h.color},{name:"selection-box-opacity",type:h.zeroOneNumber},{name:"selection-box-border-color",type:h.color},{name:"selection-box-border-width",type:h.size},{name:"active-bg-color",type:h.color},{name:"active-bg-opacity",type:h.zeroOneNumber},{name:"active-bg-size",type:h.size},{name:"outside-texture-bg-color",type:h.color},{name:"outside-texture-bg-opacity",type:h.zeroOneNumber}],L=[];wa.pieBackgroundN=16,L.push({name:"pie-size",type:h.sizeMaybePercent});for(var R=1;R<=wa.pieBackgroundN;R++)L.push({name:"pie-"+R+"-background-color",type:h.color}),L.push({name:"pie-"+R+"-background-size",type:h.percent}),L.push({name:"pie-"+R+"-background-opacity",type:h.zeroOneNumber});var O=[],M=wa.arrowPrefixes=["source","mid-source","target","mid-target"];[{name:"arrow-shape",type:h.arrowShape,triggersBounds:u.any},{name:"arrow-color",type:h.color},{name:"arrow-fill",type:h.arrowFill},{name:"arrow-width",type:h.arrowWidth}].forEach(function(he){M.forEach(function(K){var X=K+"-"+he.name,te=he.type,J=he.triggersBounds;O.push({name:X,type:te,triggersBounds:J})})},{});var B=wa.properties=[].concat(y,w,v,x,b,D,g,m,f,d,p,T,E,A,S,L,_,I,O,k),F=wa.propertyGroups={behavior:y,transition:w,visibility:v,overlay:x,underlay:b,ghost:D,commonLabel:g,labelDimensions:m,mainLabel:f,sourceLabel:d,targetLabel:p,nodeBody:T,nodeBorder:E,nodeOutline:A,backgroundImage:S,pie:L,compound:_,edgeLine:I,edgeArrow:O,core:k},P=wa.propertyGroupNames={},z=wa.propertyGroupKeys=Object.keys(F);z.forEach(function(he){P[he]=F[he].map(function(K){return K.name}),F[he].forEach(function(K){return K.groupKey=he})});var $=wa.aliases=[{name:"content",pointsTo:"label"},{name:"control-point-distance",pointsTo:"control-point-distances"},{name:"control-point-weight",pointsTo:"control-point-weights"},{name:"segment-distance",pointsTo:"segment-distances"},{name:"segment-weight",pointsTo:"segment-weights"},{name:"segment-radius",pointsTo:"segment-radii"},{name:"edge-text-rotation",pointsTo:"text-rotation"},{name:"padding-left",pointsTo:"padding"},{name:"padding-right",pointsTo:"padding"},{name:"padding-top",pointsTo:"padding"},{name:"padding-bottom",pointsTo:"padding"}];wa.propertyNames=B.map(function(he){return he.name});for(var H=0;H<B.length;H++){var Q=B[H];B[Q.name]=Q}for(var j=0;j<$.length;j++){var ie=$[j],ne=B[ie.pointsTo],le={name:ie.name,alias:!0,pointsTo:ne};B.push(le),B[ie.name]=le}})();wa.getDefaultProperty=function(t){return this.getDefaultProperties()[t]};wa.getDefaultProperties=function(){var t=this._private;if(t.defaultProperties!=null)return t.defaultProperties;for(var e=rr({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":30,"outside-texture-bg-color":"#000","outside-texture-bg-opacity":.125,events:"yes","text-events":"no","text-valign":"top","text-halign":"center","text-justification":"auto","line-height":1,color:"#000","text-outline-color":"#000","text-outline-width":0,"text-outline-opacity":1,"text-opacity":1,"text-decoration":"none","text-transform":"none","text-wrap":"none","text-overflow-wrap":"whitespace","text-max-width":9999,"text-background-color":"#000","text-background-opacity":0,"text-background-shape":"rectangle","text-background-padding":0,"text-border-opacity":0,"text-border-width":0,"text-border-style":"solid","text-border-color":"#000","font-family":"Helvetica Neue, Helvetica, sans-serif","font-style":"normal","font-weight":"normal","font-size":16,"min-zoomed-font-size":0,"text-rotation":"none","source-text-rotation":"none","target-text-rotation":"none",visibility:"visible",display:"element",opacity:1,"z-compound-depth":"auto","z-index-compare":"auto","z-index":0,label:"","text-margin-x":0,"text-margin-y":0,"source-label":"","source-text-offset":0,"source-text-margin-x":0,"source-text-margin-y":0,"target-label":"","target-text-offset":0,"target-text-margin-x":0,"target-text-margin-y":0,"overlay-opacity":0,"overlay-color":"#000","overlay-padding":10,"overlay-shape":"round-rectangle","overlay-corner-radius":"auto","underlay-opacity":0,"underlay-color":"#000","underlay-padding":10,"underlay-shape":"round-rectangle","underlay-corner-radius":"auto","transition-property":"none","transition-duration":0,"transition-delay":0,"transition-timing-function":"linear","background-blacken":0,"background-color":"#999","background-fill":"solid","background-opacity":1,"background-image":"none","background-image-crossorigin":"anonymous","background-image-opacity":1,"background-image-containment":"inside","background-image-smoothing":"yes","background-position-x":"50%","background-position-y":"50%","background-offset-x":0,"background-offset-y":0,"background-width-relative-to":"include-padding","background-height-relative-to":"include-padding","background-repeat":"no-repeat","background-fit":"none","background-clip":"node","background-width":"auto","background-height":"auto","border-color":"#000","border-opacity":1,"border-width":0,"border-style":"solid","border-dash-pattern":[4,2],"border-dash-offset":0,"border-cap":"butt","border-join":"miter","border-position":"center","outline-color":"#999","outline-opacity":1,"outline-width":0,"outline-offset":0,"outline-style":"solid",height:30,width:30,shape:"ellipse","shape-polygon-points":"-1, -1, 1, -1, 1, 1, -1, 1","corner-radius":"auto","bounds-expansion":0,"background-gradient-direction":"to-bottom","background-gradient-stop-colors":"#999","background-gradient-stop-positions":"0%",ghost:"no","ghost-offset-y":0,"ghost-offset-x":0,"ghost-opacity":0,padding:0,"padding-relative-to":"width",position:"origin","compound-sizing-wrt-labels":"include","min-width":0,"min-width-bias-left":0,"min-width-bias-right":0,"min-height":0,"min-height-bias-top":0,"min-height-bias-bottom":0},{"pie-size":"100%"},[{name:"pie-{{i}}-background-color",value:"black"},{name:"pie-{{i}}-background-size",value:"0%"},{name:"pie-{{i}}-background-opacity",value:1}].reduce(function(u,h){for(var f=1;f<=wa.pieBackgroundN;f++){var d=h.name.replace("{{i}}",f),p=h.value;u[d]=p}return u},{}),{"line-style":"solid","line-color":"#999","line-fill":"solid","line-cap":"butt","line-opacity":1,"line-outline-width":0,"line-outline-color":"#000","line-gradient-stop-colors":"#999","line-gradient-stop-positions":"0%","control-point-step-size":40,"control-point-weights":.5,"segment-weights":.5,"segment-distances":20,"segment-radii":15,"radius-type":"arc-radius","taxi-turn":"50%","taxi-radius":15,"taxi-turn-min-distance":10,"taxi-direction":"auto","edge-distances":"intersection","curve-style":"haystack","haystack-radius":0,"arrow-scale":1,"loop-direction":"-45deg","loop-sweep":"-90deg","source-distance-from-node":0,"target-distance-from-node":0,"source-endpoint":"outside-to-node","target-endpoint":"outside-to-node","line-dash-pattern":[6,3],"line-dash-offset":0},[{name:"arrow-shape",value:"none"},{name:"arrow-color",value:"#999"},{name:"arrow-fill",value:"filled"},{name:"arrow-width",value:1}].reduce(function(u,h){return wa.arrowPrefixes.forEach(function(f){var d=f+"-"+h.name,p=h.value;u[d]=p}),u},{})),r={},n=0;n<this.properties.length;n++){var i=this.properties[n];if(!i.pointsTo){var a=i.name,s=e[a],l=this.parse(a,s);r[a]=l}}return t.defaultProperties=r,t.defaultProperties};wa.addDefaultStylesheet=function(){this.selector(":parent").css({shape:"rectangle",padding:10,"background-color":"#eee","border-color":"#ccc","border-width":1}).selector("edge").css({width:3}).selector(":loop").css({"curve-style":"bezier"}).selector("edge:compound").css({"curve-style":"bezier","source-endpoint":"outside-to-line","target-endpoint":"outside-to-line"}).selector(":selected").css({"background-color":"#0169D9","line-color":"#0169D9","source-arrow-color":"#0169D9","target-arrow-color":"#0169D9","mid-source-arrow-color":"#0169D9","mid-target-arrow-color":"#0169D9"}).selector(":parent:selected").css({"background-color":"#CCE1F9","border-color":"#aec8e5"}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}),this.defaultLength=this.length};US={};US.parse=function(t,e,r,n){var i=this;if(si(e))return i.parseImplWarn(t,e,r,n);var a=n==="mapping"||n===!0||n===!1||n==null?"dontcare":n,s=r?"t":"f",l=""+e,u=cme(t,l,s,a),h=i.propCache=i.propCache||[],f;return(f=h[u])||(f=h[u]=i.parseImplWarn(t,e,r,n)),(r||n==="mapping")&&(f=Yc(f),f&&(f.value=Yc(f.value))),f};US.parseImplWarn=function(t,e,r,n){var i=this.parseImpl(t,e,r,n);return!i&&e!=null&&un("The style property `".concat(t,": ").concat(e,"` is invalid")),i&&(i.name==="width"||i.name==="height")&&e==="label"&&un("The style value of `label` is deprecated for `"+i.name+"`"),i};US.parseImpl=function(t,e,r,n){var i=this;t=eB(t);var a=i.properties[t],s=e,l=i.types;if(!a||e===void 0)return null;a.alias&&(a=a.pointsTo,t=a.name);var u=Zt(e);u&&(e=e.trim());var h=a.type;if(!h)return null;if(r&&(e===""||e===null))return{name:t,value:e,bypass:!0,deleteBypass:!0};if(si(e))return{name:t,value:e,strValue:"fn",mapped:l.fn,bypass:r};var f,d;if(!(!u||n||e.length<7||e[1]!=="a")){if(e.length>=7&&e[0]==="d"&&(f=new RegExp(l.data.regex).exec(e))){if(r)return!1;var p=l.data;return{name:t,value:f,strValue:""+e,mapped:p,field:f[1],bypass:r}}else if(e.length>=10&&e[0]==="m"&&(d=new RegExp(l.mapData.regex).exec(e))){if(r||h.multiple)return!1;var m=l.mapData;if(!(h.color||h.number))return!1;var g=this.parse(t,d[4]);if(!g||g.mapped)return!1;var y=this.parse(t,d[5]);if(!y||y.mapped)return!1;if(g.pfValue===y.pfValue||g.strValue===y.strValue)return un("`"+t+": "+e+"` is not a valid mapper because the output range is zero; converting to `"+t+": "+g.strValue+"`"),this.parse(t,g.strValue);if(h.color){var v=g.value,x=y.value,b=v[0]===x[0]&&v[1]===x[1]&&v[2]===x[2]&&(v[3]===x[3]||(v[3]==null||v[3]===1)&&(x[3]==null||x[3]===1));if(b)return!1}return{name:t,value:d,strValue:""+e,mapped:m,field:d[1],fieldMin:parseFloat(d[2]),fieldMax:parseFloat(d[3]),valueMin:g.value,valueMax:y.value,bypass:r}}}if(h.multiple&&n!=="multiple"){var w;if(u?w=e.split(/\s+/):En(e)?w=e:w=[e],h.evenMultiple&&w.length%2!==0)return null;for(var C=[],T=[],E=[],A="",S=!1,_=0;_<w.length;_++){var I=i.parse(t,w[_],r,"multiple");S=S||Zt(I.value),C.push(I.value),E.push(I.pfValue!=null?I.pfValue:I.value),T.push(I.units),A+=(_>0?" ":"")+I.strValue}return h.validate&&!h.validate(C,T)?null:h.singleEnum&&S?C.length===1&&Zt(C[0])?{name:t,value:C[0],strValue:C[0],bypass:r}:null:{name:t,value:C,pfValue:E,strValue:A,bypass:r,units:T}}var D=o(function(){for(var K=0;K<h.enums.length;K++){var X=h.enums[K];if(X===e)return{name:t,value:e,strValue:""+e,bypass:r}}return null},"checkEnums");if(h.number){var k,L="px";if(h.units&&(k=h.units),h.implicitUnits&&(L=h.implicitUnits),!h.unitless)if(u){var R="px|em"+(h.allowPercent?"|\\%":"");k&&(R=k);var O=e.match("^("+Hi+")("+R+")?$");O&&(e=O[1],k=O[2]||L)}else(!k||h.implicitUnits)&&(k=L);if(e=parseFloat(e),isNaN(e)&&h.enums===void 0)return null;if(isNaN(e)&&h.enums!==void 0)return e=s,D();if(h.integer&&!JHe(e)||h.min!==void 0&&(e<h.min||h.strictMin&&e===h.min)||h.max!==void 0&&(e>h.max||h.strictMax&&e===h.max))return null;var M={name:t,value:e,strValue:""+e+(k||""),units:k,bypass:r};return h.unitless||k!=="px"&&k!=="em"?M.pfValue=e:M.pfValue=k==="px"||!k?e:this.getEmSizeInPixels()*e,(k==="ms"||k==="s")&&(M.pfValue=k==="ms"?e:1e3*e),(k==="deg"||k==="rad")&&(M.pfValue=k==="rad"?e:Nqe(e)),k==="%"&&(M.pfValue=e/100),M}else if(h.propList){var B=[],F=""+e;if(F!=="none"){for(var P=F.split(/\s*,\s*|\s+/),z=0;z<P.length;z++){var $=P[z].trim();i.properties[$]?B.push($):un("`"+$+"` is not a valid property name")}if(B.length===0)return null}return{name:t,value:B,strValue:B.length===0?"none":B.join(" "),bypass:r}}else if(h.color){var H=tme(e);return H?{name:t,value:H,pfValue:H,strValue:"rgb("+H[0]+","+H[1]+","+H[2]+")",bypass:r}:null}else if(h.regex||h.regexes){if(h.enums){var Q=D();if(Q)return Q}for(var j=h.regexes?h.regexes:[h.regex],ie=0;ie<j.length;ie++){var ne=new RegExp(j[ie]),le=ne.exec(e);if(le)return{name:t,value:h.singleRegexMatchValue?le[1]:le,strValue:""+e,bypass:r}}return null}else return h.string?{name:t,value:""+e,strValue:""+e,bypass:r}:h.enums?D():null};Fa=o(function t(e){if(!(this instanceof t))return new t(e);if(!JP(e)){ai("A style must have a core reference");return}this._private={cy:e,coreStyle:{}},this.length=0,this.resetToDefault()},"Style"),za=Fa.prototype;za.instanceString=function(){return"style"};za.clear=function(){for(var t=this._private,e=t.cy,r=e.elements(),n=0;n<this.length;n++)this[n]=void 0;return this.length=0,t.contextStyles={},t.propDiffs={},this.cleanElements(r,!0),r.forEach(function(i){var a=i[0]._private;a.styleDirty=!0,a.appliedInitStyle=!1}),this};za.resetToDefault=function(){return this.clear(),this.addDefaultStylesheet(),this};za.core=function(t){return this._private.coreStyle[t]||this.getDefaultProperty(t)};za.selector=function(t){var e=t==="core"?null:new Lf(t),r=this.length++;return this[r]={selector:e,properties:[],mappedProperties:[],index:r},this};za.css=function(){var t=this,e=arguments;if(e.length===1)for(var r=e[0],n=0;n<t.properties.length;n++){var i=t.properties[n],a=r[i.name];a===void 0&&(a=r[LS(i.name)]),a!==void 0&&this.cssRule(i.name,a)}else e.length===2&&this.cssRule(e[0],e[1]);return this};za.style=za.css;za.cssRule=function(t,e){var r=this.parse(t,e);if(r){var n=this.length-1;this[n].properties.push(r),this[n].properties[r.name]=r,r.name.match(/pie-(\d+)-background-size/)&&r.value&&(this._private.hasPie=!0),r.mapped&&this[n].mappedProperties.push(r);var i=!this[n].selector;i&&(this._private.coreStyle[r.name]=r)}return this};za.append=function(t){return Z0e(t)?t.appendToStyle(this):En(t)?this.appendFromJson(t):Zt(t)&&this.appendFromString(t),this};Fa.fromJson=function(t,e){var r=new Fa(t);return r.fromJson(e),r};Fa.fromString=function(t,e){return new Fa(t).fromString(e)};[Ga,s4,pB,jc,VS,mB,wa,US].forEach(function(t){rr(za,t)});Fa.types=za.types;Fa.properties=za.properties;Fa.propertyGroups=za.propertyGroups;Fa.propertyGroupNames=za.propertyGroupNames;Fa.propertyGroupKeys=za.propertyGroupKeys;ZKe={style:o(function(e){if(e){var r=this.setStyle(e);r.update()}return this._private.style},"style"),setStyle:o(function(e){var r=this._private;return Z0e(e)?r.style=e.generateStyle(this):En(e)?r.style=Fa.fromJson(this,e):Zt(e)?r.style=Fa.fromString(this,e):r.style=Fa(this),r.style},"setStyle"),updateStyle:o(function(){this.mutableElements().updateStyle()},"updateStyle")},JKe="single",Hp={autolock:o(function(e){if(e!==void 0)this._private.autolock=!!e;else return this._private.autolock;return this},"autolock"),autoungrabify:o(function(e){if(e!==void 0)this._private.autoungrabify=!!e;else return this._private.autoungrabify;return this},"autoungrabify"),autounselectify:o(function(e){if(e!==void 0)this._private.autounselectify=!!e;else return this._private.autounselectify;return this},"autounselectify"),selectionType:o(function(e){var r=this._private;if(r.selectionType==null&&(r.selectionType=JKe),e!==void 0)(e==="additive"||e==="single")&&(r.selectionType=e);else return r.selectionType;return this},"selectionType"),panningEnabled:o(function(e){if(e!==void 0)this._private.panningEnabled=!!e;else return this._private.panningEnabled;return this},"panningEnabled"),userPanningEnabled:o(function(e){if(e!==void 0)this._private.userPanningEnabled=!!e;else return this._private.userPanningEnabled;return this},"userPanningEnabled"),zoomingEnabled:o(function(e){if(e!==void 0)this._private.zoomingEnabled=!!e;else return this._private.zoomingEnabled;return this},"zoomingEnabled"),userZoomingEnabled:o(function(e){if(e!==void 0)this._private.userZoomingEnabled=!!e;else return this._private.userZoomingEnabled;return this},"userZoomingEnabled"),boxSelectionEnabled:o(function(e){if(e!==void 0)this._private.boxSelectionEnabled=!!e;else return this._private.boxSelectionEnabled;return this},"boxSelectionEnabled"),pan:o(function(){var e=arguments,r=this._private.pan,n,i,a,s,l;switch(e.length){case 0:return r;case 1:if(Zt(e[0]))return n=e[0],r[n];if(Ur(e[0])){if(!this._private.panningEnabled)return this;a=e[0],s=a.x,l=a.y,Ct(s)&&(r.x=s),Ct(l)&&(r.y=l),this.emit("pan viewport")}break;case 2:if(!this._private.panningEnabled)return this;n=e[0],i=e[1],(n==="x"||n==="y")&&Ct(i)&&(r[n]=i),this.emit("pan viewport");break}return this.notify("viewport"),this},"pan"),panBy:o(function(e,r){var n=arguments,i=this._private.pan,a,s,l,u,h;if(!this._private.panningEnabled)return this;switch(n.length){case 1:Ur(e)&&(l=n[0],u=l.x,h=l.y,Ct(u)&&(i.x+=u),Ct(h)&&(i.y+=h),this.emit("pan viewport"));break;case 2:a=e,s=r,(a==="x"||a==="y")&&Ct(s)&&(i[a]+=s),this.emit("pan viewport");break}return this.notify("viewport"),this},"panBy"),gc:o(function(){this.notify("gc")},"gc"),fit:o(function(e,r){var n=this.getFitViewport(e,r);if(n){var i=this._private;i.zoom=n.zoom,i.pan=n.pan,this.emit("pan zoom viewport"),this.notify("viewport")}return this},"fit"),getFitViewport:o(function(e,r){if(Ct(e)&&r===void 0&&(r=e,e=void 0),!(!this._private.panningEnabled||!this._private.zoomingEnabled)){var n;if(Zt(e)){var i=e;e=this.$(i)}else if(rWe(e)){var a=e;n={x1:a.x1,y1:a.y1,x2:a.x2,y2:a.y2},n.w=n.x2-n.x1,n.h=n.y2-n.y1}else go(e)||(e=this.mutableElements());if(!(go(e)&&e.empty())){n=n||e.boundingBox();var s=this.width(),l=this.height(),u;if(r=Ct(r)?r:0,!isNaN(s)&&!isNaN(l)&&s>0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0){u=Math.min((s-2*r)/n.w,(l-2*r)/n.h),u=u>this._private.maxZoom?this._private.maxZoom:u,u=u<this._private.minZoom?this._private.minZoom:u;var h={x:(s-u*(n.x1+n.x2))/2,y:(l-u*(n.y1+n.y2))/2};return{zoom:u,pan:h}}}}},"getFitViewport"),zoomRange:o(function(e,r){var n=this._private;if(r==null){var i=e;e=i.min,r=i.max}return Ct(e)&&Ct(r)&&e<=r?(n.minZoom=e,n.maxZoom=r):Ct(e)&&r===void 0&&e<=n.maxZoom?n.minZoom=e:Ct(r)&&e===void 0&&r>=n.minZoom&&(n.maxZoom=r),this},"zoomRange"),minZoom:o(function(e){return e===void 0?this._private.minZoom:this.zoomRange({min:e})},"minZoom"),maxZoom:o(function(e){return e===void 0?this._private.maxZoom:this.zoomRange({max:e})},"maxZoom"),getZoomedViewport:o(function(e){var r=this._private,n=r.pan,i=r.zoom,a,s,l=!1;if(r.zoomingEnabled||(l=!0),Ct(e)?s=e:Ur(e)&&(s=e.level,e.position!=null?a=MS(e.position,i,n):e.renderedPosition!=null&&(a=e.renderedPosition),a!=null&&!r.panningEnabled&&(l=!0)),s=s>r.maxZoom?r.maxZoom:s,s=s<r.minZoom?r.minZoom:s,l||!Ct(s)||s===i||a!=null&&(!Ct(a.x)||!Ct(a.y)))return null;if(a!=null){var u=n,h=i,f=s,d={x:-f/h*(a.x-u.x)+a.x,y:-f/h*(a.y-u.y)+a.y};return{zoomed:!0,panned:!0,zoom:f,pan:d}}else return{zoomed:!0,panned:!1,zoom:s,pan:n}},"getZoomedViewport"),zoom:o(function(e){if(e===void 0)return this._private.zoom;var r=this.getZoomedViewport(e),n=this._private;return r==null||!r.zoomed?this:(n.zoom=r.zoom,r.panned&&(n.pan.x=r.pan.x,n.pan.y=r.pan.y),this.emit("zoom"+(r.panned?" pan":"")+" viewport"),this.notify("viewport"),this)},"zoom"),viewport:o(function(e){var r=this._private,n=!0,i=!0,a=[],s=!1,l=!1;if(!e)return this;if(Ct(e.zoom)||(n=!1),Ur(e.pan)||(i=!1),!n&&!i)return this;if(n){var u=e.zoom;u<r.minZoom||u>r.maxZoom||!r.zoomingEnabled?s=!0:(r.zoom=u,a.push("zoom"))}if(i&&(!s||!e.cancelOnFailedZoom)&&r.panningEnabled){var h=e.pan;Ct(h.x)&&(r.pan.x=h.x,l=!1),Ct(h.y)&&(r.pan.y=h.y,l=!1),l||a.push("pan")}return a.length>0&&(a.push("viewport"),this.emit(a.join(" ")),this.notify("viewport")),this},"viewport"),center:o(function(e){var r=this.getCenterPan(e);return r&&(this._private.pan=r,this.emit("pan viewport"),this.notify("viewport")),this},"center"),getCenterPan:o(function(e,r){if(this._private.panningEnabled){if(Zt(e)){var n=e;e=this.mutableElements().filter(n)}else go(e)||(e=this.mutableElements());if(e.length!==0){var i=e.boundingBox(),a=this.width(),s=this.height();r=r===void 0?this._private.zoom:r;var l={x:(a-r*(i.x1+i.x2))/2,y:(s-r*(i.y1+i.y2))/2};return l}}},"getCenterPan"),reset:o(function(){return!this._private.panningEnabled||!this._private.zoomingEnabled?this:(this.viewport({pan:{x:0,y:0},zoom:1}),this)},"reset"),invalidateSize:o(function(){this._private.sizeCache=null},"invalidateSize"),size:o(function(){var e=this._private,r=e.container,n=this;return e.sizeCache=e.sizeCache||(r?function(){var i=n.window().getComputedStyle(r),a=o(function(l){return parseFloat(i.getPropertyValue(l))},"val");return{width:r.clientWidth-a("padding-left")-a("padding-right"),height:r.clientHeight-a("padding-top")-a("padding-bottom")}}():{width:1,height:1})},"size"),width:o(function(){return this.size().width},"width"),height:o(function(){return this.size().height},"height"),extent:o(function(){var e=this._private.pan,r=this._private.zoom,n=this.renderedExtent(),i={x1:(n.x1-e.x)/r,x2:(n.x2-e.x)/r,y1:(n.y1-e.y)/r,y2:(n.y2-e.y)/r};return i.w=i.x2-i.x1,i.h=i.y2-i.y1,i},"extent"),renderedExtent:o(function(){var e=this.width(),r=this.height();return{x1:0,y1:0,x2:e,y2:r,w:e,h:r}},"renderedExtent"),multiClickDebounceTime:o(function(e){if(e)this._private.multiClickDebounceTime=e;else return this._private.multiClickDebounceTime;return this},"multiClickDebounceTime")};Hp.centre=Hp.center;Hp.autolockNodes=Hp.autolock;Hp.autoungrabifyNodes=Hp.autoungrabify;Zb={data:cn.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:cn.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:cn.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:cn.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};Zb.attr=Zb.data;Zb.removeAttr=Zb.removeData;Jb=o(function(e){var r=this;e=rr({},e);var n=e.container;n&&!vS(n)&&vS(n[0])&&(n=n[0]);var i=n?n._cyreg:null;i=i||{},i&&i.cy&&(i.cy.destroy(),i={});var a=i.readies=i.readies||[];n&&(n._cyreg=i),i.cy=r;var s=Ui!==void 0&&n!==void 0&&!e.headless,l=e;l.layout=rr({name:s?"grid":"null"},l.layout),l.renderer=rr({name:s?"canvas":"null"},l.renderer);var u=o(function(g,y,v){return y!==void 0?y:v!==void 0?v:g},"defVal"),h=this._private={container:n,ready:!1,options:l,elements:new ka(this),listeners:[],aniEles:new ka(this),data:l.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:u(!0,l.zoomingEnabled),userZoomingEnabled:u(!0,l.userZoomingEnabled),panningEnabled:u(!0,l.panningEnabled),userPanningEnabled:u(!0,l.userPanningEnabled),boxSelectionEnabled:u(!0,l.boxSelectionEnabled),autolock:u(!1,l.autolock,l.autolockNodes),autoungrabify:u(!1,l.autoungrabify,l.autoungrabifyNodes),autounselectify:u(!1,l.autounselectify),styleEnabled:l.styleEnabled===void 0?s:l.styleEnabled,zoom:Ct(l.zoom)?l.zoom:1,pan:{x:Ur(l.pan)&&Ct(l.pan.x)?l.pan.x:0,y:Ur(l.pan)&&Ct(l.pan.y)?l.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:u(250,l.multiClickDebounceTime)};this.createEmitter(),this.selectionType(l.selectionType),this.zoomRange({min:l.minZoom,max:l.maxZoom});var f=o(function(g,y){var v=g.some(nWe);if(v)return ey.all(g).then(y);y(g)},"loadExtData");h.styleEnabled&&r.setStyle([]);var d=rr({},l,l.renderer);r.initRenderer(d);var p=o(function(g,y,v){r.notifications(!1);var x=r.mutableElements();x.length>0&&x.remove(),g!=null&&(Ur(g)||En(g))&&r.add(g),r.one("layoutready",function(w){r.notifications(!0),r.emit(w),r.one("load",y),r.emitAndNotify("load")}).one("layoutstop",function(){r.one("done",v),r.emit("done")});var b=rr({},r._private.options.layout);b.eles=r.elements(),r.layout(b).run()},"setElesAndLayout");f([l.style,l.elements],function(m){var g=m[0],y=m[1];h.styleEnabled&&r.style().append(g),p(y,function(){r.startAnimationLoop(),h.ready=!0,si(l.ready)&&r.on("ready",l.ready);for(var v=0;v<a.length;v++){var x=a[v];r.on("ready",x)}i&&(i.readies=[]),r.emit("ready")},l.done)})},"Core"),SS=Jb.prototype;rr(SS,{instanceString:o(function(){return"core"},"instanceString"),isReady:o(function(){return this._private.ready},"isReady"),destroyed:o(function(){return this._private.destroyed},"destroyed"),ready:o(function(e){return this.isReady()?this.emitter().emit("ready",[],e):this.on("ready",e),this},"ready"),destroy:o(function(){var e=this;if(!e.destroyed())return e.stopAnimationLoop(),e.destroyRenderer(),this.emit("destroy"),e._private.destroyed=!0,e},"destroy"),hasElementWithId:o(function(e){return this._private.elements.hasElementWithId(e)},"hasElementWithId"),getElementById:o(function(e){return this._private.elements.getElementById(e)},"getElementById"),hasCompoundNodes:o(function(){return this._private.hasCompoundNodes},"hasCompoundNodes"),headless:o(function(){return this._private.renderer.isHeadless()},"headless"),styleEnabled:o(function(){return this._private.styleEnabled},"styleEnabled"),addToPool:o(function(e){return this._private.elements.merge(e),this},"addToPool"),removeFromPool:o(function(e){return this._private.elements.unmerge(e),this},"removeFromPool"),container:o(function(){return this._private.container||null},"container"),window:o(function(){var e=this._private.container;if(e==null)return Ui;var r=this._private.container.ownerDocument;return r===void 0||r==null?Ui:r.defaultView||Ui},"window"),mount:o(function(e){if(e!=null){var r=this,n=r._private,i=n.options;return!vS(e)&&vS(e[0])&&(e=e[0]),r.stopAnimationLoop(),r.destroyRenderer(),n.container=e,n.styleEnabled=!0,r.invalidateSize(),r.initRenderer(rr({},i,i.renderer,{name:i.renderer.name==="null"?"canvas":i.renderer.name})),r.startAnimationLoop(),r.style(i.style),r.emit("mount"),r}},"mount"),unmount:o(function(){var e=this;return e.stopAnimationLoop(),e.destroyRenderer(),e.initRenderer({name:"null"}),e.emit("unmount"),e},"unmount"),options:o(function(){return Yc(this._private.options)},"options"),json:o(function(e){var r=this,n=r._private,i=r.mutableElements(),a=o(function(C){return r.getElementById(C.id())},"getFreshRef");if(Ur(e)){if(r.startBatch(),e.elements){var s={},l=o(function(C,T){for(var E=[],A=[],S=0;S<C.length;S++){var _=C[S];if(!_.data.id){un("cy.json() cannot handle elements without an ID attribute");continue}var I=""+_.data.id,D=r.getElementById(I);s[I]=!0,D.length!==0?A.push({ele:D,json:_}):(T&&(_.group=T),E.push(_))}r.add(E);for(var k=0;k<A.length;k++){var L=A[k],R=L.ele,O=L.json;R.json(O)}},"updateEles");if(En(e.elements))l(e.elements);else for(var u=["nodes","edges"],h=0;h<u.length;h++){var f=u[h],d=e.elements[f];En(d)&&l(d,f)}var p=r.collection();i.filter(function(w){return!s[w.id()]}).forEach(function(w){w.isParent()?p.merge(w):w.remove()}),p.forEach(function(w){return w.children().move({parent:null})}),p.forEach(function(w){return a(w).remove()})}e.style&&r.style(e.style),e.zoom!=null&&e.zoom!==n.zoom&&r.zoom(e.zoom),e.pan&&(e.pan.x!==n.pan.x||e.pan.y!==n.pan.y)&&r.pan(e.pan),e.data&&r.data(e.data);for(var m=["minZoom","maxZoom","zoomingEnabled","userZoomingEnabled","panningEnabled","userPanningEnabled","boxSelectionEnabled","autolock","autoungrabify","autounselectify","multiClickDebounceTime"],g=0;g<m.length;g++){var y=m[g];e[y]!=null&&r[y](e[y])}return r.endBatch(),this}else{var v=!!e,x={};v?x.elements=this.elements().map(function(w){return w.json()}):(x.elements={},i.forEach(function(w){var C=w.group();x.elements[C]||(x.elements[C]=[]),x.elements[C].push(w.json())})),this._private.styleEnabled&&(x.style=r.style().json()),x.data=Yc(r.data());var b=n.options;return x.zoomingEnabled=n.zoomingEnabled,x.userZoomingEnabled=n.userZoomingEnabled,x.zoom=n.zoom,x.minZoom=n.minZoom,x.maxZoom=n.maxZoom,x.panningEnabled=n.panningEnabled,x.userPanningEnabled=n.userPanningEnabled,x.pan=Yc(n.pan),x.boxSelectionEnabled=n.boxSelectionEnabled,x.renderer=Yc(b.renderer),x.hideEdgesOnViewport=b.hideEdgesOnViewport,x.textureOnViewport=b.textureOnViewport,x.wheelSensitivity=b.wheelSensitivity,x.motionBlur=b.motionBlur,x.multiClickDebounceTime=b.multiClickDebounceTime,x}},"json")});SS.$id=SS.getElementById;[VKe,YKe,ege,VP,pS,jKe,UP,mS,ZKe,Hp,Zb].forEach(function(t){rr(SS,t)});eQe={fit:!0,directed:!1,padding:30,circle:!1,grid:!1,spacingFactor:1.75,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,roots:void 0,depthSort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")},tQe={maximal:!1,acyclic:!1},z1=o(function(e){return e.scratch("breadthfirst")},"getInfo"),T0e=o(function(e,r){return e.scratch("breadthfirst",r)},"setInfo");o(tge,"BreadthFirstLayout");tge.prototype.run=function(){var t=this.options,e=t.cy,r=t.eles,n=r.nodes().filter(function(ae){return ae.isChildless()}),i=r,a=t.directed,s=t.acyclic||t.maximal||t.maximalAdjustments>0,l=!!t.boundingBox,u=e.extent(),h=Hs(l?t.boundingBox:{x1:u.x1,y1:u.y1,w:u.w,h:u.h}),f;if(go(t.roots))f=t.roots;else if(En(t.roots)){for(var d=[],p=0;p<t.roots.length;p++){var m=t.roots[p],g=e.getElementById(m);d.push(g)}f=e.collection(d)}else if(Zt(t.roots))f=e.$(t.roots);else if(a)f=n.roots();else{var y=r.components();f=e.collection();for(var v=o(function(Oe){var ge=y[Oe],ze=ge.maxDegree(!1),He=ge.filter(function($e){return $e.degree(!1)===ze});f=f.add(He)},"_loop"),x=0;x<y.length;x++)v(x)}var b=[],w={},C=o(function(Oe,ge){b[ge]==null&&(b[ge]=[]);var ze=b[ge].length;b[ge].push(Oe),T0e(Oe,{index:ze,depth:ge})},"addToDepth"),T=o(function(Oe,ge){var ze=z1(Oe),He=ze.depth,$e=ze.index;b[He][$e]=null,Oe.isChildless()&&C(Oe,ge)},"changeDepth");i.bfs({roots:f,directed:t.directed,visit:o(function(Oe,ge,ze,He,$e){var Re=Oe[0],Ie=Re.id();Re.isChildless()&&C(Re,$e),w[Ie]=!0},"visit")});for(var E=[],A=0;A<n.length;A++){var S=n[A];w[S.id()]||E.push(S)}var _=o(function(Oe){for(var ge=b[Oe],ze=0;ze<ge.length;ze++){var He=ge[ze];if(He==null){ge.splice(ze,1),ze--;continue}T0e(He,{depth:Oe,index:ze})}},"assignDepthsAt"),I=o(function(Oe,ge){for(var ze=z1(Oe),He=Oe.incomers().filter(function(re){return re.isNode()&&r.has(re)}),$e=-1,Re=Oe.id(),Ie=0;Ie<He.length;Ie++){var be=He[Ie],W=z1(be);$e=Math.max($e,W.depth)}if(ze.depth<=$e){if(!t.acyclic&&ge[Re])return null;var de=$e+1;return T(Oe,de),ge[Re]=de,!0}return!1},"adjustMaximally");if(a&&s){var D=[],k={},L=o(function(Oe){return D.push(Oe)},"enqueue"),R=o(function(){return D.shift()},"dequeue");for(n.forEach(function(ae){return D.push(ae)});D.length>0;){var O=R(),M=I(O,k);if(M)O.outgoers().filter(function(ae){return ae.isNode()&&r.has(ae)}).forEach(L);else if(M===null){un("Detected double maximal shift for node `"+O.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}var B=0;if(t.avoidOverlap)for(var F=0;F<n.length;F++){var P=n[F],z=P.layoutDimensions(t),$=z.w,H=z.h;B=Math.max(B,$,H)}var Q={},j=o(function(Oe){if(Q[Oe.id()])return Q[Oe.id()];for(var ge=z1(Oe).depth,ze=Oe.neighborhood(),He=0,$e=0,Re=0;Re<ze.length;Re++){var Ie=ze[Re];if(!(Ie.isEdge()||Ie.isParent()||!n.has(Ie))){var be=z1(Ie);if(be!=null){var W=be.index,de=be.depth;if(!(W==null||de==null)){var re=b[de].length;de<ge&&(He+=W/re,$e++)}}}}return $e=Math.max(1,$e),He=He/$e,$e===0&&(He=0),Q[Oe.id()]=He,He},"getWeightedPercent"),ie=o(function(Oe,ge){var ze=j(Oe),He=j(ge),$e=ze-He;return $e===0?eme(Oe.id(),ge.id()):$e},"sortFn");t.depthSort!==void 0&&(ie=t.depthSort);for(var ne=b.length,le=0;le<ne;le++)b[le].sort(ie),_(le);for(var he=[],K=0;K<E.length;K++)he.push(E[K]);var X=o(function(){for(var Oe=0;Oe<ne;Oe++)_(Oe)},"assignDepths");he.length&&(b.unshift(he),ne=b.length,X());for(var te=0,J=0;J<ne;J++)te=Math.max(b[J].length,te);var se={x:h.x1+h.w/2,y:h.y1+h.h/2},ue=n.reduce(function(ae,Oe){return function(ge){return{w:ae.w===-1?ge.w:(ae.w+ge.w)/2,h:ae.h===-1?ge.h:(ae.h+ge.h)/2}}(Oe.boundingBox({includeLabels:t.nodeDimensionsIncludeLabels}))},{w:-1,h:-1}),Z=Math.max(ne===1?0:l?(h.h-t.padding*2-ue.h)/(ne-1):(h.h-t.padding*2-ue.h)/(ne+1),B),Se=b.reduce(function(ae,Oe){return Math.max(ae,Oe.length)},0),ce=o(function(Oe){var ge=z1(Oe),ze=ge.depth,He=ge.index;if(t.circle){var $e=Math.min(h.w/2/ne,h.h/2/ne);$e=Math.max($e,B);var Re=$e*ze+$e-(ne>0&&b[0].length<=3?$e/2:0),Ie=2*Math.PI/b[ze].length*He;return ze===0&&b[0].length===1&&(Re=1),{x:se.x+Re*Math.cos(Ie),y:se.y+Re*Math.sin(Ie)}}else{var be=b[ze].length,W=Math.max(be===1?0:l?(h.w-t.padding*2-ue.w)/((t.grid?Se:be)-1):(h.w-t.padding*2-ue.w)/((t.grid?Se:be)+1),B),de={x:se.x+(He+1-(be+1)/2)*W,y:se.y+(ze+1-(ne+1)/2)*Z};return de}},"getPosition");return r.nodes().layoutPositions(this,t,ce),this};rQe={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:3/2*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(rge,"CircleLayout");rge.prototype.run=function(){var t=this.options,e=t,r=t.cy,n=e.eles,i=e.counterclockwise!==void 0?!e.counterclockwise:e.clockwise,a=n.nodes().not(":parent");e.sort&&(a=a.sort(e.sort));for(var s=Hs(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=e.sweep===void 0?2*Math.PI-2*Math.PI/a.length:e.sweep,h=u/Math.max(1,a.length-1),f,d=0,p=0;p<a.length;p++){var m=a[p],g=m.layoutDimensions(e),y=g.w,v=g.h;d=Math.max(d,y,v)}if(Ct(e.radius)?f=e.radius:a.length<=1?f=0:f=Math.min(s.h,s.w)/2-d,a.length>1&&e.avoidOverlap){d*=1.75;var x=Math.cos(h)-Math.cos(0),b=Math.sin(h)-Math.sin(0),w=Math.sqrt(d*d/(x*x+b*b));f=Math.max(w,f)}var C=o(function(E,A){var S=e.startAngle+A*h*(i?1:-1),_=f*Math.cos(S),I=f*Math.sin(S),D={x:l.x+_,y:l.y+I};return D},"getPos");return n.nodes().layoutPositions(this,e,C),this};nQe={fit:!0,padding:30,startAngle:3/2*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:o(function(e){return e.degree()},"concentric"),levelWidth:o(function(e){return e.maxDegree()/4},"levelWidth"),animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(nge,"ConcentricLayout");nge.prototype.run=function(){for(var t=this.options,e=t,r=e.counterclockwise!==void 0?!e.counterclockwise:e.clockwise,n=t.cy,i=e.eles,a=i.nodes().not(":parent"),s=Hs(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=[],h=0,f=0;f<a.length;f++){var d=a[f],p=void 0;p=e.concentric(d),u.push({value:p,node:d}),d._private.scratch.concentric=p}a.updateStyle();for(var m=0;m<a.length;m++){var g=a[m],y=g.layoutDimensions(e);h=Math.max(h,y.w,y.h)}u.sort(function(ue,Z){return Z.value-ue.value});for(var v=e.levelWidth(a),x=[[]],b=x[0],w=0;w<u.length;w++){var C=u[w];if(b.length>0){var T=Math.abs(b[0].value-C.value);T>=v&&(b=[],x.push(b))}b.push(C)}var E=h+e.minNodeSpacing;if(!e.avoidOverlap){var A=x.length>0&&x[0].length>1,S=Math.min(s.w,s.h)/2-E,_=S/(x.length+A?1:0);E=Math.min(E,_)}for(var I=0,D=0;D<x.length;D++){var k=x[D],L=e.sweep===void 0?2*Math.PI-2*Math.PI/k.length:e.sweep,R=k.dTheta=L/Math.max(1,k.length-1);if(k.length>1&&e.avoidOverlap){var O=Math.cos(R)-Math.cos(0),M=Math.sin(R)-Math.sin(0),B=Math.sqrt(E*E/(O*O+M*M));I=Math.max(B,I)}k.r=I,I+=E}if(e.equidistant){for(var F=0,P=0,z=0;z<x.length;z++){var $=x[z],H=$.r-P;F=Math.max(F,H)}P=0;for(var Q=0;Q<x.length;Q++){var j=x[Q];Q===0&&(P=j.r),j.r=P,P+=F}}for(var ie={},ne=0;ne<x.length;ne++)for(var le=x[ne],he=le.dTheta,K=le.r,X=0;X<le.length;X++){var te=le[X],J=e.startAngle+(r?1:-1)*he*X,se={x:l.x+K*Math.cos(J),y:l.y+K*Math.sin(J)};ie[te.node.id()]=se}return i.nodes().layoutPositions(this,e,function(ue){var Z=ue.id();return ie[Z]}),this};iQe={ready:o(function(){},"ready"),stop:o(function(){},"stop"),animate:!0,animationEasing:void 0,animationDuration:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),animationThreshold:250,refresh:20,fit:!0,padding:30,boundingBox:void 0,nodeDimensionsIncludeLabels:!1,randomize:!1,componentSpacing:40,nodeRepulsion:o(function(e){return 2048},"nodeRepulsion"),nodeOverlap:4,idealEdgeLength:o(function(e){return 32},"idealEdgeLength"),edgeElasticity:o(function(e){return 32},"edgeElasticity"),nestingFactor:1.2,gravity:1,numIter:1e3,initialTemp:1e3,coolingFactor:.99,minTemp:1};o(HS,"CoseLayout");HS.prototype.run=function(){var t=this.options,e=t.cy,r=this;r.stopped=!1,(t.animate===!0||t.animate===!1)&&r.emit({type:"layoutstart",layout:r}),t.debug===!0?_P=!0:_P=!1;var n=aQe(e,r,t);_P&&lQe(n),t.randomize&&cQe(n);var i=Qu(),a=o(function(){uQe(n,e,t),t.fit===!0&&e.fit(t.padding)},"refresh"),s=o(function(p){return!(r.stopped||p>=t.numIter||(hQe(n,t),n.temperature=n.temperature*t.coolingFactor,n.temperature<t.minTemp))},"mainLoop"),l=o(function(){if(t.animate===!0||t.animate===!1)a(),r.one("layoutstop",t.stop),r.emit({type:"layoutstop",layout:r});else{var p=t.eles.nodes(),m=ige(n,t,p);p.layoutPositions(r,t,m)}},"done"),u=0,h=!0;if(t.animate===!0){var f=o(function d(){for(var p=0;h&&p<t.refresh;)h=s(u),u++,p++;if(!h)E0e(n,t),l();else{var m=Qu();m-i>=t.animationThreshold&&a(),xS(d)}},"frame");f()}else{for(;h;)h=s(u),u++;E0e(n,t),l()}return this};HS.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this};HS.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};aQe=o(function(e,r,n){for(var i=n.eles.edges(),a=n.eles.nodes(),s=Hs(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),l={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:a.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:i.size(),temperature:n.initialTemp,clientWidth:s.w,clientHeight:s.h,boundingBox:s},u=n.eles.components(),h={},f=0;f<u.length;f++)for(var d=u[f],p=0;p<d.length;p++){var m=d[p];h[m.id()]=f}for(var f=0;f<l.nodeSize;f++){var g=a[f],y=g.layoutDimensions(n),v={};v.isLocked=g.locked(),v.id=g.data("id"),v.parentId=g.data("parent"),v.cmptId=h[g.id()],v.children=[],v.positionX=g.position("x"),v.positionY=g.position("y"),v.offsetX=0,v.offsetY=0,v.height=y.w,v.width=y.h,v.maxX=v.positionX+v.width/2,v.minX=v.positionX-v.width/2,v.maxY=v.positionY+v.height/2,v.minY=v.positionY-v.height/2,v.padLeft=parseFloat(g.style("padding")),v.padRight=parseFloat(g.style("padding")),v.padTop=parseFloat(g.style("padding")),v.padBottom=parseFloat(g.style("padding")),v.nodeRepulsion=si(n.nodeRepulsion)?n.nodeRepulsion(g):n.nodeRepulsion,l.layoutNodes.push(v),l.idToIndex[v.id]=f}for(var x=[],b=0,w=-1,C=[],f=0;f<l.nodeSize;f++){var g=l.layoutNodes[f],T=g.parentId;T!=null?l.layoutNodes[l.idToIndex[T]].children.push(g.id):(x[++w]=g.id,C.push(g.id))}for(l.graphSet.push(C);b<=w;){var E=x[b++],A=l.idToIndex[E],m=l.layoutNodes[A],S=m.children;if(S.length>0){l.graphSet.push(S);for(var f=0;f<S.length;f++)x[++w]=S[f]}}for(var f=0;f<l.graphSet.length;f++)for(var _=l.graphSet[f],p=0;p<_.length;p++){var I=l.idToIndex[_[p]];l.indexToGraph[I]=f}for(var f=0;f<l.edgeSize;f++){var D=i[f],k={};k.id=D.data("id"),k.sourceId=D.data("source"),k.targetId=D.data("target");var L=si(n.idealEdgeLength)?n.idealEdgeLength(D):n.idealEdgeLength,R=si(n.edgeElasticity)?n.edgeElasticity(D):n.edgeElasticity,O=l.idToIndex[k.sourceId],M=l.idToIndex[k.targetId],B=l.indexToGraph[O],F=l.indexToGraph[M];if(B!=F){for(var P=sQe(k.sourceId,k.targetId,l),z=l.graphSet[P],$=0,v=l.layoutNodes[O];z.indexOf(v.id)===-1;)v=l.layoutNodes[l.idToIndex[v.parentId]],$++;for(v=l.layoutNodes[M];z.indexOf(v.id)===-1;)v=l.layoutNodes[l.idToIndex[v.parentId]],$++;L*=$*n.nestingFactor}k.idealLength=L,k.elasticity=R,l.layoutEdges.push(k)}return l},"createLayoutInfo"),sQe=o(function(e,r,n){var i=oQe(e,r,0,n);return 2>i.count?0:i.graph},"findLCA"),oQe=o(function t(e,r,n,i){var a=i.graphSet[n];if(-1<a.indexOf(e)&&-1<a.indexOf(r))return{count:2,graph:n};for(var s=0,l=0;l<a.length;l++){var u=a[l],h=i.idToIndex[u],f=i.layoutNodes[h].children;if(f.length!==0){var d=i.indexToGraph[i.idToIndex[f[0]]],p=t(e,r,d,i);if(p.count!==0)if(p.count===1){if(s++,s===2)break}else return p}}return{count:s,graph:n}},"findLCA_aux"),cQe=o(function(e,r){for(var n=e.clientWidth,i=e.clientHeight,a=0;a<e.nodeSize;a++){var s=e.layoutNodes[a];s.children.length===0&&!s.isLocked&&(s.positionX=Math.random()*n,s.positionY=Math.random()*i)}},"randomizePositions"),ige=o(function(e,r,n){var i=e.boundingBox,a={x1:1/0,x2:-1/0,y1:1/0,y2:-1/0};return r.boundingBox&&(n.forEach(function(s){var l=e.layoutNodes[e.idToIndex[s.data("id")]];a.x1=Math.min(a.x1,l.positionX),a.x2=Math.max(a.x2,l.positionX),a.y1=Math.min(a.y1,l.positionY),a.y2=Math.max(a.y2,l.positionY)}),a.w=a.x2-a.x1,a.h=a.y2-a.y1),function(s,l){var u=e.layoutNodes[e.idToIndex[s.data("id")]];if(r.boundingBox){var h=(u.positionX-a.x1)/a.w,f=(u.positionY-a.y1)/a.h;return{x:i.x1+h*i.w,y:i.y1+f*i.h}}else return{x:u.positionX,y:u.positionY}}},"getScaleInBoundsFn"),uQe=o(function(e,r,n){var i=n.layout,a=n.eles.nodes(),s=ige(e,n,a);a.positions(s),e.ready!==!0&&(e.ready=!0,i.one("layoutready",n.ready),i.emit({type:"layoutready",layout:this}))},"refreshPositions"),hQe=o(function(e,r,n){fQe(e,r),mQe(e),gQe(e,r),yQe(e),vQe(e)},"step"),fQe=o(function(e,r){for(var n=0;n<e.graphSet.length;n++)for(var i=e.graphSet[n],a=i.length,s=0;s<a;s++)for(var l=e.layoutNodes[e.idToIndex[i[s]]],u=s+1;u<a;u++){var h=e.layoutNodes[e.idToIndex[i[u]]];dQe(l,h,e,r)}},"calculateNodeForces"),k0e=o(function(e){return-e+2*e*Math.random()},"randomDistance"),dQe=o(function(e,r,n,i){var a=e.cmptId,s=r.cmptId;if(!(a!==s&&!n.isCompound)){var l=r.positionX-e.positionX,u=r.positionY-e.positionY,h=1;l===0&&u===0&&(l=k0e(h),u=k0e(h));var f=pQe(e,r,l,u);if(f>0)var d=i.nodeOverlap*f,p=Math.sqrt(l*l+u*u),m=d*l/p,g=d*u/p;else var y=CS(e,l,u),v=CS(r,-1*l,-1*u),x=v.x-y.x,b=v.y-y.y,w=x*x+b*b,p=Math.sqrt(w),d=(e.nodeRepulsion+r.nodeRepulsion)/w,m=d*x/p,g=d*b/p;e.isLocked||(e.offsetX-=m,e.offsetY-=g),r.isLocked||(r.offsetX+=m,r.offsetY+=g)}},"nodeRepulsion"),pQe=o(function(e,r,n,i){if(n>0)var a=e.maxX-r.minX;else var a=r.maxX-e.minX;if(i>0)var s=e.maxY-r.minY;else var s=r.maxY-e.minY;return a>=0&&s>=0?Math.sqrt(a*a+s*s):0},"nodesOverlap"),CS=o(function(e,r,n){var i=e.positionX,a=e.positionY,s=e.height||1,l=e.width||1,u=n/r,h=s/l,f={};return r===0&&0<n||r===0&&0>n?(f.x=i,f.y=a+s/2,f):0<r&&-1*h<=u&&u<=h?(f.x=i+l/2,f.y=a+l*n/2/r,f):0>r&&-1*h<=u&&u<=h?(f.x=i-l/2,f.y=a-l*n/2/r,f):0<n&&(u<=-1*h||u>=h)?(f.x=i+s*r/2/n,f.y=a+s/2,f):(0>n&&(u<=-1*h||u>=h)&&(f.x=i-s*r/2/n,f.y=a-s/2),f)},"findClippingPoint"),mQe=o(function(e,r){for(var n=0;n<e.edgeSize;n++){var i=e.layoutEdges[n],a=e.idToIndex[i.sourceId],s=e.layoutNodes[a],l=e.idToIndex[i.targetId],u=e.layoutNodes[l],h=u.positionX-s.positionX,f=u.positionY-s.positionY;if(!(h===0&&f===0)){var d=CS(s,h,f),p=CS(u,-1*h,-1*f),m=p.x-d.x,g=p.y-d.y,y=Math.sqrt(m*m+g*g),v=Math.pow(i.idealLength-y,2)/i.elasticity;if(y!==0)var x=v*m/y,b=v*g/y;else var x=0,b=0;s.isLocked||(s.offsetX+=x,s.offsetY+=b),u.isLocked||(u.offsetX-=x,u.offsetY-=b)}}},"calculateEdgeForces"),gQe=o(function(e,r){if(r.gravity!==0)for(var n=1,i=0;i<e.graphSet.length;i++){var a=e.graphSet[i],s=a.length;if(i===0)var l=e.clientHeight/2,u=e.clientWidth/2;else var h=e.layoutNodes[e.idToIndex[a[0]]],f=e.layoutNodes[e.idToIndex[h.parentId]],l=f.positionX,u=f.positionY;for(var d=0;d<s;d++){var p=e.layoutNodes[e.idToIndex[a[d]]];if(!p.isLocked){var m=l-p.positionX,g=u-p.positionY,y=Math.sqrt(m*m+g*g);if(y>n){var v=r.gravity*m/y,x=r.gravity*g/y;p.offsetX+=v,p.offsetY+=x}}}}},"calculateGravityForces"),yQe=o(function(e,r){var n=[],i=0,a=-1;for(n.push.apply(n,e.graphSet[0]),a+=e.graphSet[0].length;i<=a;){var s=n[i++],l=e.idToIndex[s],u=e.layoutNodes[l],h=u.children;if(0<h.length&&!u.isLocked){for(var f=u.offsetX,d=u.offsetY,p=0;p<h.length;p++){var m=e.layoutNodes[e.idToIndex[h[p]]];m.offsetX+=f,m.offsetY+=d,n[++a]=h[p]}u.offsetX=0,u.offsetY=0}}},"propagateForces"),vQe=o(function(e,r){for(var n=0;n<e.nodeSize;n++){var i=e.layoutNodes[n];0<i.children.length&&(i.maxX=void 0,i.minX=void 0,i.maxY=void 0,i.minY=void 0)}for(var n=0;n<e.nodeSize;n++){var i=e.layoutNodes[n];if(!(0<i.children.length||i.isLocked)){var a=xQe(i.offsetX,i.offsetY,e.temperature);i.positionX+=a.x,i.positionY+=a.y,i.offsetX=0,i.offsetY=0,i.minX=i.positionX-i.width,i.maxX=i.positionX+i.width,i.minY=i.positionY-i.height,i.maxY=i.positionY+i.height,bQe(i,e)}}for(var n=0;n<e.nodeSize;n++){var i=e.layoutNodes[n];0<i.children.length&&!i.isLocked&&(i.positionX=(i.maxX+i.minX)/2,i.positionY=(i.maxY+i.minY)/2,i.width=i.maxX-i.minX,i.height=i.maxY-i.minY)}},"updatePositions"),xQe=o(function(e,r,n){var i=Math.sqrt(e*e+r*r);if(i>n)var a={x:n*e/i,y:n*r/i};else var a={x:e,y:r};return a},"limitForce"),bQe=o(function t(e,r){var n=e.parentId;if(n!=null){var i=r.layoutNodes[r.idToIndex[n]],a=!1;if((i.maxX==null||e.maxX+i.padRight>i.maxX)&&(i.maxX=e.maxX+i.padRight,a=!0),(i.minX==null||e.minX-i.padLeft<i.minX)&&(i.minX=e.minX-i.padLeft,a=!0),(i.maxY==null||e.maxY+i.padBottom>i.maxY)&&(i.maxY=e.maxY+i.padBottom,a=!0),(i.minY==null||e.minY-i.padTop<i.minY)&&(i.minY=e.minY-i.padTop,a=!0),a)return t(i,r)}},"updateAncestryBoundaries"),E0e=o(function(e,r){for(var n=e.layoutNodes,i=[],a=0;a<n.length;a++){var s=n[a],l=s.cmptId,u=i[l]=i[l]||[];u.push(s)}for(var h=0,a=0;a<i.length;a++){var f=i[a];if(f){f.x1=1/0,f.x2=-1/0,f.y1=1/0,f.y2=-1/0;for(var d=0;d<f.length;d++){var p=f[d];f.x1=Math.min(f.x1,p.positionX-p.width/2),f.x2=Math.max(f.x2,p.positionX+p.width/2),f.y1=Math.min(f.y1,p.positionY-p.height/2),f.y2=Math.max(f.y2,p.positionY+p.height/2)}f.w=f.x2-f.x1,f.h=f.y2-f.y1,h+=f.w*f.h}}i.sort(function(b,w){return w.w*w.h-b.w*b.h});for(var m=0,g=0,y=0,v=0,x=Math.sqrt(h)*e.clientWidth/e.clientHeight,a=0;a<i.length;a++){var f=i[a];if(f){for(var d=0;d<f.length;d++){var p=f[d];p.isLocked||(p.positionX+=m-f.x1,p.positionY+=g-f.y1)}m+=f.w+r.componentSpacing,y+=f.w+r.componentSpacing,v=Math.max(v,f.h),y>x&&(g+=v+r.componentSpacing,m=0,y=0,v=0)}}},"separateComponents"),wQe={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:o(function(e){},"position"),sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(age,"GridLayout");age.prototype.run=function(){var t=this.options,e=t,r=t.cy,n=e.eles,i=n.nodes().not(":parent");e.sort&&(i=i.sort(e.sort));var a=Hs(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(a.h===0||a.w===0)n.nodes().layoutPositions(this,e,function(Q){return{x:a.x1,y:a.y1}});else{var s=i.size(),l=Math.sqrt(s*a.h/a.w),u=Math.round(l),h=Math.round(a.w/a.h*l),f=o(function(j){if(j==null)return Math.min(u,h);var ie=Math.min(u,h);ie==u?u=j:h=j},"small"),d=o(function(j){if(j==null)return Math.max(u,h);var ie=Math.max(u,h);ie==u?u=j:h=j},"large"),p=e.rows,m=e.cols!=null?e.cols:e.columns;if(p!=null&&m!=null)u=p,h=m;else if(p!=null&&m==null)u=p,h=Math.ceil(s/u);else if(p==null&&m!=null)h=m,u=Math.ceil(s/h);else if(h*u>s){var g=f(),y=d();(g-1)*y>=s?f(g-1):(y-1)*g>=s&&d(y-1)}else for(;h*u<s;){var v=f(),x=d();(x+1)*v>=s?d(x+1):f(v+1)}var b=a.w/h,w=a.h/u;if(e.condense&&(b=0,w=0),e.avoidOverlap)for(var C=0;C<i.length;C++){var T=i[C],E=T._private.position;(E.x==null||E.y==null)&&(E.x=0,E.y=0);var A=T.layoutDimensions(e),S=e.avoidOverlapPadding,_=A.w+S,I=A.h+S;b=Math.max(b,_),w=Math.max(w,I)}for(var D={},k=o(function(j,ie){return!!D["c-"+j+"-"+ie]},"used"),L=o(function(j,ie){D["c-"+j+"-"+ie]=!0},"use"),R=0,O=0,M=o(function(){O++,O>=h&&(O=0,R++)},"moveToNextCell"),B={},F=0;F<i.length;F++){var P=i[F],z=e.position(P);if(z&&(z.row!==void 0||z.col!==void 0)){var $={row:z.row,col:z.col};if($.col===void 0)for($.col=0;k($.row,$.col);)$.col++;else if($.row===void 0)for($.row=0;k($.row,$.col);)$.row++;B[P.id()]=$,L($.row,$.col)}}var H=o(function(j,ie){var ne,le;if(j.locked()||j.isParent())return!1;var he=B[j.id()];if(he)ne=he.col*b+b/2+a.x1,le=he.row*w+w/2+a.y1;else{for(;k(R,O);)M();ne=O*b+b/2+a.x1,le=R*w+w/2+a.y1,L(R,O),M()}return{x:ne,y:le}},"getPos");i.layoutPositions(this,e,H)}return this};TQe={ready:o(function(){},"ready"),stop:o(function(){},"stop")};o(gB,"NullLayout");gB.prototype.run=function(){var t=this.options,e=t.eles,r=this;return t.cy,r.emit("layoutstart"),e.nodes().positions(function(){return{x:0,y:0}}),r.one("layoutready",t.ready),r.emit("layoutready"),r.one("layoutstop",t.stop),r.emit("layoutstop"),this};gB.prototype.stop=function(){return this};kQe={positions:void 0,zoom:void 0,pan:void 0,fit:!0,padding:30,spacingFactor:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(sge,"PresetLayout");sge.prototype.run=function(){var t=this.options,e=t.eles,r=e.nodes(),n=si(t.positions);function i(a){if(t.positions==null)return Aqe(a.position());if(n)return t.positions(a);var s=t.positions[a._private.data.id];return s??null}return o(i,"getPosition"),r.layoutPositions(this,t,function(a,s){var l=i(a);return a.locked()||l==null?!1:l}),this};EQe={fit:!0,padding:30,boundingBox:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:o(function(e,r){return!0},"animateFilter"),ready:void 0,stop:void 0,transform:o(function(e,r){return r},"transform")};o(oge,"RandomLayout");oge.prototype.run=function(){var t=this.options,e=t.cy,r=t.eles,n=Hs(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),i=o(function(s,l){return{x:n.x1+Math.round(Math.random()*n.w),y:n.y1+Math.round(Math.random()*n.h)}},"getPos");return r.nodes().layoutPositions(this,t,i),this};SQe=[{name:"breadthfirst",impl:tge},{name:"circle",impl:rge},{name:"concentric",impl:nge},{name:"cose",impl:HS},{name:"grid",impl:age},{name:"null",impl:gB},{name:"preset",impl:sge},{name:"random",impl:oge}];o(lge,"NullRenderer");S0e=o(function(){},"noop"),C0e=o(function(){throw new Error("A headless instance can not render images")},"throwImgErr");lge.prototype={recalculateRenderedStyle:S0e,notify:o(function(){this.notifications++},"notify"),init:S0e,isHeadless:o(function(){return!0},"isHeadless"),png:C0e,jpg:C0e};yB={};yB.arrowShapeWidth=.3;yB.registerArrowShapes=function(){var t=this.arrowShapes={},e=this,r=o(function(h,f,d,p,m,g,y){var v=m.x-d/2-y,x=m.x+d/2+y,b=m.y-d/2-y,w=m.y+d/2+y,C=v<=h&&h<=x&&b<=f&&f<=w;return C},"bbCollide"),n=o(function(h,f,d,p,m){var g=h*Math.cos(p)-f*Math.sin(p),y=h*Math.sin(p)+f*Math.cos(p),v=g*d,x=y*d,b=v+m.x,w=x+m.y;return{x:b,y:w}},"transform"),i=o(function(h,f,d,p){for(var m=[],g=0;g<h.length;g+=2){var y=h[g],v=h[g+1];m.push(n(y,v,f,d,p))}return m},"transformPoints"),a=o(function(h){for(var f=[],d=0;d<h.length;d++){var p=h[d];f.push(p.x,p.y)}return f},"pointsToArr"),s=o(function(h){return h.pstyle("width").pfValue*h.pstyle("arrow-scale").pfValue*2},"standardGap"),l=o(function(h,f){Zt(f)&&(f=t[f]),t[h]=rr({name:h,points:[-.15,-.3,.15,-.3,.15,.3,-.15,.3],collide:o(function(p,m,g,y,v,x){var b=a(i(this.points,g+2*x,y,v)),w=Us(p,m,b);return w},"collide"),roughCollide:r,draw:o(function(p,m,g,y){var v=i(this.points,m,g,y);e.arrowShapeImpl("polygon")(p,v)},"draw"),spacing:o(function(p){return 0},"spacing"),gap:s},f)},"defineArrowShape");l("none",{collide:bS,roughCollide:bS,draw:rB,spacing:Ppe,gap:Ppe}),l("triangle",{points:[-.15,-.3,0,0,.15,-.3]}),l("arrow","triangle"),l("triangle-backcurve",{points:t.triangle.points,controlPoint:[0,-.15],roughCollide:r,draw:o(function(h,f,d,p,m){var g=i(this.points,f,d,p),y=this.controlPoint,v=n(y[0],y[1],f,d,p);e.arrowShapeImpl(this.name)(h,g,v)},"draw"),gap:o(function(h){return s(h)*.8},"gap")}),l("triangle-tee",{points:[0,0,.15,-.3,-.15,-.3,0,0],pointsTee:[-.15,-.4,-.15,-.5,.15,-.5,.15,-.4],collide:o(function(h,f,d,p,m,g,y){var v=a(i(this.points,d+2*y,p,m)),x=a(i(this.pointsTee,d+2*y,p,m)),b=Us(h,f,v)||Us(h,f,x);return b},"collide"),draw:o(function(h,f,d,p,m){var g=i(this.points,f,d,p),y=i(this.pointsTee,f,d,p);e.arrowShapeImpl(this.name)(h,g,y)},"draw")}),l("circle-triangle",{radius:.15,pointsTr:[0,-.15,.15,-.45,-.15,-.45,0,-.15],collide:o(function(h,f,d,p,m,g,y){var v=m,x=Math.pow(v.x-h,2)+Math.pow(v.y-f,2)<=Math.pow((d+2*y)*this.radius,2),b=a(i(this.points,d+2*y,p,m));return Us(h,f,b)||x},"collide"),draw:o(function(h,f,d,p,m){var g=i(this.pointsTr,f,d,p);e.arrowShapeImpl(this.name)(h,g,p.x,p.y,this.radius*f)},"draw"),spacing:o(function(h){return e.getArrowWidth(h.pstyle("width").pfValue,h.pstyle("arrow-scale").value)*this.radius},"spacing")}),l("triangle-cross",{points:[0,0,.15,-.3,-.15,-.3,0,0],baseCrossLinePts:[-.15,-.4,-.15,-.4,.15,-.4,.15,-.4],crossLinePts:o(function(h,f){var d=this.baseCrossLinePts.slice(),p=f/h,m=3,g=5;return d[m]=d[m]-p,d[g]=d[g]-p,d},"crossLinePts"),collide:o(function(h,f,d,p,m,g,y){var v=a(i(this.points,d+2*y,p,m)),x=a(i(this.crossLinePts(d,g),d+2*y,p,m)),b=Us(h,f,v)||Us(h,f,x);return b},"collide"),draw:o(function(h,f,d,p,m){var g=i(this.points,f,d,p),y=i(this.crossLinePts(f,m),f,d,p);e.arrowShapeImpl(this.name)(h,g,y)},"draw")}),l("vee",{points:[-.15,-.3,0,0,.15,-.3,0,-.15],gap:o(function(h){return s(h)*.525},"gap")}),l("circle",{radius:.15,collide:o(function(h,f,d,p,m,g,y){var v=m,x=Math.pow(v.x-h,2)+Math.pow(v.y-f,2)<=Math.pow((d+2*y)*this.radius,2);return x},"collide"),draw:o(function(h,f,d,p,m){e.arrowShapeImpl(this.name)(h,p.x,p.y,this.radius*f)},"draw"),spacing:o(function(h){return e.getArrowWidth(h.pstyle("width").pfValue,h.pstyle("arrow-scale").value)*this.radius},"spacing")}),l("tee",{points:[-.15,0,-.15,-.1,.15,-.1,.15,0],spacing:o(function(h){return 1},"spacing"),gap:o(function(h){return 1},"gap")}),l("square",{points:[-.15,0,.15,0,.15,-.3,-.15,-.3]}),l("diamond",{points:[-.15,-.15,0,-.3,.15,-.15,0,0],gap:o(function(h){return h.pstyle("width").pfValue*h.pstyle("arrow-scale").value},"gap")}),l("chevron",{points:[0,0,-.15,-.15,-.1,-.2,0,-.1,.1,-.2,.15,-.15],gap:o(function(h){return .95*h.pstyle("width").pfValue*h.pstyle("arrow-scale").value},"gap")})};qp={};qp.projectIntoViewport=function(t,e){var r=this.cy,n=this.findContainerClientCoords(),i=n[0],a=n[1],s=n[4],l=r.pan(),u=r.zoom(),h=((t-i)/s-l.x)/u,f=((e-a)/s-l.y)/u;return[h,f]};qp.findContainerClientCoords=function(){if(this.containerBB)return this.containerBB;var t=this.container,e=t.getBoundingClientRect(),r=this.cy.window().getComputedStyle(t),n=o(function(x){return parseFloat(r.getPropertyValue(x))},"styleValue"),i={left:n("padding-left"),right:n("padding-right"),top:n("padding-top"),bottom:n("padding-bottom")},a={left:n("border-left-width"),right:n("border-right-width"),top:n("border-top-width"),bottom:n("border-bottom-width")},s=t.clientWidth,l=t.clientHeight,u=i.left+i.right,h=i.top+i.bottom,f=a.left+a.right,d=e.width/(s+f),p=s-u,m=l-h,g=e.left+i.left+a.left,y=e.top+i.top+a.top;return this.containerBB=[g,y,p,m,d]};qp.invalidateContainerClientCoordsCache=function(){this.containerBB=null};qp.findNearestElement=function(t,e,r,n){return this.findNearestElements(t,e,r,n)[0]};qp.findNearestElements=function(t,e,r,n){var i=this,a=this,s=a.getCachedZSortedEles(),l=[],u=a.cy.zoom(),h=a.cy.hasCompoundNodes(),f=(n?24:8)/u,d=(n?8:2)/u,p=(n?8:2)/u,m=1/0,g,y;r&&(s=s.interactive);function v(A,S){if(A.isNode()){if(y)return;y=A,l.push(A)}if(A.isEdge()&&(S==null||S<m))if(g){if(g.pstyle("z-compound-depth").value===A.pstyle("z-compound-depth").value&&g.pstyle("z-compound-depth").value===A.pstyle("z-compound-depth").value){for(var _=0;_<l.length;_++)if(l[_].isEdge()){l[_]=A,g=A,m=S??m;break}}}else l.push(A),g=A,m=S??m}o(v,"addEle");function x(A){var S=A.outerWidth()+2*d,_=A.outerHeight()+2*d,I=S/2,D=_/2,k=A.position(),L=A.pstyle("corner-radius").value==="auto"?"auto":A.pstyle("corner-radius").pfValue,R=A._private.rscratch;if(k.x-I<=t&&t<=k.x+I&&k.y-D<=e&&e<=k.y+D){var O=a.nodeShapes[i.getNodeShape(A)];if(O.checkPoint(t,e,0,S,_,k.x,k.y,L,R))return v(A,0),!0}}o(x,"checkNode");function b(A){var S=A._private,_=S.rscratch,I=A.pstyle("width").pfValue,D=A.pstyle("arrow-scale").value,k=I/2+f,L=k*k,R=k*2,F=S.source,P=S.target,O;if(_.edgeType==="segments"||_.edgeType==="straight"||_.edgeType==="haystack"){for(var M=_.allpts,B=0;B+3<M.length;B+=2)if(zqe(t,e,M[B],M[B+1],M[B+2],M[B+3],R)&&L>(O=Wqe(t,e,M[B],M[B+1],M[B+2],M[B+3])))return v(A,O),!0}else if(_.edgeType==="bezier"||_.edgeType==="multibezier"||_.edgeType==="self"||_.edgeType==="compound"){for(var M=_.allpts,B=0;B+5<_.allpts.length;B+=4)if(Gqe(t,e,M[B],M[B+1],M[B+2],M[B+3],M[B+4],M[B+5],R)&&L>(O=Hqe(t,e,M[B],M[B+1],M[B+2],M[B+3],M[B+4],M[B+5])))return v(A,O),!0}for(var F=F||S.source,P=P||S.target,z=i.getArrowWidth(I,D),$=[{name:"source",x:_.arrowStartX,y:_.arrowStartY,angle:_.srcArrowAngle},{name:"target",x:_.arrowEndX,y:_.arrowEndY,angle:_.tgtArrowAngle},{name:"mid-source",x:_.midX,y:_.midY,angle:_.midsrcArrowAngle},{name:"mid-target",x:_.midX,y:_.midY,angle:_.midtgtArrowAngle}],B=0;B<$.length;B++){var H=$[B],Q=a.arrowShapes[A.pstyle(H.name+"-arrow-shape").value],j=A.pstyle("width").pfValue;if(Q.roughCollide(t,e,z,H.angle,{x:H.x,y:H.y},j,f)&&Q.collide(t,e,z,H.angle,{x:H.x,y:H.y},j,f))return v(A),!0}h&&l.length>0&&(x(F),x(P))}o(b,"checkEdge");function w(A,S,_){return Gl(A,S,_)}o(w,"preprop");function C(A,S){var _=A._private,I=p,D;S?D=S+"-":D="",A.boundingBox();var k=_.labelBounds[S||"main"],L=A.pstyle(D+"label").value,R=A.pstyle("text-events").strValue==="yes";if(!(!R||!L)){var O=w(_.rscratch,"labelX",S),M=w(_.rscratch,"labelY",S),B=w(_.rscratch,"labelAngle",S),F=A.pstyle(D+"text-margin-x").pfValue,P=A.pstyle(D+"text-margin-y").pfValue,z=k.x1-I-F,$=k.x2+I-F,H=k.y1-I-P,Q=k.y2+I-P;if(B){var j=Math.cos(B),ie=Math.sin(B),ne=o(function(se,ue){return se=se-O,ue=ue-M,{x:se*j-ue*ie+O,y:se*ie+ue*j+M}},"rotate"),le=ne(z,H),he=ne(z,Q),K=ne($,H),X=ne($,Q),te=[le.x+F,le.y+P,K.x+F,K.y+P,X.x+F,X.y+P,he.x+F,he.y+P];if(Us(t,e,te))return v(A),!0}else if(K1(k,t,e))return v(A),!0}}o(C,"checkLabel");for(var T=s.length-1;T>=0;T--){var E=s[T];E.isNode()?x(E)||C(E):b(E)||C(E)||C(E,"source")||C(E,"target")}return l};qp.getAllInBox=function(t,e,r,n){var i=this.getCachedZSortedEles().interactive,a=[],s=Math.min(t,r),l=Math.max(t,r),u=Math.min(e,n),h=Math.max(e,n);t=s,r=l,e=u,n=h;for(var f=Hs({x1:t,y1:e,x2:r,y2:n}),d=0;d<i.length;d++){var p=i[d];if(p.isNode()){var m=p,g=m.boundingBox({includeNodes:!0,includeEdges:!1,includeLabels:!1});aB(f,g)&&!yme(g,f)&&a.push(m)}else{var y=p,v=y._private,x=v.rscratch;if(x.startX!=null&&x.startY!=null&&!K1(f,x.startX,x.startY)||x.endX!=null&&x.endY!=null&&!K1(f,x.endX,x.endY))continue;if(x.edgeType==="bezier"||x.edgeType==="multibezier"||x.edgeType==="self"||x.edgeType==="compound"||x.edgeType==="segments"||x.edgeType==="haystack"){for(var b=v.rstyle.bezierPts||v.rstyle.linePts||v.rstyle.haystackPts,w=!0,C=0;C<b.length;C++)if(!$qe(f,b[C])){w=!1;break}w&&a.push(y)}else(x.edgeType==="haystack"||x.edgeType==="straight")&&a.push(y)}}return a};AS={};AS.calculateArrowAngles=function(t){var e=t._private.rscratch,r=e.edgeType==="haystack",n=e.edgeType==="bezier",i=e.edgeType==="multibezier",a=e.edgeType==="segments",s=e.edgeType==="compound",l=e.edgeType==="self",u,h,f,d,p,m,x,b;if(r?(f=e.haystackPts[0],d=e.haystackPts[1],p=e.haystackPts[2],m=e.haystackPts[3]):(f=e.arrowStartX,d=e.arrowStartY,p=e.arrowEndX,m=e.arrowEndY),x=e.midX,b=e.midY,a)u=f-e.segpts[0],h=d-e.segpts[1];else if(i||s||l||n){var g=e.allpts,y=oa(g[0],g[2],g[4],.1),v=oa(g[1],g[3],g[5],.1);u=f-y,h=d-v}else u=f-x,h=d-b;e.srcArrowAngle=K6(u,h);var x=e.midX,b=e.midY;if(r&&(x=(f+p)/2,b=(d+m)/2),u=p-f,h=m-d,a){var g=e.allpts;if(g.length/2%2===0){var w=g.length/2,C=w-2;u=g[w]-g[C],h=g[w+1]-g[C+1]}else if(e.isRound)u=e.midVector[1],h=-e.midVector[0];else{var w=g.length/2-1,C=w-2;u=g[w]-g[C],h=g[w+1]-g[C+1]}}else if(i||s||l){var g=e.allpts,T=e.ctrlpts,E,A,S,_;if(T.length/2%2===0){var I=g.length/2-1,D=I+2,k=D+2;E=oa(g[I],g[D],g[k],0),A=oa(g[I+1],g[D+1],g[k+1],0),S=oa(g[I],g[D],g[k],1e-4),_=oa(g[I+1],g[D+1],g[k+1],1e-4)}else{var D=g.length/2-1,I=D-2,k=D+2;E=oa(g[I],g[D],g[k],.4999),A=oa(g[I+1],g[D+1],g[k+1],.4999),S=oa(g[I],g[D],g[k],.5),_=oa(g[I+1],g[D+1],g[k+1],.5)}u=S-E,h=_-A}if(e.midtgtArrowAngle=K6(u,h),e.midDispX=u,e.midDispY=h,u*=-1,h*=-1,a){var g=e.allpts;if(g.length/2%2!==0){if(!e.isRound){var w=g.length/2-1,L=w+2;u=-(g[L]-g[w]),h=-(g[L+1]-g[w+1])}}}if(e.midsrcArrowAngle=K6(u,h),a)u=p-e.segpts[e.segpts.length-2],h=m-e.segpts[e.segpts.length-1];else if(i||s||l||n){var g=e.allpts,R=g.length,y=oa(g[R-6],g[R-4],g[R-2],.9),v=oa(g[R-5],g[R-3],g[R-1],.9);u=p-y,h=m-v}else u=p-x,h=m-b;e.tgtArrowAngle=K6(u,h)};AS.getArrowWidth=AS.getArrowHeight=function(t,e){var r=this.arrowWidthCache=this.arrowWidthCache||{},n=r[t+", "+e];return n||(n=Math.max(Math.pow(t*13.37,.9),29)*e,r[t+", "+e]=n,n)};qc={},Jo={},L0e=o(function(e,r,n){n.x=r.x-e.x,n.y=r.y-e.y,n.len=Math.sqrt(n.x*n.x+n.y*n.y),n.nx=n.x/n.len,n.ny=n.y/n.len,n.ang=Math.atan2(n.ny,n.nx)},"asVec"),CQe=o(function(e,r){r.x=e.x*-1,r.y=e.y*-1,r.nx=e.nx*-1,r.ny=e.ny*-1,r.ang=e.ang>0?-(Math.PI-e.ang):Math.PI+e.ang},"invertVec"),AQe=o(function(e,r,n,i,a){if(e!==D0e?L0e(r,e,qc):CQe(Jo,qc),L0e(r,n,Jo),A0e=qc.nx*Jo.ny-qc.ny*Jo.nx,_0e=qc.nx*Jo.nx-qc.ny*-Jo.ny,Ku=Math.asin(Math.max(-1,Math.min(1,A0e))),Math.abs(Ku)<1e-6){HP=r.x,WP=r.y,Bp=G1=0;return}Fp=1,gS=!1,_0e<0?Ku<0?Ku=Math.PI+Ku:(Ku=Math.PI-Ku,Fp=-1,gS=!0):Ku>0&&(Fp=-1,gS=!0),r.radius!==void 0?G1=r.radius:G1=i,Mp=Ku/2,aS=Math.min(qc.len/2,Jo.len/2),a?(Wc=Math.abs(Math.cos(Mp)*G1/Math.sin(Mp)),Wc>aS?(Wc=aS,Bp=Math.abs(Wc*Math.sin(Mp)/Math.cos(Mp))):Bp=G1):(Wc=Math.min(aS,G1),Bp=Math.abs(Wc*Math.sin(Mp)/Math.cos(Mp))),qP=r.x+Jo.nx*Wc,YP=r.y+Jo.ny*Wc,HP=qP-Jo.ny*Bp*Fp,WP=YP+Jo.nx*Bp*Fp,cge=r.x+qc.nx*Wc,uge=r.y+qc.ny*Wc,D0e=r},"calcCornerArc");o(hge,"drawPreparedRoundCorner");o(vB,"getRoundCorner");Va={};Va.findMidptPtsEtc=function(t,e){var r=e.posPts,n=e.intersectionPts,i=e.vectorNormInverse,a,s=t.pstyle("source-endpoint"),l=t.pstyle("target-endpoint"),u=s.units!=null&&l.units!=null,h=o(function(T,E,A,S){var _=S-E,I=A-T,D=Math.sqrt(I*I+_*_);return{x:-_/D,y:I/D}},"recalcVectorNormInverse"),f=t.pstyle("edge-distances").value;switch(f){case"node-position":a=r;break;case"intersection":a=n;break;case"endpoints":{if(u){var d=this.manualEndptToPx(t.source()[0],s),p=_i(d,2),m=p[0],g=p[1],y=this.manualEndptToPx(t.target()[0],l),v=_i(y,2),x=v[0],b=v[1],w={x1:m,y1:g,x2:x,y2:b};i=h(m,g,x,b),a=w}else un("Edge ".concat(t.id()," has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")),a=n;break}}return{midptPts:a,vectorNormInverse:i}};Va.findHaystackPoints=function(t){for(var e=0;e<t.length;e++){var r=t[e],n=r._private,i=n.rscratch;if(!i.haystack){var a=Math.random()*2*Math.PI;i.source={x:Math.cos(a),y:Math.sin(a)},a=Math.random()*2*Math.PI,i.target={x:Math.cos(a),y:Math.sin(a)}}var s=n.source,l=n.target,u=s.position(),h=l.position(),f=s.width(),d=l.width(),p=s.height(),m=l.height(),g=r.pstyle("haystack-radius").value,y=g/2;i.haystackPts=i.allpts=[i.source.x*f*y+u.x,i.source.y*p*y+u.y,i.target.x*d*y+h.x,i.target.y*m*y+h.y],i.midX=(i.allpts[0]+i.allpts[2])/2,i.midY=(i.allpts[1]+i.allpts[3])/2,i.edgeType="haystack",i.haystack=!0,this.storeEdgeProjections(r),this.calculateArrowAngles(r),this.recalculateEdgeLabelProjections(r),this.calculateLabelAngles(r)}};Va.findSegmentsPoints=function(t,e){var r=t._private.rscratch,n=t.pstyle("segment-weights"),i=t.pstyle("segment-distances"),a=t.pstyle("segment-radii"),s=t.pstyle("radius-type"),l=Math.min(n.pfValue.length,i.pfValue.length),u=a.pfValue[a.pfValue.length-1],h=s.pfValue[s.pfValue.length-1];r.edgeType="segments",r.segpts=[],r.radii=[],r.isArcRadius=[];for(var f=0;f<l;f++){var d=n.pfValue[f],p=i.pfValue[f],m=1-d,g=d,y=this.findMidptPtsEtc(t,e),v=y.midptPts,x=y.vectorNormInverse,b={x:v.x1*m+v.x2*g,y:v.y1*m+v.y2*g};r.segpts.push(b.x+x.x*p,b.y+x.y*p),r.radii.push(a.pfValue[f]!==void 0?a.pfValue[f]:u),r.isArcRadius.push((s.pfValue[f]!==void 0?s.pfValue[f]:h)==="arc-radius")}};Va.findLoopPoints=function(t,e,r,n){var i=t._private.rscratch,a=e.dirCounts,s=e.srcPos,l=t.pstyle("control-point-distances"),u=l?l.pfValue[0]:void 0,h=t.pstyle("loop-direction").pfValue,f=t.pstyle("loop-sweep").pfValue,d=t.pstyle("control-point-step-size").pfValue;i.edgeType="self";var p=r,m=d;n&&(p=0,m=u);var g=h-Math.PI/2,y=g-f/2,v=g+f/2,x=h+"_"+f;p=a[x]===void 0?a[x]=0:++a[x],i.ctrlpts=[s.x+Math.cos(y)*1.4*m*(p/3+1),s.y+Math.sin(y)*1.4*m*(p/3+1),s.x+Math.cos(v)*1.4*m*(p/3+1),s.y+Math.sin(v)*1.4*m*(p/3+1)]};Va.findCompoundLoopPoints=function(t,e,r,n){var i=t._private.rscratch;i.edgeType="compound";var a=e.srcPos,s=e.tgtPos,l=e.srcW,u=e.srcH,h=e.tgtW,f=e.tgtH,d=t.pstyle("control-point-step-size").pfValue,p=t.pstyle("control-point-distances"),m=p?p.pfValue[0]:void 0,g=r,y=d;n&&(g=0,y=m);var v=50,x={x:a.x-l/2,y:a.y-u/2},b={x:s.x-h/2,y:s.y-f/2},w={x:Math.min(x.x,b.x),y:Math.min(x.y,b.y)},C=.5,T=Math.max(C,Math.log(l*.01)),E=Math.max(C,Math.log(h*.01));i.ctrlpts=[w.x,w.y-(1+Math.pow(v,1.12)/100)*y*(g/3+1)*T,w.x-(1+Math.pow(v,1.12)/100)*y*(g/3+1)*E,w.y]};Va.findStraightEdgePoints=function(t){t._private.rscratch.edgeType="straight"};Va.findBezierPoints=function(t,e,r,n,i){var a=t._private.rscratch,s=t.pstyle("control-point-step-size").pfValue,l=t.pstyle("control-point-distances"),u=t.pstyle("control-point-weights"),h=l&&u?Math.min(l.value.length,u.value.length):1,f=l?l.pfValue[0]:void 0,d=u.value[0],p=n;a.edgeType=p?"multibezier":"bezier",a.ctrlpts=[];for(var m=0;m<h;m++){var g=(.5-e.eles.length/2+r)*s*(i?-1:1),y=void 0,v=mme(g);p&&(f=l?l.pfValue[m]:s,d=u.value[m]),n?y=f:y=f!==void 0?v*f:void 0;var x=y!==void 0?y:g,b=1-d,w=d,C=this.findMidptPtsEtc(t,e),T=C.midptPts,E=C.vectorNormInverse,A={x:T.x1*b+T.x2*w,y:T.y1*b+T.y2*w};a.ctrlpts.push(A.x+E.x*x,A.y+E.y*x)}};Va.findTaxiPoints=function(t,e){var r=t._private.rscratch;r.edgeType="segments";var n="vertical",i="horizontal",a="leftward",s="rightward",l="downward",u="upward",h="auto",f=e.posPts,d=e.srcW,p=e.srcH,m=e.tgtW,g=e.tgtH,y=t.pstyle("edge-distances").value,v=y!=="node-position",x=t.pstyle("taxi-direction").value,b=x,w=t.pstyle("taxi-turn"),C=w.units==="%",T=w.pfValue,E=T<0,A=t.pstyle("taxi-turn-min-distance").pfValue,S=v?(d+m)/2:0,_=v?(p+g)/2:0,I=f.x2-f.x1,D=f.y2-f.y1,k=o(function(q,pe){return q>0?Math.max(q-pe,0):Math.min(q+pe,0)},"subDWH"),L=k(I,S),R=k(D,_),O=!1;b===h?x=Math.abs(L)>Math.abs(R)?i:n:b===u||b===l?(x=n,O=!0):(b===a||b===s)&&(x=i,O=!0);var M=x===n,B=M?R:L,F=M?D:I,P=mme(F),z=!1;!(O&&(C||E))&&(b===l&&F<0||b===u&&F>0||b===a&&F>0||b===s&&F<0)&&(P*=-1,B=P*Math.abs(B),z=!0);var $;if(C){var H=T<0?1+T:T;$=H*B}else{var Q=T<0?B:0;$=Q+T*P}var j=o(function(q){return Math.abs(q)<A||Math.abs(q)>=Math.abs(B)},"getIsTooClose"),ie=j($),ne=j(Math.abs(B)-Math.abs($)),le=ie||ne;if(le&&!z)if(M){var he=Math.abs(F)<=p/2,K=Math.abs(I)<=m/2;if(he){var X=(f.x1+f.x2)/2,te=f.y1,J=f.y2;r.segpts=[X,te,X,J]}else if(K){var se=(f.y1+f.y2)/2,ue=f.x1,Z=f.x2;r.segpts=[ue,se,Z,se]}else r.segpts=[f.x1,f.y2]}else{var Se=Math.abs(F)<=d/2,ce=Math.abs(D)<=g/2;if(Se){var ae=(f.y1+f.y2)/2,Oe=f.x1,ge=f.x2;r.segpts=[Oe,ae,ge,ae]}else if(ce){var ze=(f.x1+f.x2)/2,He=f.y1,$e=f.y2;r.segpts=[ze,He,ze,$e]}else r.segpts=[f.x2,f.y1]}else if(M){var Re=f.y1+$+(v?p/2*P:0),Ie=f.x1,be=f.x2;r.segpts=[Ie,Re,be,Re]}else{var W=f.x1+$+(v?d/2*P:0),de=f.y1,re=f.y2;r.segpts=[W,de,W,re]}if(r.isRound){var oe=t.pstyle("taxi-radius").value,V=t.pstyle("radius-type").value[0]==="arc-radius";r.radii=new Array(r.segpts.length/2).fill(oe),r.isArcRadius=new Array(r.segpts.length/2).fill(V)}};Va.tryToCorrectInvalidPoints=function(t,e){var r=t._private.rscratch;if(r.edgeType==="bezier"){var n=e.srcPos,i=e.tgtPos,a=e.srcW,s=e.srcH,l=e.tgtW,u=e.tgtH,h=e.srcShape,f=e.tgtShape,d=e.srcCornerRadius,p=e.tgtCornerRadius,m=e.srcRs,g=e.tgtRs,y=!Ct(r.startX)||!Ct(r.startY),v=!Ct(r.arrowStartX)||!Ct(r.arrowStartY),x=!Ct(r.endX)||!Ct(r.endY),b=!Ct(r.arrowEndX)||!Ct(r.arrowEndY),w=3,C=this.getArrowWidth(t.pstyle("width").pfValue,t.pstyle("arrow-scale").value)*this.arrowShapeWidth,T=w*C,E=Gp({x:r.ctrlpts[0],y:r.ctrlpts[1]},{x:r.startX,y:r.startY}),A=E<T,S=Gp({x:r.ctrlpts[0],y:r.ctrlpts[1]},{x:r.endX,y:r.endY}),_=S<T,I=!1;if(y||v||A){I=!0;var D={x:r.ctrlpts[0]-n.x,y:r.ctrlpts[1]-n.y},k=Math.sqrt(D.x*D.x+D.y*D.y),L={x:D.x/k,y:D.y/k},R=Math.max(a,s),O={x:r.ctrlpts[0]+L.x*2*R,y:r.ctrlpts[1]+L.y*2*R},M=h.intersectLine(n.x,n.y,a,s,O.x,O.y,0,d,m);A?(r.ctrlpts[0]=r.ctrlpts[0]+L.x*(T-E),r.ctrlpts[1]=r.ctrlpts[1]+L.y*(T-E)):(r.ctrlpts[0]=M[0]+L.x*T,r.ctrlpts[1]=M[1]+L.y*T)}if(x||b||_){I=!0;var B={x:r.ctrlpts[0]-i.x,y:r.ctrlpts[1]-i.y},F=Math.sqrt(B.x*B.x+B.y*B.y),P={x:B.x/F,y:B.y/F},z=Math.max(a,s),$={x:r.ctrlpts[0]+P.x*2*z,y:r.ctrlpts[1]+P.y*2*z},H=f.intersectLine(i.x,i.y,l,u,$.x,$.y,0,p,g);_?(r.ctrlpts[0]=r.ctrlpts[0]+P.x*(T-S),r.ctrlpts[1]=r.ctrlpts[1]+P.y*(T-S)):(r.ctrlpts[0]=H[0]+P.x*T,r.ctrlpts[1]=H[1]+P.y*T)}I&&this.findEndpoints(t)}};Va.storeAllpts=function(t){var e=t._private.rscratch;if(e.edgeType==="multibezier"||e.edgeType==="bezier"||e.edgeType==="self"||e.edgeType==="compound"){e.allpts=[],e.allpts.push(e.startX,e.startY);for(var r=0;r+1<e.ctrlpts.length;r+=2)e.allpts.push(e.ctrlpts[r],e.ctrlpts[r+1]),r+3<e.ctrlpts.length&&e.allpts.push((e.ctrlpts[r]+e.ctrlpts[r+2])/2,(e.ctrlpts[r+1]+e.ctrlpts[r+3])/2);e.allpts.push(e.endX,e.endY);var n,i;e.ctrlpts.length/2%2===0?(n=e.allpts.length/2-1,e.midX=e.allpts[n],e.midY=e.allpts[n+1]):(n=e.allpts.length/2-3,i=.5,e.midX=oa(e.allpts[n],e.allpts[n+2],e.allpts[n+4],i),e.midY=oa(e.allpts[n+1],e.allpts[n+3],e.allpts[n+5],i))}else if(e.edgeType==="straight")e.allpts=[e.startX,e.startY,e.endX,e.endY],e.midX=(e.startX+e.endX+e.arrowStartX+e.arrowEndX)/4,e.midY=(e.startY+e.endY+e.arrowStartY+e.arrowEndY)/4;else if(e.edgeType==="segments"){if(e.allpts=[],e.allpts.push(e.startX,e.startY),e.allpts.push.apply(e.allpts,e.segpts),e.allpts.push(e.endX,e.endY),e.isRound){e.roundCorners=[];for(var a=2;a+3<e.allpts.length;a+=2){var s=e.radii[a/2-1],l=e.isArcRadius[a/2-1];e.roundCorners.push(vB({x:e.allpts[a-2],y:e.allpts[a-1]},{x:e.allpts[a],y:e.allpts[a+1],radius:s},{x:e.allpts[a+2],y:e.allpts[a+3]},s,l))}}if(e.segpts.length%4===0){var u=e.segpts.length/2,h=u-2;e.midX=(e.segpts[h]+e.segpts[u])/2,e.midY=(e.segpts[h+1]+e.segpts[u+1])/2}else{var f=e.segpts.length/2-1;if(!e.isRound)e.midX=e.segpts[f],e.midY=e.segpts[f+1];else{var d={x:e.segpts[f],y:e.segpts[f+1]},p=e.roundCorners[f/2],m=[d.x-p.cx,d.y-p.cy],g=p.radius/Math.sqrt(Math.pow(m[0],2)+Math.pow(m[1],2));m=m.map(function(y){return y*g}),e.midX=p.cx+m[0],e.midY=p.cy+m[1],e.midVector=m}}}};Va.checkForInvalidEdgeWarning=function(t){var e=t[0]._private.rscratch;e.nodesOverlap||Ct(e.startX)&&Ct(e.startY)&&Ct(e.endX)&&Ct(e.endY)?e.loggedErr=!1:e.loggedErr||(e.loggedErr=!0,un("Edge `"+t.id()+"` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap."))};Va.findEdgeControlPoints=function(t){var e=this;if(!(!t||t.length===0)){for(var r=this,n=r.cy,i=n.hasCompoundNodes(),a={map:new Xc,get:o(function(A){var S=this.map.get(A[0]);return S!=null?S.get(A[1]):null},"get"),set:o(function(A,S){var _=this.map.get(A[0]);_==null&&(_=new Xc,this.map.set(A[0],_)),_.set(A[1],S)},"set")},s=[],l=[],u=0;u<t.length;u++){var h=t[u],f=h._private,d=h.pstyle("curve-style").value;if(!(h.removed()||!h.takesUpSpace())){if(d==="haystack"){l.push(h);continue}var p=d==="unbundled-bezier"||d.endsWith("segments")||d==="straight"||d==="straight-triangle"||d.endsWith("taxi"),m=d==="unbundled-bezier"||d==="bezier",g=f.source,y=f.target,v=g.poolIndex(),x=y.poolIndex(),b=[v,x].sort(),w=a.get(b);w==null&&(w={eles:[]},a.set(b,w),s.push(b)),w.eles.push(h),p&&(w.hasUnbundled=!0),m&&(w.hasBezier=!0)}}for(var C=o(function(A){var S=s[A],_=a.get(S),I=void 0;if(!_.hasUnbundled){var D=_.eles[0].parallelEdges().filter(function(W){return W.isBundledBezier()});nB(_.eles),D.forEach(function(W){return _.eles.push(W)}),_.eles.sort(function(W,de){return W.poolIndex()-de.poolIndex()})}var k=_.eles[0],L=k.source(),R=k.target();if(L.poolIndex()>R.poolIndex()){var O=L;L=R,R=O}var M=_.srcPos=L.position(),B=_.tgtPos=R.position(),F=_.srcW=L.outerWidth(),P=_.srcH=L.outerHeight(),z=_.tgtW=R.outerWidth(),$=_.tgtH=R.outerHeight(),H=_.srcShape=r.nodeShapes[e.getNodeShape(L)],Q=_.tgtShape=r.nodeShapes[e.getNodeShape(R)],j=_.srcCornerRadius=L.pstyle("corner-radius").value==="auto"?"auto":L.pstyle("corner-radius").pfValue,ie=_.tgtCornerRadius=R.pstyle("corner-radius").value==="auto"?"auto":R.pstyle("corner-radius").pfValue,ne=_.tgtRs=R._private.rscratch,le=_.srcRs=L._private.rscratch;_.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var he=0;he<_.eles.length;he++){var K=_.eles[he],X=K[0]._private.rscratch,te=K.pstyle("curve-style").value,J=te==="unbundled-bezier"||te.endsWith("segments")||te.endsWith("taxi"),se=!L.same(K.source());if(!_.calculatedIntersection&&L!==R&&(_.hasBezier||_.hasUnbundled)){_.calculatedIntersection=!0;var ue=H.intersectLine(M.x,M.y,F,P,B.x,B.y,0,j,le),Z=_.srcIntn=ue,Se=Q.intersectLine(B.x,B.y,z,$,M.x,M.y,0,ie,ne),ce=_.tgtIntn=Se,ae=_.intersectionPts={x1:ue[0],x2:Se[0],y1:ue[1],y2:Se[1]},Oe=_.posPts={x1:M.x,x2:B.x,y1:M.y,y2:B.y},ge=Se[1]-ue[1],ze=Se[0]-ue[0],He=Math.sqrt(ze*ze+ge*ge),$e=_.vector={x:ze,y:ge},Re=_.vectorNorm={x:$e.x/He,y:$e.y/He},Ie={x:-Re.y,y:Re.x};_.nodesOverlap=!Ct(He)||Q.checkPoint(ue[0],ue[1],0,z,$,B.x,B.y,ie,ne)||H.checkPoint(Se[0],Se[1],0,F,P,M.x,M.y,j,le),_.vectorNormInverse=Ie,I={nodesOverlap:_.nodesOverlap,dirCounts:_.dirCounts,calculatedIntersection:!0,hasBezier:_.hasBezier,hasUnbundled:_.hasUnbundled,eles:_.eles,srcPos:B,srcRs:ne,tgtPos:M,tgtRs:le,srcW:z,srcH:$,tgtW:F,tgtH:P,srcIntn:ce,tgtIntn:Z,srcShape:Q,tgtShape:H,posPts:{x1:Oe.x2,y1:Oe.y2,x2:Oe.x1,y2:Oe.y1},intersectionPts:{x1:ae.x2,y1:ae.y2,x2:ae.x1,y2:ae.y1},vector:{x:-$e.x,y:-$e.y},vectorNorm:{x:-Re.x,y:-Re.y},vectorNormInverse:{x:-Ie.x,y:-Ie.y}}}var be=se?I:_;X.nodesOverlap=be.nodesOverlap,X.srcIntn=be.srcIntn,X.tgtIntn=be.tgtIntn,X.isRound=te.startsWith("round"),i&&(L.isParent()||L.isChild()||R.isParent()||R.isChild())&&(L.parents().anySame(R)||R.parents().anySame(L)||L.same(R)&&L.isParent())?e.findCompoundLoopPoints(K,be,he,J):L===R?e.findLoopPoints(K,be,he,J):te.endsWith("segments")?e.findSegmentsPoints(K,be):te.endsWith("taxi")?e.findTaxiPoints(K,be):te==="straight"||!J&&_.eles.length%2===1&&he===Math.floor(_.eles.length/2)?e.findStraightEdgePoints(K):e.findBezierPoints(K,be,he,J,se),e.findEndpoints(K),e.tryToCorrectInvalidPoints(K,be),e.checkForInvalidEdgeWarning(K),e.storeAllpts(K),e.storeEdgeProjections(K),e.calculateArrowAngles(K),e.recalculateEdgeLabelProjections(K),e.calculateLabelAngles(K)}},"_loop"),T=0;T<s.length;T++)C(T);this.findHaystackPoints(l)}};o(fge,"getPts");Va.getSegmentPoints=function(t){var e=t[0]._private.rscratch;this.recalculateRenderedStyle(t);var r=e.edgeType;if(r==="segments")return fge(e.segpts)};Va.getControlPoints=function(t){var e=t[0]._private.rscratch;this.recalculateRenderedStyle(t);var r=e.edgeType;if(r==="bezier"||r==="multibezier"||r==="self"||r==="compound")return fge(e.ctrlpts)};Va.getEdgeMidpoint=function(t){var e=t[0]._private.rscratch;return this.recalculateRenderedStyle(t),{x:e.midX,y:e.midY}};o4={};o4.manualEndptToPx=function(t,e){var r=this,n=t.position(),i=t.outerWidth(),a=t.outerHeight(),s=t._private.rscratch;if(e.value.length===2){var l=[e.pfValue[0],e.pfValue[1]];return e.units[0]==="%"&&(l[0]=l[0]*i),e.units[1]==="%"&&(l[1]=l[1]*a),l[0]+=n.x,l[1]+=n.y,l}else{var u=e.pfValue[0];u=-Math.PI/2+u;var h=2*Math.max(i,a),f=[n.x+Math.cos(u)*h,n.y+Math.sin(u)*h];return r.nodeShapes[this.getNodeShape(t)].intersectLine(n.x,n.y,i,a,f[0],f[1],0,t.pstyle("corner-radius").value==="auto"?"auto":t.pstyle("corner-radius").pfValue,s)}};o4.findEndpoints=function(t){var e=this,r,n=t.source()[0],i=t.target()[0],a=n.position(),s=i.position(),l=t.pstyle("target-arrow-shape").value,u=t.pstyle("source-arrow-shape").value,h=t.pstyle("target-distance-from-node").pfValue,f=t.pstyle("source-distance-from-node").pfValue,d=n._private.rscratch,p=i._private.rscratch,m=t.pstyle("curve-style").value,g=t._private.rscratch,y=g.edgeType,v=m==="taxi",x=y==="self"||y==="compound",b=y==="bezier"||y==="multibezier"||x,w=y!=="bezier",C=y==="straight"||y==="segments",T=y==="segments",E=b||w||C,A=x||v,S=t.pstyle("source-endpoint"),_=A?"outside-to-node":S.value,I=n.pstyle("corner-radius").value==="auto"?"auto":n.pstyle("corner-radius").pfValue,D=t.pstyle("target-endpoint"),k=A?"outside-to-node":D.value,L=i.pstyle("corner-radius").value==="auto"?"auto":i.pstyle("corner-radius").pfValue;g.srcManEndpt=S,g.tgtManEndpt=D;var R,O,M,B;if(b){var F=[g.ctrlpts[0],g.ctrlpts[1]],P=w?[g.ctrlpts[g.ctrlpts.length-2],g.ctrlpts[g.ctrlpts.length-1]]:F;R=P,O=F}else if(C){var z=T?g.segpts.slice(0,2):[s.x,s.y],$=T?g.segpts.slice(g.segpts.length-2):[a.x,a.y];R=$,O=z}if(k==="inside-to-node")r=[s.x,s.y];else if(D.units)r=this.manualEndptToPx(i,D);else if(k==="outside-to-line")r=g.tgtIntn;else if(k==="outside-to-node"||k==="outside-to-node-or-label"?M=R:(k==="outside-to-line"||k==="outside-to-line-or-label")&&(M=[a.x,a.y]),r=e.nodeShapes[this.getNodeShape(i)].intersectLine(s.x,s.y,i.outerWidth(),i.outerHeight(),M[0],M[1],0,L,p),k==="outside-to-node-or-label"||k==="outside-to-line-or-label"){var H=i._private.rscratch,Q=H.labelWidth,j=H.labelHeight,ie=H.labelX,ne=H.labelY,le=Q/2,he=j/2,K=i.pstyle("text-valign").value;K==="top"?ne-=he:K==="bottom"&&(ne+=he);var X=i.pstyle("text-halign").value;X==="left"?ie-=le:X==="right"&&(ie+=le);var te=Xb(M[0],M[1],[ie-le,ne-he,ie+le,ne-he,ie+le,ne+he,ie-le,ne+he],s.x,s.y);if(te.length>0){var J=a,se=Op(J,U1(r)),ue=Op(J,U1(te)),Z=se;if(ue<se&&(r=te,Z=ue),te.length>2){var Se=Op(J,{x:te[2],y:te[3]});Se<Z&&(r=[te[2],te[3]])}}}var ce=Q6(r,R,e.arrowShapes[l].spacing(t)+h),ae=Q6(r,R,e.arrowShapes[l].gap(t)+h);if(g.endX=ae[0],g.endY=ae[1],g.arrowEndX=ce[0],g.arrowEndY=ce[1],_==="inside-to-node")r=[a.x,a.y];else if(S.units)r=this.manualEndptToPx(n,S);else if(_==="outside-to-line")r=g.srcIntn;else if(_==="outside-to-node"||_==="outside-to-node-or-label"?B=O:(_==="outside-to-line"||_==="outside-to-line-or-label")&&(B=[s.x,s.y]),r=e.nodeShapes[this.getNodeShape(n)].intersectLine(a.x,a.y,n.outerWidth(),n.outerHeight(),B[0],B[1],0,I,d),_==="outside-to-node-or-label"||_==="outside-to-line-or-label"){var Oe=n._private.rscratch,ge=Oe.labelWidth,ze=Oe.labelHeight,He=Oe.labelX,$e=Oe.labelY,Re=ge/2,Ie=ze/2,be=n.pstyle("text-valign").value;be==="top"?$e-=Ie:be==="bottom"&&($e+=Ie);var W=n.pstyle("text-halign").value;W==="left"?He-=Re:W==="right"&&(He+=Re);var de=Xb(B[0],B[1],[He-Re,$e-Ie,He+Re,$e-Ie,He+Re,$e+Ie,He-Re,$e+Ie],a.x,a.y);if(de.length>0){var re=s,oe=Op(re,U1(r)),V=Op(re,U1(de)),xe=oe;if(V<oe&&(r=[de[0],de[1]],xe=V),de.length>2){var q=Op(re,{x:de[2],y:de[3]});q<xe&&(r=[de[2],de[3]])}}}var pe=Q6(r,O,e.arrowShapes[u].spacing(t)+f),ve=Q6(r,O,e.arrowShapes[u].gap(t)+f);g.startX=ve[0],g.startY=ve[1],g.arrowStartX=pe[0],g.arrowStartY=pe[1],E&&(!Ct(g.startX)||!Ct(g.startY)||!Ct(g.endX)||!Ct(g.endY)?g.badLine=!0:g.badLine=!1)};o4.getSourceEndpoint=function(t){var e=t[0]._private.rscratch;switch(this.recalculateRenderedStyle(t),e.edgeType){case"haystack":return{x:e.haystackPts[0],y:e.haystackPts[1]};default:return{x:e.arrowStartX,y:e.arrowStartY}}};o4.getTargetEndpoint=function(t){var e=t[0]._private.rscratch;switch(this.recalculateRenderedStyle(t),e.edgeType){case"haystack":return{x:e.haystackPts[2],y:e.haystackPts[3]};default:return{x:e.arrowEndX,y:e.arrowEndY}}};xB={};o(_Qe,"pushBezierPts");xB.storeEdgeProjections=function(t){var e=t._private,r=e.rscratch,n=r.edgeType;if(e.rstyle.bezierPts=null,e.rstyle.linePts=null,e.rstyle.haystackPts=null,n==="multibezier"||n==="bezier"||n==="self"||n==="compound"){e.rstyle.bezierPts=[];for(var i=0;i+5<r.allpts.length;i+=4)_Qe(this,t,r.allpts.slice(i,i+6))}else if(n==="segments")for(var a=e.rstyle.linePts=[],i=0;i+1<r.allpts.length;i+=2)a.push({x:r.allpts[i],y:r.allpts[i+1]});else if(n==="haystack"){var s=r.haystackPts;e.rstyle.haystackPts=[{x:s[0],y:s[1]},{x:s[2],y:s[3]}]}e.rstyle.arrowWidth=this.getArrowWidth(t.pstyle("width").pfValue,t.pstyle("arrow-scale").value)*this.arrowShapeWidth};xB.recalculateEdgeProjections=function(t){this.findEdgeControlPoints(t)};Kc={};Kc.recalculateNodeLabelProjection=function(t){var e=t.pstyle("label").strValue;if(!Af(e)){var r,n,i=t._private,a=t.width(),s=t.height(),l=t.padding(),u=t.position(),h=t.pstyle("text-halign").strValue,f=t.pstyle("text-valign").strValue,d=i.rscratch,p=i.rstyle;switch(h){case"left":r=u.x-a/2-l;break;case"right":r=u.x+a/2+l;break;default:r=u.x}switch(f){case"top":n=u.y-s/2-l;break;case"bottom":n=u.y+s/2+l;break;default:n=u.y}d.labelX=r,d.labelY=n,p.labelX=r,p.labelY=n,this.calculateLabelAngles(t),this.applyLabelDimensions(t)}};dge=o(function(e,r){var n=Math.atan(r/e);return e===0&&n<0&&(n=n*-1),n},"lineAngleFromDelta"),pge=o(function(e,r){var n=r.x-e.x,i=r.y-e.y;return dge(n,i)},"lineAngle"),DQe=o(function(e,r,n,i){var a=Yb(0,i-.001,1),s=Yb(0,i+.001,1),l=W1(e,r,n,a),u=W1(e,r,n,s);return pge(l,u)},"bezierAngle");Kc.recalculateEdgeLabelProjections=function(t){var e,r=t._private,n=r.rscratch,i=this,a={mid:t.pstyle("label").strValue,source:t.pstyle("source-label").strValue,target:t.pstyle("target-label").strValue};if(a.mid||a.source||a.target){e={x:n.midX,y:n.midY};var s=o(function(d,p,m){kf(r.rscratch,d,p,m),kf(r.rstyle,d,p,m)},"setRs");s("labelX",null,e.x),s("labelY",null,e.y);var l=dge(n.midDispX,n.midDispY);s("labelAutoAngle",null,l);var u=o(function f(){if(f.cache)return f.cache;for(var d=[],p=0;p+5<n.allpts.length;p+=4){var m={x:n.allpts[p],y:n.allpts[p+1]},g={x:n.allpts[p+2],y:n.allpts[p+3]},y={x:n.allpts[p+4],y:n.allpts[p+5]};d.push({p0:m,p1:g,p2:y,startDist:0,length:0,segments:[]})}var v=r.rstyle.bezierPts,x=i.bezierProjPcts.length;function b(A,S,_,I,D){var k=Gp(S,_),L=A.segments[A.segments.length-1],R={p0:S,p1:_,t0:I,t1:D,startDist:L?L.startDist+L.length:0,length:k};A.segments.push(R),A.length+=k}o(b,"addSegment");for(var w=0;w<d.length;w++){var C=d[w],T=d[w-1];T&&(C.startDist=T.startDist+T.length),b(C,C.p0,v[w*x],0,i.bezierProjPcts[0]);for(var E=0;E<x-1;E++)b(C,v[w*x+E],v[w*x+E+1],i.bezierProjPcts[E],i.bezierProjPcts[E+1]);b(C,v[w*x+x-1],C.p2,i.bezierProjPcts[x-1],1)}return f.cache=d},"createControlPointInfo"),h=o(function(d){var p,m=d==="source";if(a[d]){var g=t.pstyle(d+"-text-offset").pfValue;switch(n.edgeType){case"self":case"compound":case"bezier":case"multibezier":{for(var y=u(),v,x=0,b=0,w=0;w<y.length;w++){for(var C=y[m?w:y.length-1-w],T=0;T<C.segments.length;T++){var E=C.segments[m?T:C.segments.length-1-T],A=w===y.length-1&&T===C.segments.length-1;if(x=b,b+=E.length,b>=g||A){v={cp:C,segment:E};break}}if(v)break}var S=v.cp,_=v.segment,I=(g-x)/_.length,D=_.t1-_.t0,k=m?_.t0+D*I:_.t1-D*I;k=Yb(0,k,1),e=W1(S.p0,S.p1,S.p2,k),p=DQe(S.p0,S.p1,S.p2,k);break}case"straight":case"segments":case"haystack":{for(var L=0,R,O,M,B,F=n.allpts.length,P=0;P+3<F&&(m?(M={x:n.allpts[P],y:n.allpts[P+1]},B={x:n.allpts[P+2],y:n.allpts[P+3]}):(M={x:n.allpts[F-2-P],y:n.allpts[F-1-P]},B={x:n.allpts[F-4-P],y:n.allpts[F-3-P]}),R=Gp(M,B),O=L,L+=R,!(L>=g));P+=2);var z=g-O,$=z/R;$=Yb(0,$,1),e=Iqe(M,B,$),p=pge(M,B);break}}s("labelX",d,e.x),s("labelY",d,e.y),s("labelAutoAngle",d,p)}},"calculateEndProjection");h("source"),h("target"),this.applyLabelDimensions(t)}};Kc.applyLabelDimensions=function(t){this.applyPrefixedLabelDimensions(t),t.isEdge()&&(this.applyPrefixedLabelDimensions(t,"source"),this.applyPrefixedLabelDimensions(t,"target"))};Kc.applyPrefixedLabelDimensions=function(t,e){var r=t._private,n=this.getLabelText(t,e),i=this.calculateLabelDimensions(t,n),a=t.pstyle("line-height").pfValue,s=t.pstyle("text-wrap").strValue,l=Gl(r.rscratch,"labelWrapCachedLines",e)||[],u=s!=="wrap"?1:Math.max(l.length,1),h=i.height/u,f=h*a,d=i.width,p=i.height+(u-1)*(a-1)*h;kf(r.rstyle,"labelWidth",e,d),kf(r.rscratch,"labelWidth",e,d),kf(r.rstyle,"labelHeight",e,p),kf(r.rscratch,"labelHeight",e,p),kf(r.rscratch,"labelLineHeight",e,f)};Kc.getLabelText=function(t,e){var r=t._private,n=e?e+"-":"",i=t.pstyle(n+"label").strValue,a=t.pstyle("text-transform").value,s=o(function(Q,j){return j?(kf(r.rscratch,Q,e,j),j):Gl(r.rscratch,Q,e)},"rscratch");if(!i)return"";a=="none"||(a=="uppercase"?i=i.toUpperCase():a=="lowercase"&&(i=i.toLowerCase()));var l=t.pstyle("text-wrap").value;if(l==="wrap"){var u=s("labelKey");if(u!=null&&s("labelWrapKey")===u)return s("labelWrapCachedText");for(var h="\u200B",f=i.split(`
+`),d=t.pstyle("text-max-width").pfValue,p=t.pstyle("text-overflow-wrap").value,m=p==="anywhere",g=[],y=/[\s\u200b]+|$/g,v=0;v<f.length;v++){var x=f[v],b=this.calculateLabelDimensions(t,x),w=b.width;if(m){var C=x.split("").join(h);x=C}if(w>d){var T=x.matchAll(y),E="",A=0,S=mo(T),_;try{for(S.s();!(_=S.n()).done;){var I=_.value,D=I[0],k=x.substring(A,I.index);A=I.index+D.length;var L=E.length===0?k:E+k+D,R=this.calculateLabelDimensions(t,L),O=R.width;O<=d?E+=k+D:(E&&g.push(E),E=k+D)}}catch(H){S.e(H)}finally{S.f()}E.match(/^[\s\u200b]+$/)||g.push(E)}else g.push(x)}s("labelWrapCachedLines",g),i=s("labelWrapCachedText",g.join(`
+`)),s("labelWrapKey",u)}else if(l==="ellipsis"){var M=t.pstyle("text-max-width").pfValue,B="",F="\u2026",P=!1;if(this.calculateLabelDimensions(t,i).width<M)return i;for(var z=0;z<i.length;z++){var $=this.calculateLabelDimensions(t,B+i[z]+F).width;if($>M)break;B+=i[z],z===i.length-1&&(P=!0)}return P||(B+=F),B}return i};Kc.getLabelJustification=function(t){var e=t.pstyle("text-justification").strValue,r=t.pstyle("text-halign").strValue;if(e==="auto")if(t.isNode())switch(r){case"left":return"right";case"right":return"left";default:return"center"}else return"center";else return e};Kc.calculateLabelDimensions=function(t,e){var r=this,n=r.cy.window(),i=n.document,a=_f(e,t._private.labelDimsKey),s=r.labelDimCache||(r.labelDimCache=[]),l=s[a];if(l!=null)return l;var u=0,h=t.pstyle("font-style").strValue,f=t.pstyle("font-size").pfValue,d=t.pstyle("font-family").strValue,p=t.pstyle("font-weight").strValue,m=this.labelCalcCanvas,g=this.labelCalcCanvasContext;if(!m){m=this.labelCalcCanvas=i.createElement("canvas"),g=this.labelCalcCanvasContext=m.getContext("2d");var y=m.style;y.position="absolute",y.left="-9999px",y.top="-9999px",y.zIndex="-1",y.visibility="hidden",y.pointerEvents="none"}g.font="".concat(h," ").concat(p," ").concat(f,"px ").concat(d);for(var v=0,x=0,b=e.split(`
+`),w=0;w<b.length;w++){var C=b[w],T=g.measureText(C),E=Math.ceil(T.width),A=f;v=Math.max(E,v),x+=A}return v+=u,x+=u,s[a]={width:v,height:x}};Kc.calculateLabelAngle=function(t,e){var r=t._private,n=r.rscratch,i=t.isEdge(),a=e?e+"-":"",s=t.pstyle(a+"text-rotation"),l=s.strValue;return l==="none"?0:i&&l==="autorotate"?n.labelAutoAngle:l==="autorotate"?0:s.pfValue};Kc.calculateLabelAngles=function(t){var e=this,r=t.isEdge(),n=t._private,i=n.rscratch;i.labelAngle=e.calculateLabelAngle(t),r&&(i.sourceLabelAngle=e.calculateLabelAngle(t,"source"),i.targetLabelAngle=e.calculateLabelAngle(t,"target"))};mge={},R0e=28,N0e=!1;mge.getNodeShape=function(t){var e=this,r=t.pstyle("shape").value;if(r==="cutrectangle"&&(t.width()<R0e||t.height()<R0e))return N0e||(un("The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead"),N0e=!0),"rectangle";if(t.isParent())return r==="rectangle"||r==="roundrectangle"||r==="round-rectangle"||r==="cutrectangle"||r==="cut-rectangle"||r==="barrel"?r:"rectangle";if(r==="polygon"){var n=t.pstyle("shape-polygon-points").value;return e.nodeShapes.makePolygon(n).name}return r};WS={};WS.registerCalculationListeners=function(){var t=this.cy,e=t.collection(),r=this,n=o(function(s){var l=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;if(e.merge(s),l)for(var u=0;u<s.length;u++){var h=s[u],f=h._private,d=f.rstyle;d.clean=!1,d.cleanConnected=!1}},"enqueue");r.binder(t).on("bounds.* dirty.*",o(function(s){var l=s.target;n(l)},"onDirtyBounds")).on("style.* background.*",o(function(s){var l=s.target;n(l,!1)},"onDirtyStyle"));var i=o(function(s){if(s){var l=r.onUpdateEleCalcsFns;e.cleanStyle();for(var u=0;u<e.length;u++){var h=e[u],f=h._private.rstyle;h.isNode()&&!f.cleanConnected&&(n(h.connectedEdges()),f.cleanConnected=!0)}if(l)for(var d=0;d<l.length;d++){var p=l[d];p(s,e)}r.recalculateRenderedStyle(e),e=t.collection()}},"updateEleCalcs");r.flushRenderedStyleQueue=function(){i(!0)},r.beforeRender(i,r.beforeRenderPriorities.eleCalcs)};WS.onUpdateEleCalcs=function(t){var e=this.onUpdateEleCalcsFns=this.onUpdateEleCalcsFns||[];e.push(t)};WS.recalculateRenderedStyle=function(t,e){var r=o(function(C){return C._private.rstyle.cleanConnected},"isCleanConnected"),n=[],i=[];if(!this.destroyed){e===void 0&&(e=!0);for(var a=0;a<t.length;a++){var s=t[a],l=s._private,u=l.rstyle;s.isEdge()&&(!r(s.source())||!r(s.target()))&&(u.clean=!1),!(e&&u.clean||s.removed())&&s.pstyle("display").value!=="none"&&(l.group==="nodes"?i.push(s):n.push(s),u.clean=!0)}for(var h=0;h<i.length;h++){var f=i[h],d=f._private,p=d.rstyle,m=f.position();this.recalculateNodeLabelProjection(f),p.nodeX=m.x,p.nodeY=m.y,p.nodeW=f.pstyle("width").pfValue,p.nodeH=f.pstyle("height").pfValue}this.recalculateEdgeProjections(n);for(var g=0;g<n.length;g++){var y=n[g],v=y._private,x=v.rstyle,b=v.rscratch;x.srcX=b.arrowStartX,x.srcY=b.arrowStartY,x.tgtX=b.arrowEndX,x.tgtY=b.arrowEndY,x.midX=b.midX,x.midY=b.midY,x.labelAngle=b.labelAngle,x.sourceLabelAngle=b.sourceLabelAngle,x.targetLabelAngle=b.targetLabelAngle}}};qS={};qS.updateCachedGrabbedEles=function(){var t=this.cachedZSortedEles;if(t){t.drag=[],t.nondrag=[];for(var e=[],r=0;r<t.length;r++){var n=t[r],i=n._private.rscratch;n.grabbed()&&!n.isParent()?e.push(n):i.inDragLayer?t.drag.push(n):t.nondrag.push(n)}for(var r=0;r<e.length;r++){var n=e[r];t.drag.push(n)}}};qS.invalidateCachedZSortedEles=function(){this.cachedZSortedEles=null};qS.getCachedZSortedEles=function(t){if(t||!this.cachedZSortedEles){var e=this.cy.mutableElements().toArray();e.sort(Zme),e.interactive=e.filter(function(r){return r.interactive()}),this.cachedZSortedEles=e,this.updateCachedGrabbedEles()}else e=this.cachedZSortedEles;return e};gge={};[qp,AS,Va,o4,xB,Kc,mge,WS,qS].forEach(function(t){rr(gge,t)});yge={};yge.getCachedImage=function(t,e,r){var n=this,i=n.imageCache=n.imageCache||{},a=i[t];if(a)return a.image.complete||a.image.addEventListener("load",r),a.image;a=i[t]=i[t]||{};var s=a.image=new Image;s.addEventListener("load",r),s.addEventListener("error",function(){s.error=!0});var l="data:",u=t.substring(0,l.length).toLowerCase()===l;return u||(e=e==="null"?null:e,s.crossOrigin=e),s.src=t,s};sy={};sy.registerBinding=function(t,e,r,n){var i=Array.prototype.slice.apply(arguments,[1]);if(Array.isArray(t)){for(var a=[],s=0;s<t.length;s++){var l=t[s];if(l!==void 0){var u=this.binder(l);a.push(u.on.apply(u,i))}}return a}var u=this.binder(t);return u.on.apply(u,i)};sy.binder=function(t){var e=this,r=e.cy.window(),n=t===r||t===r.document||t===r.document.body||tWe(t);if(e.supportsPassiveEvents==null){var i=!1;try{var a=Object.defineProperty({},"passive",{get:o(function(){return i=!0,!0},"get")});r.addEventListener("test",null,a)}catch{}e.supportsPassiveEvents=i}var s=o(function(u,h,f){var d=Array.prototype.slice.call(arguments);return n&&e.supportsPassiveEvents&&(d[2]={capture:f??!1,passive:!1,once:!1}),e.bindings.push({target:t,args:d}),(t.addEventListener||t.on).apply(t,d),this},"on");return{on:s,addEventListener:s,addListener:s,bind:s}};sy.nodeIsDraggable=function(t){return t&&t.isNode()&&!t.locked()&&t.grabbable()};sy.nodeIsGrabbable=function(t){return this.nodeIsDraggable(t)&&t.interactive()};sy.load=function(){var t=this,e=t.cy.window(),r=o(function(W){return W.selected()},"isSelected"),n=o(function(W){var de=W.getRootNode();if(de&&de.nodeType===11&&de.host!==void 0)return de},"getShadowRoot"),i=o(function(W,de,re,oe){W==null&&(W=t.cy);for(var V=0;V<de.length;V++){var xe=de[V];W.emit({originalEvent:re,type:xe,position:oe})}},"triggerEvents"),a=o(function(W){return W.shiftKey||W.metaKey||W.ctrlKey},"isMultSelKeyDown"),s=o(function(W,de){var re=!0;if(t.cy.hasCompoundNodes()&&W&&W.pannable())for(var oe=0;de&&oe<de.length;oe++){var W=de[oe];if(W.isNode()&&W.isParent()&&!W.pannable()){re=!1;break}}else re=!0;return re},"allowPanningPassthrough"),l=o(function(W){W[0]._private.grabbed=!0},"setGrabbed"),u=o(function(W){W[0]._private.grabbed=!1},"setFreed"),h=o(function(W){W[0]._private.rscratch.inDragLayer=!0},"setInDragLayer"),f=o(function(W){W[0]._private.rscratch.inDragLayer=!1},"setOutDragLayer"),d=o(function(W){W[0]._private.rscratch.isGrabTarget=!0},"setGrabTarget"),p=o(function(W){W[0]._private.rscratch.isGrabTarget=!1},"removeGrabTarget"),m=o(function(W,de){var re=de.addToList,oe=re.has(W);!oe&&W.grabbable()&&!W.locked()&&(re.merge(W),l(W))},"addToDragList"),g=o(function(W,de){if(W.cy().hasCompoundNodes()&&!(de.inDragLayer==null&&de.addToList==null)){var re=W.descendants();de.inDragLayer&&(re.forEach(h),re.connectedEdges().forEach(h)),de.addToList&&m(re,de)}},"addDescendantsToDrag"),y=o(function(W,de){de=de||{};var re=W.cy().hasCompoundNodes();de.inDragLayer&&(W.forEach(h),W.neighborhood().stdFilter(function(oe){return!re||oe.isEdge()}).forEach(h)),de.addToList&&W.forEach(function(oe){m(oe,de)}),g(W,de),b(W,{inDragLayer:de.inDragLayer}),t.updateCachedGrabbedEles()},"addNodesToDrag"),v=y,x=o(function(W){W&&(t.getCachedZSortedEles().forEach(function(de){u(de),f(de),p(de)}),t.updateCachedGrabbedEles())},"freeDraggedElements"),b=o(function(W,de){if(!(de.inDragLayer==null&&de.addToList==null)&&W.cy().hasCompoundNodes()){var re=W.ancestors().orphans();if(!re.same(W)){var oe=re.descendants().spawnSelf().merge(re).unmerge(W).unmerge(W.descendants()),V=oe.connectedEdges();de.inDragLayer&&(V.forEach(h),oe.forEach(h)),de.addToList&&oe.forEach(function(xe){m(xe,de)})}}},"updateAncestorsInDragLayer"),w=o(function(){document.activeElement!=null&&document.activeElement.blur!=null&&document.activeElement.blur()},"blurActiveDomElement"),C=typeof MutationObserver<"u",T=typeof ResizeObserver<"u";C?(t.removeObserver=new MutationObserver(function(be){for(var W=0;W<be.length;W++){var de=be[W],re=de.removedNodes;if(re)for(var oe=0;oe<re.length;oe++){var V=re[oe];if(V===t.container){t.destroy();break}}}}),t.container.parentNode&&t.removeObserver.observe(t.container.parentNode,{childList:!0})):t.registerBinding(t.container,"DOMNodeRemoved",function(be){t.destroy()});var E=n4(function(){t.cy.resize()},100);C&&(t.styleObserver=new MutationObserver(E),t.styleObserver.observe(t.container,{attributes:!0})),t.registerBinding(e,"resize",E),T&&(t.resizeObserver=new ResizeObserver(E),t.resizeObserver.observe(t.container));var A=o(function(W,de){for(;W!=null;)de(W),W=W.parentNode},"forEachUp"),S=o(function(){t.invalidateContainerClientCoordsCache()},"invalidateCoords");A(t.container,function(be){t.registerBinding(be,"transitionend",S),t.registerBinding(be,"animationend",S),t.registerBinding(be,"scroll",S)}),t.registerBinding(t.container,"contextmenu",function(be){be.preventDefault()});var _=o(function(){return t.selection[4]!==0},"inBoxSelection"),I=o(function(W){for(var de=t.findContainerClientCoords(),re=de[0],oe=de[1],V=de[2],xe=de[3],q=W.touches?W.touches:[W],pe=!1,ve=0;ve<q.length;ve++){var Pe=q[ve];if(re<=Pe.clientX&&Pe.clientX<=re+V&&oe<=Pe.clientY&&Pe.clientY<=oe+xe){pe=!0;break}}if(!pe)return!1;for(var _e=t.container,we=W.target,Ve=we.parentNode,De=!1;Ve;){if(Ve===_e){De=!0;break}Ve=Ve.parentNode}return!!De},"eventInContainer");t.registerBinding(t.container,"mousedown",o(function(W){if(I(W)&&!(t.hoverData.which===1&&W.which!==1)){W.preventDefault(),w(),t.hoverData.capture=!0,t.hoverData.which=W.which;var de=t.cy,re=[W.clientX,W.clientY],oe=t.projectIntoViewport(re[0],re[1]),V=t.selection,xe=t.findNearestElements(oe[0],oe[1],!0,!1),q=xe[0],pe=t.dragData.possibleDragElements;t.hoverData.mdownPos=oe,t.hoverData.mdownGPos=re;var ve=o(function(){t.hoverData.tapholdCancelled=!1,clearTimeout(t.hoverData.tapholdTimeout),t.hoverData.tapholdTimeout=setTimeout(function(){if(!t.hoverData.tapholdCancelled){var qe=t.hoverData.down;qe?qe.emit({originalEvent:W,type:"taphold",position:{x:oe[0],y:oe[1]}}):de.emit({originalEvent:W,type:"taphold",position:{x:oe[0],y:oe[1]}})}},t.tapholdDuration)},"checkForTaphold");if(W.which==3){t.hoverData.cxtStarted=!0;var Pe={originalEvent:W,type:"cxttapstart",position:{x:oe[0],y:oe[1]}};q?(q.activate(),q.emit(Pe),t.hoverData.down=q):de.emit(Pe),t.hoverData.downTime=new Date().getTime(),t.hoverData.cxtDragged=!1}else if(W.which==1){q&&q.activate();{if(q!=null&&t.nodeIsGrabbable(q)){var _e=o(function(qe){return{originalEvent:W,type:qe,position:{x:oe[0],y:oe[1]}}},"makeEvent"),we=o(function(qe){qe.emit(_e("grab"))},"triggerGrab");if(d(q),!q.selected())pe=t.dragData.possibleDragElements=de.collection(),v(q,{addToList:pe}),q.emit(_e("grabon")).emit(_e("grab"));else{pe=t.dragData.possibleDragElements=de.collection();var Ve=de.$(function(De){return De.isNode()&&De.selected()&&t.nodeIsGrabbable(De)});y(Ve,{addToList:pe}),q.emit(_e("grabon")),Ve.forEach(we)}t.redrawHint("eles",!0),t.redrawHint("drag",!0)}t.hoverData.down=q,t.hoverData.downs=xe,t.hoverData.downTime=new Date().getTime()}i(q,["mousedown","tapstart","vmousedown"],W,{x:oe[0],y:oe[1]}),q==null?(V[4]=1,t.data.bgActivePosistion={x:oe[0],y:oe[1]},t.redrawHint("select",!0),t.redraw()):q.pannable()&&(V[4]=1),ve()}V[0]=V[2]=oe[0],V[1]=V[3]=oe[1]}},"mousedownHandler"),!1);var D=n(t.container);t.registerBinding([e,D],"mousemove",o(function(W){var de=t.hoverData.capture;if(!(!de&&!I(W))){var re=!1,oe=t.cy,V=oe.zoom(),xe=[W.clientX,W.clientY],q=t.projectIntoViewport(xe[0],xe[1]),pe=t.hoverData.mdownPos,ve=t.hoverData.mdownGPos,Pe=t.selection,_e=null;!t.hoverData.draggingEles&&!t.hoverData.dragging&&!t.hoverData.selecting&&(_e=t.findNearestElement(q[0],q[1],!0,!1));var we=t.hoverData.last,Ve=t.hoverData.down,De=[q[0]-Pe[2],q[1]-Pe[3]],qe=t.dragData.possibleDragElements,at;if(ve){var Rt=xe[0]-ve[0],st=Rt*Rt,Ue=xe[1]-ve[1],ct=Ue*Ue,We=st+ct;t.hoverData.isOverThresholdDrag=at=We>=t.desktopTapThreshold2}var ot=a(W);at&&(t.hoverData.tapholdCancelled=!0);var Yt=o(function(){var Tt=t.hoverData.dragDelta=t.hoverData.dragDelta||[];Tt.length===0?(Tt.push(De[0]),Tt.push(De[1])):(Tt[0]+=De[0],Tt[1]+=De[1])},"updateDragDelta");re=!0,i(_e,["mousemove","vmousemove","tapdrag"],W,{x:q[0],y:q[1]});var bt=o(function(){t.data.bgActivePosistion=void 0,t.hoverData.selecting||oe.emit({originalEvent:W,type:"boxstart",position:{x:q[0],y:q[1]}}),Pe[4]=1,t.hoverData.selecting=!0,t.redrawHint("select",!0),t.redraw()},"goIntoBoxMode");if(t.hoverData.which===3){if(at){var Mt={originalEvent:W,type:"cxtdrag",position:{x:q[0],y:q[1]}};Ve?Ve.emit(Mt):oe.emit(Mt),t.hoverData.cxtDragged=!0,(!t.hoverData.cxtOver||_e!==t.hoverData.cxtOver)&&(t.hoverData.cxtOver&&t.hoverData.cxtOver.emit({originalEvent:W,type:"cxtdragout",position:{x:q[0],y:q[1]}}),t.hoverData.cxtOver=_e,_e&&_e.emit({originalEvent:W,type:"cxtdragover",position:{x:q[0],y:q[1]}}))}}else if(t.hoverData.dragging){if(re=!0,oe.panningEnabled()&&oe.userPanningEnabled()){var xt;if(t.hoverData.justStartedPan){var ut=t.hoverData.mdownPos;xt={x:(q[0]-ut[0])*V,y:(q[1]-ut[1])*V},t.hoverData.justStartedPan=!1}else xt={x:De[0]*V,y:De[1]*V};oe.panBy(xt),oe.emit("dragpan"),t.hoverData.dragged=!0}q=t.projectIntoViewport(W.clientX,W.clientY)}else if(Pe[4]==1&&(Ve==null||Ve.pannable())){if(at){if(!t.hoverData.dragging&&oe.boxSelectionEnabled()&&(ot||!oe.panningEnabled()||!oe.userPanningEnabled()))bt();else if(!t.hoverData.selecting&&oe.panningEnabled()&&oe.userPanningEnabled()){var Et=s(Ve,t.hoverData.downs);Et&&(t.hoverData.dragging=!0,t.hoverData.justStartedPan=!0,Pe[4]=0,t.data.bgActivePosistion=U1(pe),t.redrawHint("select",!0),t.redraw())}Ve&&Ve.pannable()&&Ve.active()&&Ve.unactivate()}}else{if(Ve&&Ve.pannable()&&Ve.active()&&Ve.unactivate(),(!Ve||!Ve.grabbed())&&_e!=we&&(we&&i(we,["mouseout","tapdragout"],W,{x:q[0],y:q[1]}),_e&&i(_e,["mouseover","tapdragover"],W,{x:q[0],y:q[1]}),t.hoverData.last=_e),Ve)if(at){if(oe.boxSelectionEnabled()&&ot)Ve&&Ve.grabbed()&&(x(qe),Ve.emit("freeon"),qe.emit("free"),t.dragData.didDrag&&(Ve.emit("dragfreeon"),qe.emit("dragfree"))),bt();else if(Ve&&Ve.grabbed()&&t.nodeIsDraggable(Ve)){var ft=!t.dragData.didDrag;ft&&t.redrawHint("eles",!0),t.dragData.didDrag=!0,t.hoverData.draggingEles||y(qe,{inDragLayer:!0});var yt={x:0,y:0};if(Ct(De[0])&&Ct(De[1])&&(yt.x+=De[0],yt.y+=De[1],ft)){var nt=t.hoverData.dragDelta;nt&&Ct(nt[0])&&Ct(nt[1])&&(yt.x+=nt[0],yt.y+=nt[1])}t.hoverData.draggingEles=!0,qe.silentShift(yt).emit("position drag"),t.redrawHint("drag",!0),t.redraw()}}else Yt();re=!0}if(Pe[2]=q[0],Pe[3]=q[1],re)return W.stopPropagation&&W.stopPropagation(),W.preventDefault&&W.preventDefault(),!1}},"mousemoveHandler"),!1);var k,L,R;t.registerBinding(e,"mouseup",o(function(W){if(!(t.hoverData.which===1&&W.which!==1&&t.hoverData.capture)){var de=t.hoverData.capture;if(de){t.hoverData.capture=!1;var re=t.cy,oe=t.projectIntoViewport(W.clientX,W.clientY),V=t.selection,xe=t.findNearestElement(oe[0],oe[1],!0,!1),q=t.dragData.possibleDragElements,pe=t.hoverData.down,ve=a(W);if(t.data.bgActivePosistion&&(t.redrawHint("select",!0),t.redraw()),t.hoverData.tapholdCancelled=!0,t.data.bgActivePosistion=void 0,pe&&pe.unactivate(),t.hoverData.which===3){var Pe={originalEvent:W,type:"cxttapend",position:{x:oe[0],y:oe[1]}};if(pe?pe.emit(Pe):re.emit(Pe),!t.hoverData.cxtDragged){var _e={originalEvent:W,type:"cxttap",position:{x:oe[0],y:oe[1]}};pe?pe.emit(_e):re.emit(_e)}t.hoverData.cxtDragged=!1,t.hoverData.which=null}else if(t.hoverData.which===1){if(i(xe,["mouseup","tapend","vmouseup"],W,{x:oe[0],y:oe[1]}),!t.dragData.didDrag&&!t.hoverData.dragged&&!t.hoverData.selecting&&!t.hoverData.isOverThresholdDrag&&(i(pe,["click","tap","vclick"],W,{x:oe[0],y:oe[1]}),L=!1,W.timeStamp-R<=re.multiClickDebounceTime()?(k&&clearTimeout(k),L=!0,R=null,i(pe,["dblclick","dbltap","vdblclick"],W,{x:oe[0],y:oe[1]})):(k=setTimeout(function(){L||i(pe,["oneclick","onetap","voneclick"],W,{x:oe[0],y:oe[1]})},re.multiClickDebounceTime()),R=W.timeStamp)),pe==null&&!t.dragData.didDrag&&!t.hoverData.selecting&&!t.hoverData.dragged&&!a(W)&&(re.$(r).unselect(["tapunselect"]),q.length>0&&t.redrawHint("eles",!0),t.dragData.possibleDragElements=q=re.collection()),xe==pe&&!t.dragData.didDrag&&!t.hoverData.selecting&&xe!=null&&xe._private.selectable&&(t.hoverData.dragging||(re.selectionType()==="additive"||ve?xe.selected()?xe.unselect(["tapunselect"]):xe.select(["tapselect"]):ve||(re.$(r).unmerge(xe).unselect(["tapunselect"]),xe.select(["tapselect"]))),t.redrawHint("eles",!0)),t.hoverData.selecting){var we=re.collection(t.getAllInBox(V[0],V[1],V[2],V[3]));t.redrawHint("select",!0),we.length>0&&t.redrawHint("eles",!0),re.emit({type:"boxend",originalEvent:W,position:{x:oe[0],y:oe[1]}});var Ve=o(function(at){return at.selectable()&&!at.selected()},"eleWouldBeSelected");re.selectionType()==="additive"||ve||re.$(r).unmerge(we).unselect(),we.emit("box").stdFilter(Ve).select().emit("boxselect"),t.redraw()}if(t.hoverData.dragging&&(t.hoverData.dragging=!1,t.redrawHint("select",!0),t.redrawHint("eles",!0),t.redraw()),!V[4]){t.redrawHint("drag",!0),t.redrawHint("eles",!0);var De=pe&&pe.grabbed();x(q),De&&(pe.emit("freeon"),q.emit("free"),t.dragData.didDrag&&(pe.emit("dragfreeon"),q.emit("dragfree")))}}V[4]=0,t.hoverData.down=null,t.hoverData.cxtStarted=!1,t.hoverData.draggingEles=!1,t.hoverData.selecting=!1,t.hoverData.isOverThresholdDrag=!1,t.dragData.didDrag=!1,t.hoverData.dragged=!1,t.hoverData.dragDelta=[],t.hoverData.mdownPos=null,t.hoverData.mdownGPos=null,t.hoverData.which=null}}},"mouseupHandler"),!1);var O=o(function(W){if(!t.scrollingPage){var de=t.cy,re=de.zoom(),oe=de.pan(),V=t.projectIntoViewport(W.clientX,W.clientY),xe=[V[0]*re+oe.x,V[1]*re+oe.y];if(t.hoverData.draggingEles||t.hoverData.dragging||t.hoverData.cxtStarted||_()){W.preventDefault();return}if(de.panningEnabled()&&de.userPanningEnabled()&&de.zoomingEnabled()&&de.userZoomingEnabled()){W.preventDefault(),t.data.wheelZooming=!0,clearTimeout(t.data.wheelTimeout),t.data.wheelTimeout=setTimeout(function(){t.data.wheelZooming=!1,t.redrawHint("eles",!0),t.redraw()},150);var q;W.deltaY!=null?q=W.deltaY/-250:W.wheelDeltaY!=null?q=W.wheelDeltaY/1e3:q=W.wheelDelta/1e3,q=q*t.wheelSensitivity;var pe=W.deltaMode===1;pe&&(q*=33);var ve=de.zoom()*Math.pow(10,q);W.type==="gesturechange"&&(ve=t.gestureStartZoom*W.scale),de.zoom({level:ve,renderedPosition:{x:xe[0],y:xe[1]}}),de.emit(W.type==="gesturechange"?"pinchzoom":"scrollzoom")}}},"wheelHandler");t.registerBinding(t.container,"wheel",O,!0),t.registerBinding(e,"scroll",o(function(W){t.scrollingPage=!0,clearTimeout(t.scrollingPageTimeout),t.scrollingPageTimeout=setTimeout(function(){t.scrollingPage=!1},250)},"scrollHandler"),!0),t.registerBinding(t.container,"gesturestart",o(function(W){t.gestureStartZoom=t.cy.zoom(),t.hasTouchStarted||W.preventDefault()},"gestureStartHandler"),!0),t.registerBinding(t.container,"gesturechange",function(be){t.hasTouchStarted||O(be)},!0),t.registerBinding(t.container,"mouseout",o(function(W){var de=t.projectIntoViewport(W.clientX,W.clientY);t.cy.emit({originalEvent:W,type:"mouseout",position:{x:de[0],y:de[1]}})},"mouseOutHandler"),!1),t.registerBinding(t.container,"mouseover",o(function(W){var de=t.projectIntoViewport(W.clientX,W.clientY);t.cy.emit({originalEvent:W,type:"mouseover",position:{x:de[0],y:de[1]}})},"mouseOverHandler"),!1);var M,B,F,P,z,$,H,Q,j,ie,ne,le,he,K=o(function(W,de,re,oe){return Math.sqrt((re-W)*(re-W)+(oe-de)*(oe-de))},"distance"),X=o(function(W,de,re,oe){return(re-W)*(re-W)+(oe-de)*(oe-de)},"distanceSq"),te;t.registerBinding(t.container,"touchstart",te=o(function(W){if(t.hasTouchStarted=!0,!!I(W)){w(),t.touchData.capture=!0,t.data.bgActivePosistion=void 0;var de=t.cy,re=t.touchData.now,oe=t.touchData.earlier;if(W.touches[0]){var V=t.projectIntoViewport(W.touches[0].clientX,W.touches[0].clientY);re[0]=V[0],re[1]=V[1]}if(W.touches[1]){var V=t.projectIntoViewport(W.touches[1].clientX,W.touches[1].clientY);re[2]=V[0],re[3]=V[1]}if(W.touches[2]){var V=t.projectIntoViewport(W.touches[2].clientX,W.touches[2].clientY);re[4]=V[0],re[5]=V[1]}if(W.touches[1]){t.touchData.singleTouchMoved=!0,x(t.dragData.touchDragEles);var xe=t.findContainerClientCoords();j=xe[0],ie=xe[1],ne=xe[2],le=xe[3],M=W.touches[0].clientX-j,B=W.touches[0].clientY-ie,F=W.touches[1].clientX-j,P=W.touches[1].clientY-ie,he=0<=M&&M<=ne&&0<=F&&F<=ne&&0<=B&&B<=le&&0<=P&&P<=le;var q=de.pan(),pe=de.zoom();z=K(M,B,F,P),$=X(M,B,F,P),H=[(M+F)/2,(B+P)/2],Q=[(H[0]-q.x)/pe,(H[1]-q.y)/pe];var ve=200,Pe=ve*ve;if($<Pe&&!W.touches[2]){var _e=t.findNearestElement(re[0],re[1],!0,!0),we=t.findNearestElement(re[2],re[3],!0,!0);_e&&_e.isNode()?(_e.activate().emit({originalEvent:W,type:"cxttapstart",position:{x:re[0],y:re[1]}}),t.touchData.start=_e):we&&we.isNode()?(we.activate().emit({originalEvent:W,type:"cxttapstart",position:{x:re[0],y:re[1]}}),t.touchData.start=we):de.emit({originalEvent:W,type:"cxttapstart",position:{x:re[0],y:re[1]}}),t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxt=!0,t.touchData.cxtDragged=!1,t.data.bgActivePosistion=void 0,t.redraw();return}}if(W.touches[2])de.boxSelectionEnabled()&&W.preventDefault();else if(!W.touches[1]){if(W.touches[0]){var Ve=t.findNearestElements(re[0],re[1],!0,!0),De=Ve[0];if(De!=null&&(De.activate(),t.touchData.start=De,t.touchData.starts=Ve,t.nodeIsGrabbable(De))){var qe=t.dragData.touchDragEles=de.collection(),at=null;t.redrawHint("eles",!0),t.redrawHint("drag",!0),De.selected()?(at=de.$(function(We){return We.selected()&&t.nodeIsGrabbable(We)}),y(at,{addToList:qe})):v(De,{addToList:qe}),d(De);var Rt=o(function(ot){return{originalEvent:W,type:ot,position:{x:re[0],y:re[1]}}},"makeEvent");De.emit(Rt("grabon")),at?at.forEach(function(We){We.emit(Rt("grab"))}):De.emit(Rt("grab"))}i(De,["touchstart","tapstart","vmousedown"],W,{x:re[0],y:re[1]}),De==null&&(t.data.bgActivePosistion={x:V[0],y:V[1]},t.redrawHint("select",!0),t.redraw()),t.touchData.singleTouchMoved=!1,t.touchData.singleTouchStartTime=+new Date,clearTimeout(t.touchData.tapholdTimeout),t.touchData.tapholdTimeout=setTimeout(function(){t.touchData.singleTouchMoved===!1&&!t.pinching&&!t.touchData.selecting&&i(t.touchData.start,["taphold"],W,{x:re[0],y:re[1]})},t.tapholdDuration)}}if(W.touches.length>=1){for(var st=t.touchData.startPosition=[null,null,null,null,null,null],Ue=0;Ue<re.length;Ue++)st[Ue]=oe[Ue]=re[Ue];var ct=W.touches[0];t.touchData.startGPosition=[ct.clientX,ct.clientY]}}},"touchstartHandler"),!1);var J;t.registerBinding(e,"touchmove",J=o(function(W){var de=t.touchData.capture;if(!(!de&&!I(W))){var re=t.selection,oe=t.cy,V=t.touchData.now,xe=t.touchData.earlier,q=oe.zoom();if(W.touches[0]){var pe=t.projectIntoViewport(W.touches[0].clientX,W.touches[0].clientY);V[0]=pe[0],V[1]=pe[1]}if(W.touches[1]){var pe=t.projectIntoViewport(W.touches[1].clientX,W.touches[1].clientY);V[2]=pe[0],V[3]=pe[1]}if(W.touches[2]){var pe=t.projectIntoViewport(W.touches[2].clientX,W.touches[2].clientY);V[4]=pe[0],V[5]=pe[1]}var ve=t.touchData.startGPosition,Pe;if(de&&W.touches[0]&&ve){for(var _e=[],we=0;we<V.length;we++)_e[we]=V[we]-xe[we];var Ve=W.touches[0].clientX-ve[0],De=Ve*Ve,qe=W.touches[0].clientY-ve[1],at=qe*qe,Rt=De+at;Pe=Rt>=t.touchTapThreshold2}if(de&&t.touchData.cxt){W.preventDefault();var st=W.touches[0].clientX-j,Ue=W.touches[0].clientY-ie,ct=W.touches[1].clientX-j,We=W.touches[1].clientY-ie,ot=X(st,Ue,ct,We),Yt=ot/$,bt=150,Mt=bt*bt,xt=1.5,ut=xt*xt;if(Yt>=ut||ot>=Mt){t.touchData.cxt=!1,t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var Et={originalEvent:W,type:"cxttapend",position:{x:V[0],y:V[1]}};t.touchData.start?(t.touchData.start.unactivate().emit(Et),t.touchData.start=null):oe.emit(Et)}}if(de&&t.touchData.cxt){var Et={originalEvent:W,type:"cxtdrag",position:{x:V[0],y:V[1]}};t.data.bgActivePosistion=void 0,t.redrawHint("select",!0),t.touchData.start?t.touchData.start.emit(Et):oe.emit(Et),t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxtDragged=!0;var ft=t.findNearestElement(V[0],V[1],!0,!0);(!t.touchData.cxtOver||ft!==t.touchData.cxtOver)&&(t.touchData.cxtOver&&t.touchData.cxtOver.emit({originalEvent:W,type:"cxtdragout",position:{x:V[0],y:V[1]}}),t.touchData.cxtOver=ft,ft&&ft.emit({originalEvent:W,type:"cxtdragover",position:{x:V[0],y:V[1]}}))}else if(de&&W.touches[2]&&oe.boxSelectionEnabled())W.preventDefault(),t.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,t.touchData.selecting||oe.emit({originalEvent:W,type:"boxstart",position:{x:V[0],y:V[1]}}),t.touchData.selecting=!0,t.touchData.didSelect=!0,re[4]=1,!re||re.length===0||re[0]===void 0?(re[0]=(V[0]+V[2]+V[4])/3,re[1]=(V[1]+V[3]+V[5])/3,re[2]=(V[0]+V[2]+V[4])/3+1,re[3]=(V[1]+V[3]+V[5])/3+1):(re[2]=(V[0]+V[2]+V[4])/3,re[3]=(V[1]+V[3]+V[5])/3),t.redrawHint("select",!0),t.redraw();else if(de&&W.touches[1]&&!t.touchData.didSelect&&oe.zoomingEnabled()&&oe.panningEnabled()&&oe.userZoomingEnabled()&&oe.userPanningEnabled()){W.preventDefault(),t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var yt=t.dragData.touchDragEles;if(yt){t.redrawHint("drag",!0);for(var nt=0;nt<yt.length;nt++){var dn=yt[nt]._private;dn.grabbed=!1,dn.rscratch.inDragLayer=!1}}var Tt=t.touchData.start,st=W.touches[0].clientX-j,Ue=W.touches[0].clientY-ie,ct=W.touches[1].clientX-j,We=W.touches[1].clientY-ie,On=K(st,Ue,ct,We),tn=On/z;if(he){var _r=st-M,Dr=Ue-B,Pn=ct-F,At=We-P,Ce=(_r+Pn)/2,tt=(Dr+At)/2,St=oe.zoom(),mr=St*tn,rn=oe.pan(),gn=Q[0]*St+rn.x,Zr=Q[1]*St+rn.y,Ni={x:-mr/St*(gn-rn.x-Ce)+gn,y:-mr/St*(Zr-rn.y-tt)+Zr};if(Tt&&Tt.active()){var yt=t.dragData.touchDragEles;x(yt),t.redrawHint("drag",!0),t.redrawHint("eles",!0),Tt.unactivate().emit("freeon"),yt.emit("free"),t.dragData.didDrag&&(Tt.emit("dragfreeon"),yt.emit("dragfree"))}oe.viewport({zoom:mr,pan:Ni,cancelOnFailedZoom:!0}),oe.emit("pinchzoom"),z=On,M=st,B=Ue,F=ct,P=We,t.pinching=!0}if(W.touches[0]){var pe=t.projectIntoViewport(W.touches[0].clientX,W.touches[0].clientY);V[0]=pe[0],V[1]=pe[1]}if(W.touches[1]){var pe=t.projectIntoViewport(W.touches[1].clientX,W.touches[1].clientY);V[2]=pe[0],V[3]=pe[1]}if(W.touches[2]){var pe=t.projectIntoViewport(W.touches[2].clientX,W.touches[2].clientY);V[4]=pe[0],V[5]=pe[1]}}else if(W.touches[0]&&!t.touchData.didSelect){var Zn=t.touchData.start,Sn=t.touchData.last,ft;if(!t.hoverData.draggingEles&&!t.swipePanning&&(ft=t.findNearestElement(V[0],V[1],!0,!0)),de&&Zn!=null&&W.preventDefault(),de&&Zn!=null&&t.nodeIsDraggable(Zn))if(Pe){var yt=t.dragData.touchDragEles,Hr=!t.dragData.didDrag;Hr&&y(yt,{inDragLayer:!0}),t.dragData.didDrag=!0;var et={x:0,y:0};if(Ct(_e[0])&&Ct(_e[1])&&(et.x+=_e[0],et.y+=_e[1],Hr)){t.redrawHint("eles",!0);var mt=t.touchData.dragDelta;mt&&Ct(mt[0])&&Ct(mt[1])&&(et.x+=mt[0],et.y+=mt[1])}t.hoverData.draggingEles=!0,yt.silentShift(et).emit("position drag"),t.redrawHint("drag",!0),t.touchData.startPosition[0]==xe[0]&&t.touchData.startPosition[1]==xe[1]&&t.redrawHint("eles",!0),t.redraw()}else{var mt=t.touchData.dragDelta=t.touchData.dragDelta||[];mt.length===0?(mt.push(_e[0]),mt.push(_e[1])):(mt[0]+=_e[0],mt[1]+=_e[1])}if(i(Zn||ft,["touchmove","tapdrag","vmousemove"],W,{x:V[0],y:V[1]}),(!Zn||!Zn.grabbed())&&ft!=Sn&&(Sn&&Sn.emit({originalEvent:W,type:"tapdragout",position:{x:V[0],y:V[1]}}),ft&&ft.emit({originalEvent:W,type:"tapdragover",position:{x:V[0],y:V[1]}})),t.touchData.last=ft,de)for(var nt=0;nt<V.length;nt++)V[nt]&&t.touchData.startPosition[nt]&&Pe&&(t.touchData.singleTouchMoved=!0);if(de&&(Zn==null||Zn.pannable())&&oe.panningEnabled()&&oe.userPanningEnabled()){var Kt=s(Zn,t.touchData.starts);Kt&&(W.preventDefault(),t.data.bgActivePosistion||(t.data.bgActivePosistion=U1(t.touchData.startPosition)),t.swipePanning?(oe.panBy({x:_e[0]*q,y:_e[1]*q}),oe.emit("dragpan")):Pe&&(t.swipePanning=!0,oe.panBy({x:Ve*q,y:qe*q}),oe.emit("dragpan"),Zn&&(Zn.unactivate(),t.redrawHint("select",!0),t.touchData.start=null)));var pe=t.projectIntoViewport(W.touches[0].clientX,W.touches[0].clientY);V[0]=pe[0],V[1]=pe[1]}}for(var we=0;we<V.length;we++)xe[we]=V[we];de&&W.touches.length>0&&!t.hoverData.draggingEles&&!t.swipePanning&&t.data.bgActivePosistion!=null&&(t.data.bgActivePosistion=void 0,t.redrawHint("select",!0),t.redraw())}},"touchmoveHandler"),!1);var se;t.registerBinding(e,"touchcancel",se=o(function(W){var de=t.touchData.start;t.touchData.capture=!1,de&&de.unactivate()},"touchcancelHandler"));var ue,Z,Se,ce;if(t.registerBinding(e,"touchend",ue=o(function(W){var de=t.touchData.start,re=t.touchData.capture;if(re)W.touches.length===0&&(t.touchData.capture=!1),W.preventDefault();else return;var oe=t.selection;t.swipePanning=!1,t.hoverData.draggingEles=!1;var V=t.cy,xe=V.zoom(),q=t.touchData.now,pe=t.touchData.earlier;if(W.touches[0]){var ve=t.projectIntoViewport(W.touches[0].clientX,W.touches[0].clientY);q[0]=ve[0],q[1]=ve[1]}if(W.touches[1]){var ve=t.projectIntoViewport(W.touches[1].clientX,W.touches[1].clientY);q[2]=ve[0],q[3]=ve[1]}if(W.touches[2]){var ve=t.projectIntoViewport(W.touches[2].clientX,W.touches[2].clientY);q[4]=ve[0],q[5]=ve[1]}de&&de.unactivate();var Pe;if(t.touchData.cxt){if(Pe={originalEvent:W,type:"cxttapend",position:{x:q[0],y:q[1]}},de?de.emit(Pe):V.emit(Pe),!t.touchData.cxtDragged){var _e={originalEvent:W,type:"cxttap",position:{x:q[0],y:q[1]}};de?de.emit(_e):V.emit(_e)}t.touchData.start&&(t.touchData.start._private.grabbed=!1),t.touchData.cxt=!1,t.touchData.start=null,t.redraw();return}if(!W.touches[2]&&V.boxSelectionEnabled()&&t.touchData.selecting){t.touchData.selecting=!1;var we=V.collection(t.getAllInBox(oe[0],oe[1],oe[2],oe[3]));oe[0]=void 0,oe[1]=void 0,oe[2]=void 0,oe[3]=void 0,oe[4]=0,t.redrawHint("select",!0),V.emit({type:"boxend",originalEvent:W,position:{x:q[0],y:q[1]}});var Ve=o(function(Mt){return Mt.selectable()&&!Mt.selected()},"eleWouldBeSelected");we.emit("box").stdFilter(Ve).select().emit("boxselect"),we.nonempty()&&t.redrawHint("eles",!0),t.redraw()}if(de?.unactivate(),W.touches[2])t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);else if(!W.touches[1]){if(!W.touches[0]){if(!W.touches[0]){t.data.bgActivePosistion=void 0,t.redrawHint("select",!0);var De=t.dragData.touchDragEles;if(de!=null){var qe=de._private.grabbed;x(De),t.redrawHint("drag",!0),t.redrawHint("eles",!0),qe&&(de.emit("freeon"),De.emit("free"),t.dragData.didDrag&&(de.emit("dragfreeon"),De.emit("dragfree"))),i(de,["touchend","tapend","vmouseup","tapdragout"],W,{x:q[0],y:q[1]}),de.unactivate(),t.touchData.start=null}else{var at=t.findNearestElement(q[0],q[1],!0,!0);i(at,["touchend","tapend","vmouseup","tapdragout"],W,{x:q[0],y:q[1]})}var Rt=t.touchData.startPosition[0]-q[0],st=Rt*Rt,Ue=t.touchData.startPosition[1]-q[1],ct=Ue*Ue,We=st+ct,ot=We*xe*xe;t.touchData.singleTouchMoved||(de||V.$(":selected").unselect(["tapunselect"]),i(de,["tap","vclick"],W,{x:q[0],y:q[1]}),Z=!1,W.timeStamp-ce<=V.multiClickDebounceTime()?(Se&&clearTimeout(Se),Z=!0,ce=null,i(de,["dbltap","vdblclick"],W,{x:q[0],y:q[1]})):(Se=setTimeout(function(){Z||i(de,["onetap","voneclick"],W,{x:q[0],y:q[1]})},V.multiClickDebounceTime()),ce=W.timeStamp)),de!=null&&!t.dragData.didDrag&&de._private.selectable&&ot<t.touchTapThreshold2&&!t.pinching&&(V.selectionType()==="single"?(V.$(r).unmerge(de).unselect(["tapunselect"]),de.select(["tapselect"])):de.selected()?de.unselect(["tapunselect"]):de.select(["tapselect"]),t.redrawHint("eles",!0)),t.touchData.singleTouchMoved=!0}}}for(var Yt=0;Yt<q.length;Yt++)pe[Yt]=q[Yt];t.dragData.didDrag=!1,W.touches.length===0&&(t.touchData.dragDelta=[],t.touchData.startPosition=[null,null,null,null,null,null],t.touchData.startGPosition=null,t.touchData.didSelect=!1),W.touches.length<2&&(W.touches.length===1&&(t.touchData.startGPosition=[W.touches[0].clientX,W.touches[0].clientY]),t.pinching=!1,t.redrawHint("eles",!0),t.redraw())},"touchendHandler"),!1),typeof TouchEvent>"u"){var ae=[],Oe=o(function(W){return{clientX:W.clientX,clientY:W.clientY,force:1,identifier:W.pointerId,pageX:W.pageX,pageY:W.pageY,radiusX:W.width/2,radiusY:W.height/2,screenX:W.screenX,screenY:W.screenY,target:W.target}},"makeTouch"),ge=o(function(W){return{event:W,touch:Oe(W)}},"makePointer"),ze=o(function(W){ae.push(ge(W))},"addPointer"),He=o(function(W){for(var de=0;de<ae.length;de++){var re=ae[de];if(re.event.pointerId===W.pointerId){ae.splice(de,1);return}}},"removePointer"),$e=o(function(W){var de=ae.filter(function(re){return re.event.pointerId===W.pointerId})[0];de.event=W,de.touch=Oe(W)},"updatePointer"),Re=o(function(W){W.touches=ae.map(function(de){return de.touch})},"addTouchesToEvent"),Ie=o(function(W){return W.pointerType==="mouse"||W.pointerType===4},"pointerIsMouse");t.registerBinding(t.container,"pointerdown",function(be){Ie(be)||(be.preventDefault(),ze(be),Re(be),te(be))}),t.registerBinding(t.container,"pointerup",function(be){Ie(be)||(He(be),Re(be),ue(be))}),t.registerBinding(t.container,"pointercancel",function(be){Ie(be)||(He(be),Re(be),se(be))}),t.registerBinding(t.container,"pointermove",function(be){Ie(be)||(be.preventDefault(),$e(be),Re(be),J(be))})}};eh={};eh.generatePolygon=function(t,e){return this.nodeShapes[t]={renderer:this,name:t,points:e,draw:o(function(n,i,a,s,l,u){this.renderer.nodeShapeImpl("polygon",n,i,a,s,l,this.points)},"draw"),intersectLine:o(function(n,i,a,s,l,u,h,f){return Xb(l,u,this.points,n,i,a/2,s/2,h)},"intersectLine"),checkPoint:o(function(n,i,a,s,l,u,h,f){return Zu(n,i,this.points,u,h,s,l,[0,-1],a)},"checkPoint")}};eh.generateEllipse=function(){return this.nodeShapes.ellipse={renderer:this,name:"ellipse",draw:o(function(e,r,n,i,a,s){this.renderer.nodeShapeImpl(this.name,e,r,n,i,a)},"draw"),intersectLine:o(function(e,r,n,i,a,s,l,u){return Yqe(a,s,e,r,n/2+l,i/2+l)},"intersectLine"),checkPoint:o(function(e,r,n,i,a,s,l,u){return $p(e,r,i,a,s,l,n)},"checkPoint")}};eh.generateRoundPolygon=function(t,e){return this.nodeShapes[t]={renderer:this,name:t,points:e,getOrCreateCorners:o(function(n,i,a,s,l,u,h){if(u[h]!==void 0&&u[h+"-cx"]===n&&u[h+"-cy"]===i)return u[h];u[h]=new Array(e.length/2),u[h+"-cx"]=n,u[h+"-cy"]=i;var f=a/2,d=s/2;l=l==="auto"?bme(a,s):l;for(var p=new Array(e.length/2),m=0;m<e.length/2;m++)p[m]={x:n+f*e[m*2],y:i+d*e[m*2+1]};var g,y,v,x,b=p.length;for(y=p[b-1],g=0;g<b;g++)v=p[g%b],x=p[(g+1)%b],u[h][g]=vB(y,v,x,l),y=v,v=x;return u[h]},"getOrCreateCorners"),draw:o(function(n,i,a,s,l,u,h){this.renderer.nodeShapeImpl("round-polygon",n,i,a,s,l,this.points,this.getOrCreateCorners(i,a,s,l,u,h,"drawCorners"))},"draw"),intersectLine:o(function(n,i,a,s,l,u,h,f,d){return Xqe(l,u,this.points,n,i,a,s,h,this.getOrCreateCorners(n,i,a,s,f,d,"corners"))},"intersectLine"),checkPoint:o(function(n,i,a,s,l,u,h,f,d){return qqe(n,i,this.points,u,h,s,l,this.getOrCreateCorners(u,h,s,l,f,d,"corners"))},"checkPoint")}};eh.generateRoundRectangle=function(){return this.nodeShapes["round-rectangle"]=this.nodeShapes.roundrectangle={renderer:this,name:"round-rectangle",points:gs(4,0),draw:o(function(e,r,n,i,a,s){this.renderer.nodeShapeImpl(this.name,e,r,n,i,a,this.points,s)},"draw"),intersectLine:o(function(e,r,n,i,a,s,l,u){return vme(a,s,e,r,n,i,l,u)},"intersectLine"),checkPoint:o(function(e,r,n,i,a,s,l,u){var h=i/2,f=a/2;u=u==="auto"?Vp(i,a):u,u=Math.min(h,f,u);var d=u*2;return!!(Zu(e,r,this.points,s,l,i,a-d,[0,-1],n)||Zu(e,r,this.points,s,l,i-d,a,[0,-1],n)||$p(e,r,d,d,s-h+u,l-f+u,n)||$p(e,r,d,d,s+h-u,l-f+u,n)||$p(e,r,d,d,s+h-u,l+f-u,n)||$p(e,r,d,d,s-h+u,l+f-u,n))},"checkPoint")}};eh.generateCutRectangle=function(){return this.nodeShapes["cut-rectangle"]=this.nodeShapes.cutrectangle={renderer:this,name:"cut-rectangle",cornerLength:sB(),points:gs(4,0),draw:o(function(e,r,n,i,a,s){this.renderer.nodeShapeImpl(this.name,e,r,n,i,a,null,s)},"draw"),generateCutTrianglePts:o(function(e,r,n,i,a){var s=a==="auto"?this.cornerLength:a,l=r/2,u=e/2,h=n-u,f=n+u,d=i-l,p=i+l;return{topLeft:[h,d+s,h+s,d,h+s,d+s],topRight:[f-s,d,f,d+s,f-s,d+s],bottomRight:[f,p-s,f-s,p,f-s,p-s],bottomLeft:[h+s,p,h,p-s,h+s,p-s]}},"generateCutTrianglePts"),intersectLine:o(function(e,r,n,i,a,s,l,u){var h=this.generateCutTrianglePts(n+2*l,i+2*l,e,r,u),f=[].concat.apply([],[h.topLeft.splice(0,4),h.topRight.splice(0,4),h.bottomRight.splice(0,4),h.bottomLeft.splice(0,4)]);return Xb(a,s,f,e,r)},"intersectLine"),checkPoint:o(function(e,r,n,i,a,s,l,u){var h=u==="auto"?this.cornerLength:u;if(Zu(e,r,this.points,s,l,i,a-2*h,[0,-1],n)||Zu(e,r,this.points,s,l,i-2*h,a,[0,-1],n))return!0;var f=this.generateCutTrianglePts(i,a,s,l);return Us(e,r,f.topLeft)||Us(e,r,f.topRight)||Us(e,r,f.bottomRight)||Us(e,r,f.bottomLeft)},"checkPoint")}};eh.generateBarrel=function(){return this.nodeShapes.barrel={renderer:this,name:"barrel",points:gs(4,0),draw:o(function(e,r,n,i,a,s){this.renderer.nodeShapeImpl(this.name,e,r,n,i,a)},"draw"),intersectLine:o(function(e,r,n,i,a,s,l,u){var h=.15,f=.5,d=.85,p=this.generateBarrelBezierPts(n+2*l,i+2*l,e,r),m=o(function(v){var x=W1({x:v[0],y:v[1]},{x:v[2],y:v[3]},{x:v[4],y:v[5]},h),b=W1({x:v[0],y:v[1]},{x:v[2],y:v[3]},{x:v[4],y:v[5]},f),w=W1({x:v[0],y:v[1]},{x:v[2],y:v[3]},{x:v[4],y:v[5]},d);return[v[0],v[1],x.x,x.y,b.x,b.y,w.x,w.y,v[4],v[5]]},"approximateBarrelCurvePts"),g=[].concat(m(p.topLeft),m(p.topRight),m(p.bottomRight),m(p.bottomLeft));return Xb(a,s,g,e,r)},"intersectLine"),generateBarrelBezierPts:o(function(e,r,n,i){var a=r/2,s=e/2,l=n-s,u=n+s,h=i-a,f=i+a,d=BP(e,r),p=d.heightOffset,m=d.widthOffset,g=d.ctrlPtOffsetPct*e,y={topLeft:[l,h+p,l+g,h,l+m,h],topRight:[u-m,h,u-g,h,u,h+p],bottomRight:[u,f-p,u-g,f,u-m,f],bottomLeft:[l+m,f,l+g,f,l,f-p]};return y.topLeft.isTop=!0,y.topRight.isTop=!0,y.bottomLeft.isBottom=!0,y.bottomRight.isBottom=!0,y},"generateBarrelBezierPts"),checkPoint:o(function(e,r,n,i,a,s,l,u){var h=BP(i,a),f=h.heightOffset,d=h.widthOffset;if(Zu(e,r,this.points,s,l,i,a-2*f,[0,-1],n)||Zu(e,r,this.points,s,l,i-2*d,a,[0,-1],n))return!0;for(var p=this.generateBarrelBezierPts(i,a,s,l),m=o(function(S,_,I){var D=I[4],k=I[2],L=I[0],R=I[5],O=I[1],M=Math.min(D,L),B=Math.max(D,L),F=Math.min(R,O),P=Math.max(R,O);if(M<=S&&S<=B&&F<=_&&_<=P){var z=jqe(D,k,L),$=Vqe(z[0],z[1],z[2],S),H=$.filter(function(Q){return 0<=Q&&Q<=1});if(H.length>0)return H[0]}return null},"getCurveT"),g=Object.keys(p),y=0;y<g.length;y++){var v=g[y],x=p[v],b=m(e,r,x);if(b!=null){var w=x[5],C=x[3],T=x[1],E=oa(w,C,T,b);if(x.isTop&&E<=r||x.isBottom&&r<=E)return!0}}return!1},"checkPoint")}};eh.generateBottomRoundrectangle=function(){return this.nodeShapes["bottom-round-rectangle"]=this.nodeShapes.bottomroundrectangle={renderer:this,name:"bottom-round-rectangle",points:gs(4,0),draw:o(function(e,r,n,i,a,s){this.renderer.nodeShapeImpl(this.name,e,r,n,i,a,this.points,s)},"draw"),intersectLine:o(function(e,r,n,i,a,s,l,u){var h=e-(n/2+l),f=r-(i/2+l),d=f,p=e+(n/2+l),m=Ef(a,s,e,r,h,f,p,d,!1);return m.length>0?m:vme(a,s,e,r,n,i,l,u)},"intersectLine"),checkPoint:o(function(e,r,n,i,a,s,l,u){u=u==="auto"?Vp(i,a):u;var h=2*u;if(Zu(e,r,this.points,s,l,i,a-h,[0,-1],n)||Zu(e,r,this.points,s,l,i-h,a,[0,-1],n))return!0;var f=i/2+2*n,d=a/2+2*n,p=[s-f,l-d,s-f,l,s+f,l,s+f,l-d];return!!(Us(e,r,p)||$p(e,r,h,h,s+i/2-u,l+a/2-u,n)||$p(e,r,h,h,s-i/2+u,l+a/2-u,n))},"checkPoint")}};eh.registerNodeShapes=function(){var t=this.nodeShapes={},e=this;this.generateEllipse(),this.generatePolygon("triangle",gs(3,0)),this.generateRoundPolygon("round-triangle",gs(3,0)),this.generatePolygon("rectangle",gs(4,0)),t.square=t.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();{var r=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",r),this.generateRoundPolygon("round-diamond",r)}this.generatePolygon("pentagon",gs(5,0)),this.generateRoundPolygon("round-pentagon",gs(5,0)),this.generatePolygon("hexagon",gs(6,0)),this.generateRoundPolygon("round-hexagon",gs(6,0)),this.generatePolygon("heptagon",gs(7,0)),this.generateRoundPolygon("round-heptagon",gs(7,0)),this.generatePolygon("octagon",gs(8,0)),this.generateRoundPolygon("round-octagon",gs(8,0));var n=new Array(20);{var i=PP(5,0),a=PP(5,Math.PI/5),s=.5*(3-Math.sqrt(5));s*=1.57;for(var l=0;l<a.length/2;l++)a[l*2]*=s,a[l*2+1]*=s;for(var l=0;l<20/4;l++)n[l*4]=i[l*2],n[l*4+1]=i[l*2+1],n[l*4+2]=a[l*2],n[l*4+3]=a[l*2+1]}n=xme(n),this.generatePolygon("star",n),this.generatePolygon("vee",[-1,-1,0,-.333,1,-1,0,1]),this.generatePolygon("rhomboid",[-1,-1,.333,-1,1,1,-.333,1]),this.generatePolygon("right-rhomboid",[-.333,-1,1,-1,.333,1,-1,1]),this.nodeShapes.concavehexagon=this.generatePolygon("concave-hexagon",[-1,-.95,-.75,0,-1,.95,1,.95,.75,0,1,-.95]);{var u=[-1,-1,.25,-1,1,0,.25,1,-1,1];this.generatePolygon("tag",u),this.generateRoundPolygon("round-tag",u)}t.makePolygon=function(h){var f=h.join("$"),d="polygon-"+f,p;return(p=this[d])?p:e.generatePolygon(d,h)}};l4={};l4.timeToRender=function(){return this.redrawTotalTime/this.redrawCount};l4.redraw=function(t){t=t||dme();var e=this;e.averageRedrawTime===void 0&&(e.averageRedrawTime=0),e.lastRedrawTime===void 0&&(e.lastRedrawTime=0),e.lastDrawTime===void 0&&(e.lastDrawTime=0),e.requestedFrame=!0,e.renderOptions=t};l4.beforeRender=function(t,e){if(!this.destroyed){e==null&&ai("Priority is not optional for beforeRender");var r=this.beforeRenderCallbacks;r.push({fn:t,priority:e}),r.sort(function(n,i){return i.priority-n.priority})}};M0e=o(function(e,r,n){for(var i=e.beforeRenderCallbacks,a=0;a<i.length;a++)i[a].fn(r,n)},"beforeRenderCallbacks");l4.startRenderLoop=function(){var t=this,e=t.cy;if(!t.renderLoopStarted){t.renderLoopStarted=!0;var r=o(function n(i){if(!t.destroyed){if(!e.batching())if(t.requestedFrame&&!t.skipFrame){M0e(t,!0,i);var a=Qu();t.render(t.renderOptions);var s=t.lastDrawTime=Qu();t.averageRedrawTime===void 0&&(t.averageRedrawTime=s-a),t.redrawCount===void 0&&(t.redrawCount=0),t.redrawCount++,t.redrawTotalTime===void 0&&(t.redrawTotalTime=0);var l=s-a;t.redrawTotalTime+=l,t.lastRedrawTime=l,t.averageRedrawTime=t.averageRedrawTime/2+l/2,t.requestedFrame=!1}else M0e(t,!1,i);t.skipFrame=!1,xS(n)}},"renderFn");xS(r)}};LQe=o(function(e){this.init(e)},"BaseRenderer"),vge=LQe,oy=vge.prototype;oy.clientFunctions=["redrawHint","render","renderTo","matchCanvasSize","nodeShapeImpl","arrowShapeImpl"];oy.init=function(t){var e=this;e.options=t,e.cy=t.cy;var r=e.container=t.cy.container(),n=e.cy.window();if(n){var i=n.document,a=i.head,s="__________cytoscape_stylesheet",l="__________cytoscape_container",u=i.getElementById(s)!=null;if(r.className.indexOf(l)<0&&(r.className=(r.className||"")+" "+l),!u){var h=i.createElement("style");h.id=s,h.textContent="."+l+" { position: relative; }",a.insertBefore(h,a.children[0])}var f=n.getComputedStyle(r),d=f.getPropertyValue("position");d==="static"&&un("A Cytoscape container has style position:static and so can not use UI extensions properly")}e.selection=[void 0,void 0,void 0,void 0,0],e.bezierProjPcts=[.05,.225,.4,.5,.6,.775,.95],e.hoverData={down:null,last:null,downTime:null,triggerMode:null,dragging:!1,initialPan:[null,null],capture:!1},e.dragData={possibleDragElements:[]},e.touchData={start:null,capture:!1,startPosition:[null,null,null,null,null,null],singleTouchStartTime:null,singleTouchMoved:!0,now:[null,null,null,null,null,null],earlier:[null,null,null,null,null,null]},e.redraws=0,e.showFps=t.showFps,e.debug=t.debug,e.webgl=t.webgl,e.hideEdgesOnViewport=t.hideEdgesOnViewport,e.textureOnViewport=t.textureOnViewport,e.wheelSensitivity=t.wheelSensitivity,e.motionBlurEnabled=t.motionBlur,e.forcedPixelRatio=Ct(t.pixelRatio)?t.pixelRatio:null,e.motionBlur=t.motionBlur,e.motionBlurOpacity=t.motionBlurOpacity,e.motionBlurTransparency=1-e.motionBlurOpacity,e.motionBlurPxRatio=1,e.mbPxRBlurry=1,e.minMbLowQualFrames=4,e.fullQualityMb=!1,e.clearedForMotionBlur=[],e.desktopTapThreshold=t.desktopTapThreshold,e.desktopTapThreshold2=t.desktopTapThreshold*t.desktopTapThreshold,e.touchTapThreshold=t.touchTapThreshold,e.touchTapThreshold2=t.touchTapThreshold*t.touchTapThreshold,e.tapholdDuration=500,e.bindings=[],e.beforeRenderCallbacks=[],e.beforeRenderPriorities={animations:400,eleCalcs:300,eleTxrDeq:200,lyrTxrDeq:150,lyrTxrSkip:100},e.registerNodeShapes(),e.registerArrowShapes(),e.registerCalculationListeners()};oy.notify=function(t,e){var r=this,n=r.cy;if(!this.destroyed){if(t==="init"){r.load();return}if(t==="destroy"){r.destroy();return}(t==="add"||t==="remove"||t==="move"&&n.hasCompoundNodes()||t==="load"||t==="zorder"||t==="mount")&&r.invalidateCachedZSortedEles(),t==="viewport"&&r.redrawHint("select",!0),t==="gc"&&r.redrawHint("gc",!0),(t==="load"||t==="resize"||t==="mount")&&(r.invalidateContainerClientCoordsCache(),r.matchCanvasSize(r.container)),r.redrawHint("eles",!0),r.redrawHint("drag",!0),this.startRenderLoop(),this.redraw()}};oy.destroy=function(){var t=this;t.destroyed=!0,t.cy.stopAnimationLoop();for(var e=0;e<t.bindings.length;e++){var r=t.bindings[e],n=r,i=n.target;(i.off||i.removeEventListener).apply(i,n.args)}if(t.bindings=[],t.beforeRenderCallbacks=[],t.onUpdateEleCalcsFns=[],t.removeObserver&&t.removeObserver.disconnect(),t.styleObserver&&t.styleObserver.disconnect(),t.resizeObserver&&t.resizeObserver.disconnect(),t.labelCalcDiv)try{document.body.removeChild(t.labelCalcDiv)}catch{}};oy.isHeadless=function(){return!1};[yB,gge,yge,sy,eh,l4].forEach(function(t){rr(oy,t)});DP=1e3/60,xge={setupDequeueing:o(function(e){return o(function(){var n=this,i=this.renderer;if(!n.dequeueingSetup){n.dequeueingSetup=!0;var a=n4(function(){i.redrawHint("eles",!0),i.redrawHint("drag",!0),i.redraw()},e.deqRedrawThreshold),s=o(function(h,f){var d=Qu(),p=i.averageRedrawTime,m=i.lastRedrawTime,g=[],y=i.cy.extent(),v=i.getPixelRatio();for(h||i.flushRenderedStyleQueue();;){var x=Qu(),b=x-d,w=x-f;if(m<DP){var C=DP-(h?p:0);if(w>=e.deqFastCost*C)break}else if(h){if(b>=e.deqCost*m||b>=e.deqAvgCost*p)break}else if(w>=e.deqNoDrawCost*DP)break;var T=e.deq(n,v,y);if(T.length>0)for(var E=0;E<T.length;E++)g.push(T[E]);else break}g.length>0&&(e.onDeqd(n,g),!h&&e.shouldRedraw(n,g,v,y)&&a())},"dequeue"),l=e.priority||rB;i.beforeRender(s,l(n))}},"setupDequeueingImpl")},"setupDequeueing")},RQe=function(){function t(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:bS;Mf(this,t),this.idsByKey=new Xc,this.keyForId=new Xc,this.cachesByLvl=new Xc,this.lvls=[],this.getKey=e,this.doesEleInvalidateKey=r}return o(t,"ElementTextureCacheLookup"),If(t,[{key:"getIdsFor",value:o(function(r){r==null&&ai("Can not get id list for null key");var n=this.idsByKey,i=this.idsByKey.get(r);return i||(i=new J1,n.set(r,i)),i},"getIdsFor")},{key:"addIdForKey",value:o(function(r,n){r!=null&&this.getIdsFor(r).add(n)},"addIdForKey")},{key:"deleteIdForKey",value:o(function(r,n){r!=null&&this.getIdsFor(r).delete(n)},"deleteIdForKey")},{key:"getNumberOfIdsForKey",value:o(function(r){return r==null?0:this.getIdsFor(r).size},"getNumberOfIdsForKey")},{key:"updateKeyMappingFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n),a=this.getKey(r);this.deleteIdForKey(i,n),this.addIdForKey(a,n),this.keyForId.set(n,a)},"updateKeyMappingFor")},{key:"deleteKeyMappingFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n);this.deleteIdForKey(i,n),this.keyForId.delete(n)},"deleteKeyMappingFor")},{key:"keyHasChangedFor",value:o(function(r){var n=r.id(),i=this.keyForId.get(n),a=this.getKey(r);return i!==a},"keyHasChangedFor")},{key:"isInvalid",value:o(function(r){return this.keyHasChangedFor(r)||this.doesEleInvalidateKey(r)},"isInvalid")},{key:"getCachesAt",value:o(function(r){var n=this.cachesByLvl,i=this.lvls,a=n.get(r);return a||(a=new Xc,n.set(r,a),i.push(r)),a},"getCachesAt")},{key:"getCache",value:o(function(r,n){return this.getCachesAt(n).get(r)},"getCache")},{key:"get",value:o(function(r,n){var i=this.getKey(r),a=this.getCache(i,n);return a!=null&&this.updateKeyMappingFor(r),a},"get")},{key:"getForCachedKey",value:o(function(r,n){var i=this.keyForId.get(r.id()),a=this.getCache(i,n);return a},"getForCachedKey")},{key:"hasCache",value:o(function(r,n){return this.getCachesAt(n).has(r)},"hasCache")},{key:"has",value:o(function(r,n){var i=this.getKey(r);return this.hasCache(i,n)},"has")},{key:"setCache",value:o(function(r,n,i){i.key=r,this.getCachesAt(n).set(r,i)},"setCache")},{key:"set",value:o(function(r,n,i){var a=this.getKey(r);this.setCache(a,n,i),this.updateKeyMappingFor(r)},"set")},{key:"deleteCache",value:o(function(r,n){this.getCachesAt(n).delete(r)},"deleteCache")},{key:"delete",value:o(function(r,n){var i=this.getKey(r);this.deleteCache(i,n)},"_delete")},{key:"invalidateKey",value:o(function(r){var n=this;this.lvls.forEach(function(i){return n.deleteCache(r,i)})},"invalidateKey")},{key:"invalidate",value:o(function(r){var n=r.id(),i=this.keyForId.get(n);this.deleteKeyMappingFor(r);var a=this.doesEleInvalidateKey(r);return a&&this.invalidateKey(i),a||this.getNumberOfIdsForKey(i)===0},"invalidate")}]),t}(),I0e=25,sS=50,yS=-4,XP=3,bge=7.99,NQe=8,MQe=1024,IQe=1024,OQe=1024,PQe=.2,BQe=.8,FQe=10,$Qe=.15,zQe=.1,GQe=.9,VQe=.9,UQe=100,HQe=1,H1={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},WQe=la({getKey:null,doesEleInvalidateKey:bS,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:ume,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),Fb=o(function(e,r){var n=this;n.renderer=e,n.onDequeues=[];var i=WQe(r);rr(n,i),n.lookup=new RQe(i.getKey,i.doesEleInvalidateKey),n.setupDequeueing()},"ElementTextureCache"),qi=Fb.prototype;qi.reasons=H1;qi.getTextureQueue=function(t){var e=this;return e.eleImgCaches=e.eleImgCaches||{},e.eleImgCaches[t]=e.eleImgCaches[t]||[]};qi.getRetiredTextureQueue=function(t){var e=this,r=e.eleImgCaches.retired=e.eleImgCaches.retired||{},n=r[t]=r[t]||[];return n};qi.getElementQueue=function(){var t=this,e=t.eleCacheQueue=t.eleCacheQueue||new i4(function(r,n){return n.reqs-r.reqs});return e};qi.getElementKeyToQueue=function(){var t=this,e=t.eleKeyToCacheQueue=t.eleKeyToCacheQueue||{};return e};qi.getElement=function(t,e,r,n,i){var a=this,s=this.renderer,l=s.cy.zoom(),u=this.lookup;if(!e||e.w===0||e.h===0||isNaN(e.w)||isNaN(e.h)||!t.visible()||t.removed()||!a.allowEdgeTxrCaching&&t.isEdge()||!a.allowParentTxrCaching&&t.isParent())return null;if(n==null&&(n=Math.ceil(iB(l*r))),n<yS)n=yS;else if(l>=bge||n>XP)return null;var h=Math.pow(2,n),f=e.h*h,d=e.w*h,p=s.eleTextBiggerThanMin(t,h);if(!this.isVisible(t,p))return null;var m=u.get(t,n);if(m&&m.invalidated&&(m.invalidated=!1,m.texture.invalidatedWidth-=m.width),m)return m;var g;if(f<=I0e?g=I0e:f<=sS?g=sS:g=Math.ceil(f/sS)*sS,f>OQe||d>IQe)return null;var y=a.getTextureQueue(g),v=y[y.length-2],x=o(function(){return a.recycleTexture(g,d)||a.addTexture(g,d)},"addNewTxr");v||(v=y[y.length-1]),v||(v=x()),v.width-v.usedWidth<d&&(v=x());for(var b=o(function(M){return M&&M.scaledLabelShown===p},"scalableFrom"),w=i&&i===H1.dequeue,C=i&&i===H1.highQuality,T=i&&i===H1.downscale,E,A=n+1;A<=XP;A++){var S=u.get(t,A);if(S){E=S;break}}var _=E&&E.level===n+1?E:null,I=o(function(){v.context.drawImage(_.texture.canvas,_.x,0,_.width,_.height,v.usedWidth,0,d,f)},"downscale");if(v.context.setTransform(1,0,0,1,0,0),v.context.clearRect(v.usedWidth,0,d,g),b(_))I();else if(b(E))if(C){for(var D=E.level;D>n;D--)_=a.getElement(t,e,r,D,H1.downscale);I()}else return a.queueElement(t,E.level-1),E;else{var k;if(!w&&!C&&!T)for(var L=n-1;L>=yS;L--){var R=u.get(t,L);if(R){k=R;break}}if(b(k))return a.queueElement(t,n),k;v.context.translate(v.usedWidth,0),v.context.scale(h,h),this.drawElement(v.context,t,e,p,!1),v.context.scale(1/h,1/h),v.context.translate(-v.usedWidth,0)}return m={x:v.usedWidth,texture:v,level:n,scale:h,width:d,height:f,scaledLabelShown:p},v.usedWidth+=Math.ceil(d+NQe),v.eleCaches.push(m),u.set(t,n,m),a.checkTextureFullness(v),m};qi.invalidateElements=function(t){for(var e=0;e<t.length;e++)this.invalidateElement(t[e])};qi.invalidateElement=function(t){var e=this,r=e.lookup,n=[],i=r.isInvalid(t);if(i){for(var a=yS;a<=XP;a++){var s=r.getForCachedKey(t,a);s&&n.push(s)}var l=r.invalidate(t);if(l)for(var u=0;u<n.length;u++){var h=n[u],f=h.texture;f.invalidatedWidth+=h.width,h.invalidated=!0,e.checkTextureUtility(f)}e.removeFromQueue(t)}};qi.checkTextureUtility=function(t){t.invalidatedWidth>=PQe*t.width&&this.retireTexture(t)};qi.checkTextureFullness=function(t){var e=this,r=e.getTextureQueue(t.height);t.usedWidth/t.width>BQe&&t.fullnessChecks>=FQe?Df(r,t):t.fullnessChecks++};qi.retireTexture=function(t){var e=this,r=t.height,n=e.getTextureQueue(r),i=this.lookup;Df(n,t),t.retired=!0;for(var a=t.eleCaches,s=0;s<a.length;s++){var l=a[s];i.deleteCache(l.key,l.level)}nB(a);var u=e.getRetiredTextureQueue(r);u.push(t)};qi.addTexture=function(t,e){var r=this,n=r.getTextureQueue(t),i={};return n.push(i),i.eleCaches=[],i.height=t,i.width=Math.max(MQe,e),i.usedWidth=0,i.invalidatedWidth=0,i.fullnessChecks=0,i.canvas=r.renderer.makeOffscreenCanvas(i.width,i.height),i.context=i.canvas.getContext("2d"),i};qi.recycleTexture=function(t,e){for(var r=this,n=r.getTextureQueue(t),i=r.getRetiredTextureQueue(t),a=0;a<i.length;a++){var s=i[a];if(s.width>=e)return s.retired=!1,s.usedWidth=0,s.invalidatedWidth=0,s.fullnessChecks=0,nB(s.eleCaches),s.context.setTransform(1,0,0,1,0,0),s.context.clearRect(0,0,s.width,s.height),Df(i,s),n.push(s),s}};qi.queueElement=function(t,e){var r=this,n=r.getElementQueue(),i=r.getElementKeyToQueue(),a=this.getKey(t),s=i[a];if(s)s.level=Math.max(s.level,e),s.eles.merge(t),s.reqs++,n.updateItem(s);else{var l={eles:t.spawn().merge(t),level:e,reqs:1,key:a};n.push(l),i[a]=l}};qi.dequeue=function(t){for(var e=this,r=e.getElementQueue(),n=e.getElementKeyToQueue(),i=[],a=e.lookup,s=0;s<HQe&&r.size()>0;s++){var l=r.pop(),u=l.key,h=l.eles[0],f=a.hasCache(h,l.level);if(n[u]=null,f)continue;i.push(l);var d=e.getBoundingBox(h);e.getElement(h,d,t,l.level,H1.dequeue)}return i};qi.removeFromQueue=function(t){var e=this,r=e.getElementQueue(),n=e.getElementKeyToQueue(),i=this.getKey(t),a=n[i];a!=null&&(a.eles.length===1?(a.reqs=tB,r.updateItem(a),r.pop(),n[i]=null):a.eles.unmerge(t))};qi.onDequeue=function(t){this.onDequeues.push(t)};qi.offDequeue=function(t){Df(this.onDequeues,t)};qi.setupDequeueing=xge.setupDequeueing({deqRedrawThreshold:UQe,deqCost:$Qe,deqAvgCost:zQe,deqNoDrawCost:GQe,deqFastCost:VQe,deq:o(function(e,r,n){return e.dequeue(r,n)},"deq"),onDeqd:o(function(e,r){for(var n=0;n<e.onDequeues.length;n++){var i=e.onDequeues[n];i(r)}},"onDeqd"),shouldRedraw:o(function(e,r,n,i){for(var a=0;a<r.length;a++)for(var s=r[a].eles,l=0;l<s.length;l++){var u=s[l].boundingBox();if(aB(u,i))return!0}return!1},"shouldRedraw"),priority:o(function(e){return e.renderer.beforeRenderPriorities.eleTxrDeq},"priority")});qQe=1,zb=-4,_S=2,YQe=3.99,XQe=50,jQe=50,KQe=.15,QQe=.1,ZQe=.9,JQe=.9,eZe=1,O0e=250,tZe=4e3*4e3,P0e=32767,rZe=!0,wge=o(function(e){var r=this,n=r.renderer=e,i=n.cy;r.layersByLevel={},r.firstGet=!0,r.lastInvalidationTime=Qu()-2*O0e,r.skipping=!1,r.eleTxrDeqs=i.collection(),r.scheduleElementRefinement=n4(function(){r.refineElementTextures(r.eleTxrDeqs),r.eleTxrDeqs.unmerge(r.eleTxrDeqs)},jQe),n.beforeRender(function(s,l){l-r.lastInvalidationTime<=O0e?r.skipping=!0:r.skipping=!1},n.beforeRenderPriorities.lyrTxrSkip);var a=o(function(l,u){return u.reqs-l.reqs},"qSort");r.layersQueue=new i4(a),r.setupDequeueing()},"LayeredTextureCache"),Ea=wge.prototype,B0e=0,nZe=Math.pow(2,53)-1;Ea.makeLayer=function(t,e){var r=Math.pow(2,e),n=Math.ceil(t.w*r),i=Math.ceil(t.h*r),a=this.renderer.makeOffscreenCanvas(n,i),s={id:B0e=++B0e%nZe,bb:t,level:e,width:n,height:i,canvas:a,context:a.getContext("2d"),eles:[],elesQueue:[],reqs:0},l=s.context,u=-s.bb.x1,h=-s.bb.y1;return l.scale(r,r),l.translate(u,h),s};Ea.getLayers=function(t,e,r){var n=this,i=n.renderer,a=i.cy,s=a.zoom(),l=n.firstGet;if(n.firstGet=!1,r==null){if(r=Math.ceil(iB(s*e)),r<zb)r=zb;else if(s>=YQe||r>_S)return null}n.validateLayersElesOrdering(r,t);var u=n.layersByLevel,h=Math.pow(2,r),f=u[r]=u[r]||[],d,p=n.levelIsComplete(r,t),m,g=o(function(){var I=o(function(O){if(n.validateLayersElesOrdering(O,t),n.levelIsComplete(O,t))return m=u[O],!0},"canUseAsTmpLvl"),D=o(function(O){if(!m)for(var M=r+O;zb<=M&&M<=_S&&!I(M);M+=O);},"checkLvls");D(1),D(-1);for(var k=f.length-1;k>=0;k--){var L=f[k];L.invalid&&Df(f,L)}},"checkTempLevels");if(!p)g();else return f;var y=o(function(){if(!d){d=Hs();for(var I=0;I<t.length;I++)gme(d,t[I].boundingBox())}return d},"getBb"),v=o(function(I){I=I||{};var D=I.after;y();var k=Math.ceil(d.w*h),L=Math.ceil(d.h*h);if(k>P0e||L>P0e)return null;var R=k*L;if(R>tZe)return null;var O=n.makeLayer(d,r);if(D!=null){var M=f.indexOf(D)+1;f.splice(M,0,O)}else(I.insert===void 0||I.insert)&&f.unshift(O);return O},"makeLayer");if(n.skipping&&!l)return null;for(var x=null,b=t.length/qQe,w=!l,C=0;C<t.length;C++){var T=t[C],E=T._private.rscratch,A=E.imgLayerCaches=E.imgLayerCaches||{},S=A[r];if(S){x=S;continue}if((!x||x.eles.length>=b||!yme(x.bb,T.boundingBox()))&&(x=v({insert:!0,after:x}),!x))return null;m||w?n.queueLayer(x,T):n.drawEleInLayer(x,T,r,e),x.eles.push(T),A[r]=x}return m||(w?null:f)};Ea.getEleLevelForLayerLevel=function(t,e){return t};Ea.drawEleInLayer=function(t,e,r,n){var i=this,a=this.renderer,s=t.context,l=e.boundingBox();l.w===0||l.h===0||!e.visible()||(r=i.getEleLevelForLayerLevel(r,n),a.setImgSmoothing(s,!1),a.drawCachedElement(s,e,null,null,r,rZe),a.setImgSmoothing(s,!0))};Ea.levelIsComplete=function(t,e){var r=this,n=r.layersByLevel[t];if(!n||n.length===0)return!1;for(var i=0,a=0;a<n.length;a++){var s=n[a];if(s.reqs>0||s.invalid)return!1;i+=s.eles.length}return i===e.length};Ea.validateLayersElesOrdering=function(t,e){var r=this.layersByLevel[t];if(r)for(var n=0;n<r.length;n++){for(var i=r[n],a=-1,s=0;s<e.length;s++)if(i.eles[0]===e[s]){a=s;break}if(a<0){this.invalidateLayer(i);continue}for(var l=a,s=0;s<i.eles.length;s++)if(i.eles[s]!==e[l+s]){this.invalidateLayer(i);break}}};Ea.updateElementsInLayers=function(t,e){for(var r=this,n=t4(t[0]),i=0;i<t.length;i++)for(var a=n?null:t[i],s=n?t[i]:t[i].ele,l=s._private.rscratch,u=l.imgLayerCaches=l.imgLayerCaches||{},h=zb;h<=_S;h++){var f=u[h];f&&(a&&r.getEleLevelForLayerLevel(f.level)!==a.level||e(f,s,a))}};Ea.haveLayers=function(){for(var t=this,e=!1,r=zb;r<=_S;r++){var n=t.layersByLevel[r];if(n&&n.length>0){e=!0;break}}return e};Ea.invalidateElements=function(t){var e=this;t.length!==0&&(e.lastInvalidationTime=Qu(),!(t.length===0||!e.haveLayers())&&e.updateElementsInLayers(t,o(function(n,i,a){e.invalidateLayer(n)},"invalAssocLayers")))};Ea.invalidateLayer=function(t){if(this.lastInvalidationTime=Qu(),!t.invalid){var e=t.level,r=t.eles,n=this.layersByLevel[e];Df(n,t),t.elesQueue=[],t.invalid=!0,t.replacement&&(t.replacement.invalid=!0);for(var i=0;i<r.length;i++){var a=r[i]._private.rscratch.imgLayerCaches;a&&(a[e]=null)}}};Ea.refineElementTextures=function(t){var e=this;e.updateElementsInLayers(t,o(function(n,i,a){var s=n.replacement;if(s||(s=n.replacement=e.makeLayer(n.bb,n.level),s.replaces=n,s.eles=n.eles),!s.reqs)for(var l=0;l<s.eles.length;l++)e.queueLayer(s,s.eles[l])},"refineEachEle"))};Ea.enqueueElementRefinement=function(t){this.eleTxrDeqs.merge(t),this.scheduleElementRefinement()};Ea.queueLayer=function(t,e){var r=this,n=r.layersQueue,i=t.elesQueue,a=i.hasId=i.hasId||{};if(!t.replacement){if(e){if(a[e.id()])return;i.push(e),a[e.id()]=!0}t.reqs?(t.reqs++,n.updateItem(t)):(t.reqs=1,n.push(t))}};Ea.dequeue=function(t){for(var e=this,r=e.layersQueue,n=[],i=0;i<eZe&&r.size()!==0;){var a=r.peek();if(a.replacement){r.pop();continue}if(a.replaces&&a!==a.replaces.replacement){r.pop();continue}if(a.invalid){r.pop();continue}var s=a.elesQueue.shift();s&&(e.drawEleInLayer(a,s,a.level,t),i++),n.length===0&&n.push(!0),a.elesQueue.length===0&&(r.pop(),a.reqs=0,a.replaces&&e.applyLayerReplacement(a),e.requestRedraw())}return n};Ea.applyLayerReplacement=function(t){var e=this,r=e.layersByLevel[t.level],n=t.replaces,i=r.indexOf(n);if(!(i<0||n.invalid)){r[i]=t;for(var a=0;a<t.eles.length;a++){var s=t.eles[a]._private,l=s.imgLayerCaches=s.imgLayerCaches||{};l&&(l[t.level]=t)}e.requestRedraw()}};Ea.requestRedraw=n4(function(){var t=this.renderer;t.redrawHint("eles",!0),t.redrawHint("drag",!0),t.redraw()},100);Ea.setupDequeueing=xge.setupDequeueing({deqRedrawThreshold:XQe,deqCost:KQe,deqAvgCost:QQe,deqNoDrawCost:ZQe,deqFastCost:JQe,deq:o(function(e,r){return e.dequeue(r)},"deq"),onDeqd:rB,shouldRedraw:ume,priority:o(function(e){return e.renderer.beforeRenderPriorities.lyrTxrDeq},"priority")});Tge={};o(iZe,"polygon");o(aZe,"triangleBackcurve");o($0e,"triangleTee");o(sZe,"circleTriangle");o(oZe,"circle");Tge.arrowShapeImpl=function(t){return(F0e||(F0e={polygon:iZe,"triangle-backcurve":aZe,"triangle-tee":$0e,"circle-triangle":sZe,"triangle-cross":$0e,circle:oZe}))[t]};Qc={};Qc.drawElement=function(t,e,r,n,i,a){var s=this;e.isNode()?s.drawNode(t,e,r,n,i,a):s.drawEdge(t,e,r,n,i,a)};Qc.drawElementOverlay=function(t,e){var r=this;e.isNode()?r.drawNodeOverlay(t,e):r.drawEdgeOverlay(t,e)};Qc.drawElementUnderlay=function(t,e){var r=this;e.isNode()?r.drawNodeUnderlay(t,e):r.drawEdgeUnderlay(t,e)};Qc.drawCachedElementPortion=function(t,e,r,n,i,a,s,l){var u=this,h=r.getBoundingBox(e);if(!(h.w===0||h.h===0)){var f=r.getElement(e,h,n,i,a);if(f!=null){var d=l(u,e);if(d===0)return;var p=s(u,e),m=h.x1,g=h.y1,y=h.w,v=h.h,x,b,w,C,T;if(p!==0){var E=r.getRotationPoint(e);w=E.x,C=E.y,t.translate(w,C),t.rotate(p),T=u.getImgSmoothing(t),T||u.setImgSmoothing(t,!0);var A=r.getRotationOffset(e);x=A.x,b=A.y}else x=m,b=g;var S;d!==1&&(S=t.globalAlpha,t.globalAlpha=S*d),t.drawImage(f.texture.canvas,f.x,0,f.width,f.height,x,b,y,v),d!==1&&(t.globalAlpha=S),p!==0&&(t.rotate(-p),t.translate(-w,-C),T||u.setImgSmoothing(t,!1))}else r.drawElement(t,e)}};lZe=o(function(){return 0},"getZeroRotation"),cZe=o(function(e,r){return e.getTextAngle(r,null)},"getLabelRotation"),uZe=o(function(e,r){return e.getTextAngle(r,"source")},"getSourceLabelRotation"),hZe=o(function(e,r){return e.getTextAngle(r,"target")},"getTargetLabelRotation"),fZe=o(function(e,r){return r.effectiveOpacity()},"getOpacity"),LP=o(function(e,r){return r.pstyle("text-opacity").pfValue*r.effectiveOpacity()},"getTextOpacity");Qc.drawCachedElement=function(t,e,r,n,i,a){var s=this,l=s.data,u=l.eleTxrCache,h=l.lblTxrCache,f=l.slbTxrCache,d=l.tlbTxrCache,p=e.boundingBox(),m=a===!0?u.reasons.highQuality:null;if(!(p.w===0||p.h===0||!e.visible())&&(!n||aB(p,n))){var g=e.isEdge(),y=e.element()._private.rscratch.badLine;s.drawElementUnderlay(t,e),s.drawCachedElementPortion(t,e,u,r,i,m,lZe,fZe),(!g||!y)&&s.drawCachedElementPortion(t,e,h,r,i,m,cZe,LP),g&&!y&&(s.drawCachedElementPortion(t,e,f,r,i,m,uZe,LP),s.drawCachedElementPortion(t,e,d,r,i,m,hZe,LP)),s.drawElementOverlay(t,e)}};Qc.drawElements=function(t,e){for(var r=this,n=0;n<e.length;n++){var i=e[n];r.drawElement(t,i)}};Qc.drawCachedElements=function(t,e,r,n){for(var i=this,a=0;a<e.length;a++){var s=e[a];i.drawCachedElement(t,s,r,n)}};Qc.drawCachedNodes=function(t,e,r,n){for(var i=this,a=0;a<e.length;a++){var s=e[a];s.isNode()&&i.drawCachedElement(t,s,r,n)}};Qc.drawLayeredElements=function(t,e,r,n){var i=this,a=i.data.lyrTxrCache.getLayers(e,r);if(a)for(var s=0;s<a.length;s++){var l=a[s],u=l.bb;u.w===0||u.h===0||t.drawImage(l.canvas,u.x1,u.y1,u.w,u.h)}else i.drawCachedElements(t,e,r,n)};th={};th.drawEdge=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this,l=e._private.rscratch;if(!(a&&!e.visible())&&!(l.badLine||l.allpts==null||isNaN(l.allpts[0]))){var u;r&&(u=r,t.translate(-u.x1,-u.y1));var h=a?e.pstyle("opacity").value:1,f=a?e.pstyle("line-opacity").value:1,d=e.pstyle("curve-style").value,p=e.pstyle("line-style").value,m=e.pstyle("width").pfValue,g=e.pstyle("line-cap").value,y=e.pstyle("line-outline-width").value,v=e.pstyle("line-outline-color").value,x=h*f,b=h*f,w=o(function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:x;d==="straight-triangle"?(s.eleStrokeStyle(t,e,O),s.drawEdgeTrianglePath(e,t,l.allpts)):(t.lineWidth=m,t.lineCap=g,s.eleStrokeStyle(t,e,O),s.drawEdgePath(e,t,l.allpts,p),t.lineCap="butt")},"drawLine"),C=o(function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:x;if(t.lineWidth=m+y,t.lineCap=g,y>0)s.colorStrokeStyle(t,v[0],v[1],v[2],O);else{t.lineCap="butt";return}d==="straight-triangle"?s.drawEdgeTrianglePath(e,t,l.allpts):(s.drawEdgePath(e,t,l.allpts,p),t.lineCap="butt")},"drawLineOutline"),T=o(function(){i&&s.drawEdgeOverlay(t,e)},"drawOverlay"),E=o(function(){i&&s.drawEdgeUnderlay(t,e)},"drawUnderlay"),A=o(function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:b;s.drawArrowheads(t,e,O)},"drawArrows"),S=o(function(){s.drawElementText(t,e,null,n)},"drawText");t.lineJoin="round";var _=e.pstyle("ghost").value==="yes";if(_){var I=e.pstyle("ghost-offset-x").pfValue,D=e.pstyle("ghost-offset-y").pfValue,k=e.pstyle("ghost-opacity").value,L=x*k;t.translate(I,D),w(L),A(L),t.translate(-I,-D)}else C();E(),w(),A(),T(),S(),r&&t.translate(u.x1,u.y1)}};kge=o(function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(r,n){if(n.visible()){var i=n.pstyle("".concat(e,"-opacity")).value;if(i!==0){var a=this,s=a.usePaths(),l=n._private.rscratch,u=n.pstyle("".concat(e,"-padding")).pfValue,h=2*u,f=n.pstyle("".concat(e,"-color")).value;r.lineWidth=h,l.edgeType==="self"&&!s?r.lineCap="butt":r.lineCap="round",a.colorStrokeStyle(r,f[0],f[1],f[2],i),a.drawEdgePath(n,r,l.allpts,"solid")}}}},"drawEdgeOverlayUnderlay");th.drawEdgeOverlay=kge("overlay");th.drawEdgeUnderlay=kge("underlay");th.drawEdgePath=function(t,e,r,n){var i=t._private.rscratch,a=e,s,l=!1,u=this.usePaths(),h=t.pstyle("line-dash-pattern").pfValue,f=t.pstyle("line-dash-offset").pfValue;if(u){var d=r.join("$"),p=i.pathCacheKey&&i.pathCacheKey===d;p?(s=e=i.pathCache,l=!0):(s=e=new Path2D,i.pathCacheKey=d,i.pathCache=s)}if(a.setLineDash)switch(n){case"dotted":a.setLineDash([1,1]);break;case"dashed":a.setLineDash(h),a.lineDashOffset=f;break;case"solid":a.setLineDash([]);break}if(!l&&!i.badLine)switch(e.beginPath&&e.beginPath(),e.moveTo(r[0],r[1]),i.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var m=2;m+3<r.length;m+=4)e.quadraticCurveTo(r[m],r[m+1],r[m+2],r[m+3]);break;case"straight":case"haystack":for(var g=2;g+1<r.length;g+=2)e.lineTo(r[g],r[g+1]);break;case"segments":if(i.isRound){var y=mo(i.roundCorners),v;try{for(y.s();!(v=y.n()).done;){var x=v.value;hge(e,x)}}catch(w){y.e(w)}finally{y.f()}e.lineTo(r[r.length-2],r[r.length-1])}else for(var b=2;b+1<r.length;b+=2)e.lineTo(r[b],r[b+1]);break}e=a,u?e.stroke(s):e.stroke(),e.setLineDash&&e.setLineDash([])};th.drawEdgeTrianglePath=function(t,e,r){e.fillStyle=e.strokeStyle;for(var n=t.pstyle("width").pfValue,i=0;i+1<r.length;i+=2){var a=[r[i+2]-r[i],r[i+3]-r[i+1]],s=Math.sqrt(a[0]*a[0]+a[1]*a[1]),l=[a[1]/s,-a[0]/s],u=[l[0]*n/2,l[1]*n/2];e.beginPath(),e.moveTo(r[i]-u[0],r[i+1]-u[1]),e.lineTo(r[i]+u[0],r[i+1]+u[1]),e.lineTo(r[i+2],r[i+3]),e.closePath(),e.fill()}};th.drawArrowheads=function(t,e,r){var n=e._private.rscratch,i=n.edgeType==="haystack";i||this.drawArrowhead(t,e,"source",n.arrowStartX,n.arrowStartY,n.srcArrowAngle,r),this.drawArrowhead(t,e,"mid-target",n.midX,n.midY,n.midtgtArrowAngle,r),this.drawArrowhead(t,e,"mid-source",n.midX,n.midY,n.midsrcArrowAngle,r),i||this.drawArrowhead(t,e,"target",n.arrowEndX,n.arrowEndY,n.tgtArrowAngle,r)};th.drawArrowhead=function(t,e,r,n,i,a,s){if(!(isNaN(n)||n==null||isNaN(i)||i==null||isNaN(a)||a==null)){var l=this,u=e.pstyle(r+"-arrow-shape").value;if(u!=="none"){var h=e.pstyle(r+"-arrow-fill").value==="hollow"?"both":"filled",f=e.pstyle(r+"-arrow-fill").value,d=e.pstyle("width").pfValue,p=e.pstyle(r+"-arrow-width"),m=p.value==="match-line"?d:p.pfValue;p.units==="%"&&(m*=d);var g=e.pstyle("opacity").value;s===void 0&&(s=g);var y=t.globalCompositeOperation;(s!==1||f==="hollow")&&(t.globalCompositeOperation="destination-out",l.colorFillStyle(t,255,255,255,1),l.colorStrokeStyle(t,255,255,255,1),l.drawArrowShape(e,t,h,d,u,m,n,i,a),t.globalCompositeOperation=y);var v=e.pstyle(r+"-arrow-color").value;l.colorFillStyle(t,v[0],v[1],v[2],s),l.colorStrokeStyle(t,v[0],v[1],v[2],s),l.drawArrowShape(e,t,f,d,u,m,n,i,a)}}};th.drawArrowShape=function(t,e,r,n,i,a,s,l,u){var h=this,f=this.usePaths()&&i!=="triangle-cross",d=!1,p,m=e,g={x:s,y:l},y=t.pstyle("arrow-scale").value,v=this.getArrowWidth(n,y),x=h.arrowShapes[i];if(f){var b=h.arrowPathCache=h.arrowPathCache||[],w=_f(i),C=b[w];C!=null?(p=e=C,d=!0):(p=e=new Path2D,b[w]=p)}d||(e.beginPath&&e.beginPath(),f?x.draw(e,1,0,{x:0,y:0},1):x.draw(e,v,u,g,n),e.closePath&&e.closePath()),e=m,f&&(e.translate(s,l),e.rotate(u),e.scale(v,v)),(r==="filled"||r==="both")&&(f?e.fill(p):e.fill()),(r==="hollow"||r==="both")&&(e.lineWidth=a/(f?v:1),e.lineJoin="miter",f?e.stroke(p):e.stroke()),f&&(e.scale(1/v,1/v),e.rotate(-u),e.translate(-s,-l))};bB={};bB.safeDrawImage=function(t,e,r,n,i,a,s,l,u,h){if(!(i<=0||a<=0||u<=0||h<=0))try{t.drawImage(e,r,n,i,a,s,l,u,h)}catch(f){un(f)}};bB.drawInscribedImage=function(t,e,r,n,i){var a=this,s=r.position(),l=s.x,u=s.y,h=r.cy().style(),f=h.getIndexedStyle.bind(h),d=f(r,"background-fit","value",n),p=f(r,"background-repeat","value",n),m=r.width(),g=r.height(),y=r.padding()*2,v=m+(f(r,"background-width-relative-to","value",n)==="inner"?0:y),x=g+(f(r,"background-height-relative-to","value",n)==="inner"?0:y),b=r._private.rscratch,w=f(r,"background-clip","value",n),C=w==="node",T=f(r,"background-image-opacity","value",n)*i,E=f(r,"background-image-smoothing","value",n),A=r.pstyle("corner-radius").value;A!=="auto"&&(A=r.pstyle("corner-radius").pfValue);var S=e.width||e.cachedW,_=e.height||e.cachedH;(S==null||_==null)&&(document.body.appendChild(e),S=e.cachedW=e.width||e.offsetWidth,_=e.cachedH=e.height||e.offsetHeight,document.body.removeChild(e));var I=S,D=_;if(f(r,"background-width","value",n)!=="auto"&&(f(r,"background-width","units",n)==="%"?I=f(r,"background-width","pfValue",n)*v:I=f(r,"background-width","pfValue",n)),f(r,"background-height","value",n)!=="auto"&&(f(r,"background-height","units",n)==="%"?D=f(r,"background-height","pfValue",n)*x:D=f(r,"background-height","pfValue",n)),!(I===0||D===0)){if(d==="contain"){var k=Math.min(v/I,x/D);I*=k,D*=k}else if(d==="cover"){var k=Math.max(v/I,x/D);I*=k,D*=k}var L=l-v/2,R=f(r,"background-position-x","units",n),O=f(r,"background-position-x","pfValue",n);R==="%"?L+=(v-I)*O:L+=O;var M=f(r,"background-offset-x","units",n),B=f(r,"background-offset-x","pfValue",n);M==="%"?L+=(v-I)*B:L+=B;var F=u-x/2,P=f(r,"background-position-y","units",n),z=f(r,"background-position-y","pfValue",n);P==="%"?F+=(x-D)*z:F+=z;var $=f(r,"background-offset-y","units",n),H=f(r,"background-offset-y","pfValue",n);$==="%"?F+=(x-D)*H:F+=H,b.pathCache&&(L-=l,F-=u,l=0,u=0);var Q=t.globalAlpha;t.globalAlpha=T;var j=a.getImgSmoothing(t),ie=!1;if(E==="no"&&j?(a.setImgSmoothing(t,!1),ie=!0):E==="yes"&&!j&&(a.setImgSmoothing(t,!0),ie=!0),p==="no-repeat")C&&(t.save(),b.pathCache?t.clip(b.pathCache):(a.nodeShapes[a.getNodeShape(r)].draw(t,l,u,v,x,A,b),t.clip())),a.safeDrawImage(t,e,0,0,S,_,L,F,I,D),C&&t.restore();else{var ne=t.createPattern(e,p);t.fillStyle=ne,a.nodeShapes[a.getNodeShape(r)].draw(t,l,u,v,x,A,b),t.translate(L,F),t.fill(),t.translate(-L,-F)}t.globalAlpha=Q,ie&&a.setImgSmoothing(t,j)}};Yp={};Yp.eleTextBiggerThanMin=function(t,e){if(!e){var r=t.cy().zoom(),n=this.getPixelRatio(),i=Math.ceil(iB(r*n));e=Math.pow(2,i)}var a=t.pstyle("font-size").pfValue*e,s=t.pstyle("min-zoomed-font-size").pfValue;return!(a<s)};Yp.drawElementText=function(t,e,r,n,i){var a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this;if(n==null){if(a&&!s.eleTextBiggerThanMin(e))return}else if(n===!1)return;if(e.isNode()){var l=e.pstyle("label");if(!l||!l.value)return;var u=s.getLabelJustification(e);t.textAlign=u,t.textBaseline="bottom"}else{var h=e.element()._private.rscratch.badLine,f=e.pstyle("label"),d=e.pstyle("source-label"),p=e.pstyle("target-label");if(h||(!f||!f.value)&&(!d||!d.value)&&(!p||!p.value))return;t.textAlign="center",t.textBaseline="bottom"}var m=!r,g;r&&(g=r,t.translate(-g.x1,-g.y1)),i==null?(s.drawText(t,e,null,m,a),e.isEdge()&&(s.drawText(t,e,"source",m,a),s.drawText(t,e,"target",m,a))):s.drawText(t,e,i,m,a),r&&t.translate(g.x1,g.y1)};Yp.getFontCache=function(t){var e;this.fontCaches=this.fontCaches||[];for(var r=0;r<this.fontCaches.length;r++)if(e=this.fontCaches[r],e.context===t)return e;return e={context:t},this.fontCaches.push(e),e};Yp.setupTextStyle=function(t,e){var r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,n=e.pstyle("font-style").strValue,i=e.pstyle("font-size").pfValue+"px",a=e.pstyle("font-family").strValue,s=e.pstyle("font-weight").strValue,l=r?e.effectiveOpacity()*e.pstyle("text-opacity").value:1,u=e.pstyle("text-outline-opacity").value*l,h=e.pstyle("color").value,f=e.pstyle("text-outline-color").value;t.font=n+" "+s+" "+i+" "+a,t.lineJoin="round",this.colorFillStyle(t,h[0],h[1],h[2],l),this.colorStrokeStyle(t,f[0],f[1],f[2],u)};o(RP,"roundRect");Yp.getTextAngle=function(t,e){var r,n=t._private,i=n.rscratch,a=e?e+"-":"",s=t.pstyle(a+"text-rotation");if(s.strValue==="autorotate"){var l=Gl(i,"labelAngle",e);r=t.isEdge()?l:0}else s.strValue==="none"?r=0:r=s.pfValue;return r};Yp.drawText=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=e._private,s=a.rscratch,l=i?e.effectiveOpacity():1;if(!(i&&(l===0||e.pstyle("text-opacity").value===0))){r==="main"&&(r=null);var u=Gl(s,"labelX",r),h=Gl(s,"labelY",r),f,d,p=this.getLabelText(e,r);if(p!=null&&p!==""&&!isNaN(u)&&!isNaN(h)){this.setupTextStyle(t,e,i);var m=r?r+"-":"",g=Gl(s,"labelWidth",r),y=Gl(s,"labelHeight",r),v=e.pstyle(m+"text-margin-x").pfValue,x=e.pstyle(m+"text-margin-y").pfValue,b=e.isEdge(),w=e.pstyle("text-halign").value,C=e.pstyle("text-valign").value;b&&(w="center",C="center"),u+=v,h+=x;var T;switch(n?T=this.getTextAngle(e,r):T=0,T!==0&&(f=u,d=h,t.translate(f,d),t.rotate(T),u=0,h=0),C){case"top":break;case"center":h+=y/2;break;case"bottom":h+=y;break}var E=e.pstyle("text-background-opacity").value,A=e.pstyle("text-border-opacity").value,S=e.pstyle("text-border-width").pfValue,_=e.pstyle("text-background-padding").pfValue,I=e.pstyle("text-background-shape").strValue,D=I.indexOf("round")===0,k=2;if(E>0||S>0&&A>0){var L=u-_;switch(w){case"left":L-=g;break;case"center":L-=g/2;break}var R=h-y-_,O=g+2*_,M=y+2*_;if(E>0){var B=t.fillStyle,F=e.pstyle("text-background-color").value;t.fillStyle="rgba("+F[0]+","+F[1]+","+F[2]+","+E*l+")",D?RP(t,L,R,O,M,k):t.fillRect(L,R,O,M),t.fillStyle=B}if(S>0&&A>0){var P=t.strokeStyle,z=t.lineWidth,$=e.pstyle("text-border-color").value,H=e.pstyle("text-border-style").value;if(t.strokeStyle="rgba("+$[0]+","+$[1]+","+$[2]+","+A*l+")",t.lineWidth=S,t.setLineDash)switch(H){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash([4,2]);break;case"double":t.lineWidth=S/4,t.setLineDash([]);break;case"solid":t.setLineDash([]);break}if(D?RP(t,L,R,O,M,k,"stroke"):t.strokeRect(L,R,O,M),H==="double"){var Q=S/2;D?RP(t,L+Q,R+Q,O-Q*2,M-Q*2,k,"stroke"):t.strokeRect(L+Q,R+Q,O-Q*2,M-Q*2)}t.setLineDash&&t.setLineDash([]),t.lineWidth=z,t.strokeStyle=P}}var j=2*e.pstyle("text-outline-width").pfValue;if(j>0&&(t.lineWidth=j),e.pstyle("text-wrap").value==="wrap"){var ie=Gl(s,"labelWrapCachedLines",r),ne=Gl(s,"labelLineHeight",r),le=g/2,he=this.getLabelJustification(e);switch(he==="auto"||(w==="left"?he==="left"?u+=-g:he==="center"&&(u+=-le):w==="center"?he==="left"?u+=-le:he==="right"&&(u+=le):w==="right"&&(he==="center"?u+=le:he==="right"&&(u+=g))),C){case"top":h-=(ie.length-1)*ne;break;case"center":case"bottom":h-=(ie.length-1)*ne;break}for(var K=0;K<ie.length;K++)j>0&&t.strokeText(ie[K],u,h),t.fillText(ie[K],u,h),h+=ne}else j>0&&t.strokeText(p,u,h),t.fillText(p,u,h);T!==0&&(t.rotate(-T),t.translate(-f,-d))}}};ly={};ly.drawNode=function(t,e,r){var n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0,s=this,l,u,h=e._private,f=h.rscratch,d=e.position();if(!(!Ct(d.x)||!Ct(d.y))&&!(a&&!e.visible())){var p=a?e.effectiveOpacity():1,m=s.usePaths(),g,y=!1,v=e.padding();l=e.width()+2*v,u=e.height()+2*v;var x;r&&(x=r,t.translate(-x.x1,-x.y1));for(var b=e.pstyle("background-image"),w=b.value,C=new Array(w.length),T=new Array(w.length),E=0,A=0;A<w.length;A++){var S=w[A],_=C[A]=S!=null&&S!=="none";if(_){var I=e.cy().style().getIndexedStyle(e,"background-image-crossorigin","value",A);E++,T[A]=s.getCachedImage(S,I,function(){h.backgroundTimestamp=Date.now(),e.emitAndNotify("background")})}}var D=e.pstyle("background-blacken").value,k=e.pstyle("border-width").pfValue,L=e.pstyle("background-opacity").value*p,R=e.pstyle("border-color").value,O=e.pstyle("border-style").value,M=e.pstyle("border-join").value,B=e.pstyle("border-cap").value,F=e.pstyle("border-position").value,P=e.pstyle("border-dash-pattern").pfValue,z=e.pstyle("border-dash-offset").pfValue,$=e.pstyle("border-opacity").value*p,H=e.pstyle("outline-width").pfValue,Q=e.pstyle("outline-color").value,j=e.pstyle("outline-style").value,ie=e.pstyle("outline-opacity").value*p,ne=e.pstyle("outline-offset").value,le=e.pstyle("corner-radius").value;le!=="auto"&&(le=e.pstyle("corner-radius").pfValue);var he=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:L;s.eleFillStyle(t,e,oe)},"setupShapeColor"),K=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:$;s.colorStrokeStyle(t,R[0],R[1],R[2],oe)},"setupBorderColor"),X=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:ie;s.colorStrokeStyle(t,Q[0],Q[1],Q[2],oe)},"setupOutlineColor"),te=o(function(oe,V,xe,q){var pe=s.nodePathCache=s.nodePathCache||[],ve=cme(xe==="polygon"?xe+","+q.join(","):xe,""+V,""+oe,""+le),Pe=pe[ve],_e,we=!1;return Pe!=null?(_e=Pe,we=!0,f.pathCache=_e):(_e=new Path2D,pe[ve]=f.pathCache=_e),{path:_e,cacheHit:we}},"getPath"),J=e.pstyle("shape").strValue,se=e.pstyle("shape-polygon-points").pfValue;if(m){t.translate(d.x,d.y);var ue=te(l,u,J,se);g=ue.path,y=ue.cacheHit}var Z=o(function(){if(!y){var oe=d;m&&(oe={x:0,y:0}),s.nodeShapes[s.getNodeShape(e)].draw(g||t,oe.x,oe.y,l,u,le,f)}m?t.fill(g):t.fill()},"drawShape"),Se=o(function(){for(var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:p,V=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,xe=h.backgrounding,q=0,pe=0;pe<T.length;pe++){var ve=e.cy().style().getIndexedStyle(e,"background-image-containment","value",pe);if(V&&ve==="over"||!V&&ve==="inside"){q++;continue}C[pe]&&T[pe].complete&&!T[pe].error&&(q++,s.drawInscribedImage(t,T[pe],e,pe,oe))}h.backgrounding=q!==E,xe!==h.backgrounding&&e.updateStyle(!1)},"drawImages"),ce=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,V=arguments.length>1&&arguments[1]!==void 0?arguments[1]:p;s.hasPie(e)&&(s.drawPie(t,e,V),oe&&(m||s.nodeShapes[s.getNodeShape(e)].draw(t,d.x,d.y,l,u,le,f)))},"drawPie"),ae=o(function(){var oe=arguments.length>0&&arguments[0]!==void 0?arguments[0]:p,V=(D>0?D:-D)*oe,xe=D>0?0:255;D!==0&&(s.colorFillStyle(t,xe,xe,xe,V),m?t.fill(g):t.fill())},"darken"),Oe=o(function(){if(k>0){if(t.lineWidth=k,t.lineCap=B,t.lineJoin=M,t.setLineDash)switch(O){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash(P),t.lineDashOffset=z;break;case"solid":case"double":t.setLineDash([]);break}if(F!=="center"){if(t.save(),t.lineWidth*=2,F==="inside")m?t.clip(g):t.clip();else{var oe=new Path2D;oe.rect(-l/2-k,-u/2-k,l+2*k,u+2*k),oe.addPath(g),t.clip(oe,"evenodd")}m?t.stroke(g):t.stroke(),t.restore()}else m?t.stroke(g):t.stroke();if(O==="double"){t.lineWidth=k/3;var V=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",m?t.stroke(g):t.stroke(),t.globalCompositeOperation=V}t.setLineDash&&t.setLineDash([])}},"drawBorder"),ge=o(function(){if(H>0){if(t.lineWidth=H,t.lineCap="butt",t.setLineDash)switch(j){case"dotted":t.setLineDash([1,1]);break;case"dashed":t.setLineDash([4,2]);break;case"solid":case"double":t.setLineDash([]);break}var oe=d;m&&(oe={x:0,y:0});var V=s.getNodeShape(e),xe=k;F==="inside"&&(xe=0),F==="outside"&&(xe*=2);var q=(l+xe+(H+ne))/l,pe=(u+xe+(H+ne))/u,ve=l*q,Pe=u*pe,_e=s.nodeShapes[V].points,we;if(m){var Ve=te(ve,Pe,V,_e);we=Ve.path}if(V==="ellipse")s.drawEllipsePath(we||t,oe.x,oe.y,ve,Pe);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(V)){var De=0,qe=0,at=0;V==="round-diamond"?De=(xe+ne+H)*1.4:V==="round-heptagon"?(De=(xe+ne+H)*1.075,at=-(xe/2+ne+H)/35):V==="round-hexagon"?De=(xe+ne+H)*1.12:V==="round-pentagon"?(De=(xe+ne+H)*1.13,at=-(xe/2+ne+H)/15):V==="round-tag"?(De=(xe+ne+H)*1.12,qe=(xe/2+H+ne)*.07):V==="round-triangle"&&(De=(xe+ne+H)*(Math.PI/2),at=-(xe+ne/2+H)/Math.PI),De!==0&&(q=(l+De)/l,ve=l*q,["round-hexagon","round-tag"].includes(V)||(pe=(u+De)/u,Pe=u*pe)),le=le==="auto"?bme(ve,Pe):le;for(var Rt=ve/2,st=Pe/2,Ue=le+(xe+H+ne)/2,ct=new Array(_e.length/2),We=new Array(_e.length/2),ot=0;ot<_e.length/2;ot++)ct[ot]={x:oe.x+qe+Rt*_e[ot*2],y:oe.y+at+st*_e[ot*2+1]};var Yt,bt,Mt,xt,ut=ct.length;for(bt=ct[ut-1],Yt=0;Yt<ut;Yt++)Mt=ct[Yt%ut],xt=ct[(Yt+1)%ut],We[Yt]=vB(bt,Mt,xt,Ue),bt=Mt,Mt=xt;s.drawRoundPolygonPath(we||t,oe.x+qe,oe.y+at,l*q,u*pe,_e,We)}else if(["roundrectangle","round-rectangle"].includes(V))le=le==="auto"?Vp(ve,Pe):le,s.drawRoundRectanglePath(we||t,oe.x,oe.y,ve,Pe,le+(xe+H+ne)/2);else if(["cutrectangle","cut-rectangle"].includes(V))le=le==="auto"?sB():le,s.drawCutRectanglePath(we||t,oe.x,oe.y,ve,Pe,null,le+(xe+H+ne)/4);else if(["bottomroundrectangle","bottom-round-rectangle"].includes(V))le=le==="auto"?Vp(ve,Pe):le,s.drawBottomRoundRectanglePath(we||t,oe.x,oe.y,ve,Pe,le+(xe+H+ne)/2);else if(V==="barrel")s.drawBarrelPath(we||t,oe.x,oe.y,ve,Pe);else if(V.startsWith("polygon")||["rhomboid","right-rhomboid","round-tag","tag","vee"].includes(V)){var Et=(xe+H+ne)/l;_e=wS(TS(_e,Et)),s.drawPolygonPath(we||t,oe.x,oe.y,l,u,_e)}else{var ft=(xe+H+ne)/l;_e=wS(TS(_e,-ft)),s.drawPolygonPath(we||t,oe.x,oe.y,l,u,_e)}if(m?t.stroke(we):t.stroke(),j==="double"){t.lineWidth=xe/3;var yt=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",m?t.stroke(we):t.stroke(),t.globalCompositeOperation=yt}t.setLineDash&&t.setLineDash([])}},"drawOutline"),ze=o(function(){i&&s.drawNodeOverlay(t,e,d,l,u)},"drawOverlay"),He=o(function(){i&&s.drawNodeUnderlay(t,e,d,l,u)},"drawUnderlay"),$e=o(function(){s.drawElementText(t,e,null,n)},"drawText"),Re=e.pstyle("ghost").value==="yes";if(Re){var Ie=e.pstyle("ghost-offset-x").pfValue,be=e.pstyle("ghost-offset-y").pfValue,W=e.pstyle("ghost-opacity").value,de=W*p;t.translate(Ie,be),X(),ge(),he(W*L),Z(),Se(de,!0),K(W*$),Oe(),ce(D!==0||k!==0),Se(de,!1),ae(de),t.translate(-Ie,-be)}m&&t.translate(-d.x,-d.y),He(),m&&t.translate(d.x,d.y),X(),ge(),he(),Z(),Se(p,!0),K(),Oe(),ce(D!==0||k!==0),Se(p,!1),ae(),m&&t.translate(-d.x,-d.y),$e(),ze(),r&&t.translate(x.x1,x.y1)}};Ege=o(function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(r,n,i,a,s){var l=this;if(n.visible()){var u=n.pstyle("".concat(e,"-padding")).pfValue,h=n.pstyle("".concat(e,"-opacity")).value,f=n.pstyle("".concat(e,"-color")).value,d=n.pstyle("".concat(e,"-shape")).value,p=n.pstyle("".concat(e,"-corner-radius")).value;if(h>0){if(i=i||n.position(),a==null||s==null){var m=n.padding();a=n.width()+2*m,s=n.height()+2*m}l.colorFillStyle(r,f[0],f[1],f[2],h),l.nodeShapes[d].draw(r,i.x,i.y,a+u*2,s+u*2,p),r.fill()}}}},"drawNodeOverlayUnderlay");ly.drawNodeOverlay=Ege("overlay");ly.drawNodeUnderlay=Ege("underlay");ly.hasPie=function(t){return t=t[0],t._private.hasPie};ly.drawPie=function(t,e,r,n){e=e[0],n=n||e.position();var i=e.cy().style(),a=e.pstyle("pie-size"),s=n.x,l=n.y,u=e.width(),h=e.height(),f=Math.min(u,h)/2,d=0,p=this.usePaths();p&&(s=0,l=0),a.units==="%"?f=f*a.pfValue:a.pfValue!==void 0&&(f=a.pfValue/2);for(var m=1;m<=i.pieBackgroundN;m++){var g=e.pstyle("pie-"+m+"-background-size").value,y=e.pstyle("pie-"+m+"-background-color").value,v=e.pstyle("pie-"+m+"-background-opacity").value*r,x=g/100;x+d>1&&(x=1-d);var b=1.5*Math.PI+2*Math.PI*d,w=2*Math.PI*x,C=b+w;g===0||d>=1||d+x>1||(t.beginPath(),t.moveTo(s,l),t.arc(s,l,f,b,C),t.closePath(),this.colorFillStyle(t,y[0],y[1],y[2],v),t.fill(),d+=x)}};ys={},dZe=100;ys.getPixelRatio=function(){var t=this.data.contexts[0];if(this.forcedPixelRatio!=null)return this.forcedPixelRatio;var e=this.cy.window(),r=t.backingStorePixelRatio||t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return(e.devicePixelRatio||1)/r};ys.paintCache=function(t){for(var e=this.paintCaches=this.paintCaches||[],r=!0,n,i=0;i<e.length;i++)if(n=e[i],n.context===t){r=!1;break}return r&&(n={context:t},e.push(n)),n};ys.createGradientStyleFor=function(t,e,r,n,i){var a,s=this.usePaths(),l=r.pstyle(e+"-gradient-stop-colors").value,u=r.pstyle(e+"-gradient-stop-positions").pfValue;if(n==="radial-gradient")if(r.isEdge()){var h=r.sourceEndpoint(),f=r.targetEndpoint(),d=r.midpoint(),p=Gp(h,d),m=Gp(f,d);a=t.createRadialGradient(d.x,d.y,0,d.x,d.y,Math.max(p,m))}else{var g=s?{x:0,y:0}:r.position(),y=r.paddedWidth(),v=r.paddedHeight();a=t.createRadialGradient(g.x,g.y,0,g.x,g.y,Math.max(y,v))}else if(r.isEdge()){var x=r.sourceEndpoint(),b=r.targetEndpoint();a=t.createLinearGradient(x.x,x.y,b.x,b.y)}else{var w=s?{x:0,y:0}:r.position(),C=r.paddedWidth(),T=r.paddedHeight(),E=C/2,A=T/2,S=r.pstyle("background-gradient-direction").value;switch(S){case"to-bottom":a=t.createLinearGradient(w.x,w.y-A,w.x,w.y+A);break;case"to-top":a=t.createLinearGradient(w.x,w.y+A,w.x,w.y-A);break;case"to-left":a=t.createLinearGradient(w.x+E,w.y,w.x-E,w.y);break;case"to-right":a=t.createLinearGradient(w.x-E,w.y,w.x+E,w.y);break;case"to-bottom-right":case"to-right-bottom":a=t.createLinearGradient(w.x-E,w.y-A,w.x+E,w.y+A);break;case"to-top-right":case"to-right-top":a=t.createLinearGradient(w.x-E,w.y+A,w.x+E,w.y-A);break;case"to-bottom-left":case"to-left-bottom":a=t.createLinearGradient(w.x+E,w.y-A,w.x-E,w.y+A);break;case"to-top-left":case"to-left-top":a=t.createLinearGradient(w.x+E,w.y+A,w.x-E,w.y-A);break}}if(!a)return null;for(var _=u.length===l.length,I=l.length,D=0;D<I;D++)a.addColorStop(_?u[D]:D/(I-1),"rgba("+l[D][0]+","+l[D][1]+","+l[D][2]+","+i+")");return a};ys.gradientFillStyle=function(t,e,r,n){var i=this.createGradientStyleFor(t,"background",e,r,n);if(!i)return null;t.fillStyle=i};ys.colorFillStyle=function(t,e,r,n,i){t.fillStyle="rgba("+e+","+r+","+n+","+i+")"};ys.eleFillStyle=function(t,e,r){var n=e.pstyle("background-fill").value;if(n==="linear-gradient"||n==="radial-gradient")this.gradientFillStyle(t,e,n,r);else{var i=e.pstyle("background-color").value;this.colorFillStyle(t,i[0],i[1],i[2],r)}};ys.gradientStrokeStyle=function(t,e,r,n){var i=this.createGradientStyleFor(t,"line",e,r,n);if(!i)return null;t.strokeStyle=i};ys.colorStrokeStyle=function(t,e,r,n,i){t.strokeStyle="rgba("+e+","+r+","+n+","+i+")"};ys.eleStrokeStyle=function(t,e,r){var n=e.pstyle("line-fill").value;if(n==="linear-gradient"||n==="radial-gradient")this.gradientStrokeStyle(t,e,n,r);else{var i=e.pstyle("line-color").value;this.colorStrokeStyle(t,i[0],i[1],i[2],r)}};ys.matchCanvasSize=function(t){var e=this,r=e.data,n=e.findContainerClientCoords(),i=n[2],a=n[3],s=e.getPixelRatio(),l=e.motionBlurPxRatio;(t===e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_NODE]||t===e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_DRAG])&&(s=l);var u=i*s,h=a*s,f;if(!(u===e.canvasWidth&&h===e.canvasHeight)){e.fontCaches=null;var d=r.canvasContainer;d.style.width=i+"px",d.style.height=a+"px";for(var p=0;p<e.CANVAS_LAYERS;p++)f=r.canvases[p],f.width=u,f.height=h,f.style.width=i+"px",f.style.height=a+"px";for(var p=0;p<e.BUFFER_COUNT;p++)f=r.bufferCanvases[p],f.width=u,f.height=h,f.style.width=i+"px",f.style.height=a+"px";e.textureMult=1,s<=1&&(f=r.bufferCanvases[e.TEXTURE_BUFFER],e.textureMult=2,f.width=u*e.textureMult,f.height=h*e.textureMult),e.canvasWidth=u,e.canvasHeight=h,e.pixelRatio=s}};ys.renderTo=function(t,e,r,n){this.render({forcedContext:t,forcedZoom:e,forcedPan:r,drawAllLayers:!0,forcedPxRatio:n})};ys.clearCanvas=function(){var t=this,e=t.data;function r(n){n.clearRect(0,0,t.canvasWidth,t.canvasHeight)}o(r,"clear"),r(e.contexts[t.NODE]),r(e.contexts[t.DRAG])};ys.render=function(t){var e=this;t=t||dme();var r=e.cy,n=t.forcedContext,i=t.drawAllLayers,a=t.drawOnlyNodeLayer,s=t.forcedZoom,l=t.forcedPan,u=t.forcedPxRatio===void 0?this.getPixelRatio():t.forcedPxRatio,h=e.data,f=h.canvasNeedsRedraw,d=e.textureOnViewport&&!n&&(e.pinching||e.hoverData.dragging||e.swipePanning||e.data.wheelZooming),p=t.motionBlur!==void 0?t.motionBlur:e.motionBlur,m=e.motionBlurPxRatio,g=r.hasCompoundNodes(),y=e.hoverData.draggingEles,v=!!(e.hoverData.selecting||e.touchData.selecting);p=p&&!n&&e.motionBlurEnabled&&!v;var x=p;n||(e.prevPxRatio!==u&&(e.invalidateContainerClientCoordsCache(),e.matchCanvasSize(e.container),e.redrawHint("eles",!0),e.redrawHint("drag",!0)),e.prevPxRatio=u),!n&&e.motionBlurTimeout&&clearTimeout(e.motionBlurTimeout),p&&(e.mbFrames==null&&(e.mbFrames=0),e.mbFrames++,e.mbFrames<3&&(x=!1),e.mbFrames>e.minMbLowQualFrames&&(e.motionBlurPxRatio=e.mbPxRBlurry)),e.clearingMotionBlur&&(e.motionBlurPxRatio=1),e.textureDrawLastFrame&&!d&&(f[e.NODE]=!0,f[e.SELECT_BOX]=!0);var b=r.style(),w=r.zoom(),C=s!==void 0?s:w,T=r.pan(),E={x:T.x,y:T.y},A={zoom:w,pan:{x:T.x,y:T.y}},S=e.prevViewport,_=S===void 0||A.zoom!==S.zoom||A.pan.x!==S.pan.x||A.pan.y!==S.pan.y;!_&&!(y&&!g)&&(e.motionBlurPxRatio=1),l&&(E=l),C*=u,E.x*=u,E.y*=u;var I=e.getCachedZSortedEles();function D(K,X,te,J,se){var ue=K.globalCompositeOperation;K.globalCompositeOperation="destination-out",e.colorFillStyle(K,255,255,255,e.motionBlurTransparency),K.fillRect(X,te,J,se),K.globalCompositeOperation=ue}o(D,"mbclear");function k(K,X){var te,J,se,ue;!e.clearingMotionBlur&&(K===h.bufferContexts[e.MOTIONBLUR_BUFFER_NODE]||K===h.bufferContexts[e.MOTIONBLUR_BUFFER_DRAG])?(te={x:T.x*m,y:T.y*m},J=w*m,se=e.canvasWidth*m,ue=e.canvasHeight*m):(te=E,J=C,se=e.canvasWidth,ue=e.canvasHeight),K.setTransform(1,0,0,1,0,0),X==="motionBlur"?D(K,0,0,se,ue):!n&&(X===void 0||X)&&K.clearRect(0,0,se,ue),i||(K.translate(te.x,te.y),K.scale(J,J)),l&&K.translate(l.x,l.y),s&&K.scale(s,s)}if(o(k,"setContextTransform"),d||(e.textureDrawLastFrame=!1),d){if(e.textureDrawLastFrame=!0,!e.textureCache){e.textureCache={},e.textureCache.bb=r.mutableElements().boundingBox(),e.textureCache.texture=e.data.bufferCanvases[e.TEXTURE_BUFFER];var L=e.data.bufferContexts[e.TEXTURE_BUFFER];L.setTransform(1,0,0,1,0,0),L.clearRect(0,0,e.canvasWidth*e.textureMult,e.canvasHeight*e.textureMult),e.render({forcedContext:L,drawOnlyNodeLayer:!0,forcedPxRatio:u*e.textureMult});var A=e.textureCache.viewport={zoom:r.zoom(),pan:r.pan(),width:e.canvasWidth,height:e.canvasHeight};A.mpan={x:(0-A.pan.x)/A.zoom,y:(0-A.pan.y)/A.zoom}}f[e.DRAG]=!1,f[e.NODE]=!1;var R=h.contexts[e.NODE],O=e.textureCache.texture,A=e.textureCache.viewport;R.setTransform(1,0,0,1,0,0),p?D(R,0,0,A.width,A.height):R.clearRect(0,0,A.width,A.height);var M=b.core("outside-texture-bg-color").value,B=b.core("outside-texture-bg-opacity").value;e.colorFillStyle(R,M[0],M[1],M[2],B),R.fillRect(0,0,A.width,A.height);var w=r.zoom();k(R,!1),R.clearRect(A.mpan.x,A.mpan.y,A.width/A.zoom/u,A.height/A.zoom/u),R.drawImage(O,A.mpan.x,A.mpan.y,A.width/A.zoom/u,A.height/A.zoom/u)}else e.textureOnViewport&&!n&&(e.textureCache=null);var F=r.extent(),P=e.pinching||e.hoverData.dragging||e.swipePanning||e.data.wheelZooming||e.hoverData.draggingEles||e.cy.animated(),z=e.hideEdgesOnViewport&&P,$=[];if($[e.NODE]=!f[e.NODE]&&p&&!e.clearedForMotionBlur[e.NODE]||e.clearingMotionBlur,$[e.NODE]&&(e.clearedForMotionBlur[e.NODE]=!0),$[e.DRAG]=!f[e.DRAG]&&p&&!e.clearedForMotionBlur[e.DRAG]||e.clearingMotionBlur,$[e.DRAG]&&(e.clearedForMotionBlur[e.DRAG]=!0),f[e.NODE]||i||a||$[e.NODE]){var H=p&&!$[e.NODE]&&m!==1,R=n||(H?e.data.bufferContexts[e.MOTIONBLUR_BUFFER_NODE]:h.contexts[e.NODE]),Q=p&&!H?"motionBlur":void 0;k(R,Q),z?e.drawCachedNodes(R,I.nondrag,u,F):e.drawLayeredElements(R,I.nondrag,u,F),e.debug&&e.drawDebugPoints(R,I.nondrag),!i&&!p&&(f[e.NODE]=!1)}if(!a&&(f[e.DRAG]||i||$[e.DRAG])){var H=p&&!$[e.DRAG]&&m!==1,R=n||(H?e.data.bufferContexts[e.MOTIONBLUR_BUFFER_DRAG]:h.contexts[e.DRAG]);k(R,p&&!H?"motionBlur":void 0),z?e.drawCachedNodes(R,I.drag,u,F):e.drawCachedElements(R,I.drag,u,F),e.debug&&e.drawDebugPoints(R,I.drag),!i&&!p&&(f[e.DRAG]=!1)}if(this.drawSelectionRectangle(t,k),p&&m!==1){var j=h.contexts[e.NODE],ie=e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_NODE],ne=h.contexts[e.DRAG],le=e.data.bufferCanvases[e.MOTIONBLUR_BUFFER_DRAG],he=o(function(X,te,J){X.setTransform(1,0,0,1,0,0),J||!x?X.clearRect(0,0,e.canvasWidth,e.canvasHeight):D(X,0,0,e.canvasWidth,e.canvasHeight);var se=m;X.drawImage(te,0,0,e.canvasWidth*se,e.canvasHeight*se,0,0,e.canvasWidth,e.canvasHeight)},"drawMotionBlur");(f[e.NODE]||$[e.NODE])&&(he(j,ie,$[e.NODE]),f[e.NODE]=!1),(f[e.DRAG]||$[e.DRAG])&&(he(ne,le,$[e.DRAG]),f[e.DRAG]=!1)}e.prevViewport=A,e.clearingMotionBlur&&(e.clearingMotionBlur=!1,e.motionBlurCleared=!0,e.motionBlur=!0),p&&(e.motionBlurTimeout=setTimeout(function(){e.motionBlurTimeout=null,e.clearedForMotionBlur[e.NODE]=!1,e.clearedForMotionBlur[e.DRAG]=!1,e.motionBlur=!1,e.clearingMotionBlur=!d,e.mbFrames=0,f[e.NODE]=!0,f[e.DRAG]=!0,e.redraw()},dZe)),n||r.emit("render")};ys.drawSelectionRectangle=function(t,e){var r=this,n=r.cy,i=r.data,a=n.style(),s=t.drawOnlyNodeLayer,l=t.drawAllLayers,u=i.canvasNeedsRedraw,h=t.forcedContext;if(r.showFps||!s&&u[r.SELECT_BOX]&&!l){var f=h||i.contexts[r.SELECT_BOX];if(e(f),r.selection[4]==1&&(r.hoverData.selecting||r.touchData.selecting)){var d=r.cy.zoom(),p=a.core("selection-box-border-width").value/d;f.lineWidth=p,f.fillStyle="rgba("+a.core("selection-box-color").value[0]+","+a.core("selection-box-color").value[1]+","+a.core("selection-box-color").value[2]+","+a.core("selection-box-opacity").value+")",f.fillRect(r.selection[0],r.selection[1],r.selection[2]-r.selection[0],r.selection[3]-r.selection[1]),p>0&&(f.strokeStyle="rgba("+a.core("selection-box-border-color").value[0]+","+a.core("selection-box-border-color").value[1]+","+a.core("selection-box-border-color").value[2]+","+a.core("selection-box-opacity").value+")",f.strokeRect(r.selection[0],r.selection[1],r.selection[2]-r.selection[0],r.selection[3]-r.selection[1]))}if(i.bgActivePosistion&&!r.hoverData.selecting){var d=r.cy.zoom(),m=i.bgActivePosistion;f.fillStyle="rgba("+a.core("active-bg-color").value[0]+","+a.core("active-bg-color").value[1]+","+a.core("active-bg-color").value[2]+","+a.core("active-bg-opacity").value+")",f.beginPath(),f.arc(m.x,m.y,a.core("active-bg-size").pfValue/d,0,2*Math.PI),f.fill()}var g=r.lastRedrawTime;if(r.showFps&&g){g=Math.round(g);var y=Math.round(1e3/g),v="1 frame = "+g+" ms = "+y+" fps";if(f.setTransform(1,0,0,1,0,0),f.fillStyle="rgba(255, 0, 0, 0.75)",f.strokeStyle="rgba(255, 0, 0, 0.75)",f.font="30px Arial",!Nb){var x=f.measureText(v);Nb=x.actualBoundingBoxAscent}f.fillText(v,0,Nb);var b=60;f.strokeRect(0,Nb+10,250,20),f.fillRect(0,Nb+10,250*Math.min(y/b,1),20)}l||(u[r.SELECT_BOX]=!1)}};o(z0e,"compileShader");o(pZe,"createProgram");o(mZe,"createTextureCanvas");o(wB,"getEffectivePanZoom");o(NP,"modelToRenderedPosition");o(oS,"toWebGLColor");o(lS,"indexToVec4");o(gZe,"vec4ToIndex");o(yZe,"createTexture");o(Sge,"getTypeInfo");o(Cge,"createTypedArray");o(vZe,"createTypedArrayView");o(xZe,"createBufferStaticDraw");o(po,"createBufferDynamicDraw");o(bZe,"createPickingFrameBuffer");G0e=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});o(Gb,"create");o(Age,"identity");o(wZe,"multiply");o(DS,"translate");o(_ge,"rotate");o(TB,"scale");o(TZe,"projection");Vb={SCREEN:{name:"screen",screen:!0},PICKING:{name:"picking",picking:!0}},Mb=la({getKey:null,drawElement:null,getBoundingBox:null,getRotation:null,getRotationPoint:null,getRotationOffset:null,isVisible:null,getPadding:null}),kZe=function(){function t(e,r){Mf(this,t),this.debugID=Math.floor(Math.random()*1e4),this.r=e,this.atlasSize=r.webglTexSize,this.rows=r.webglTexRows,this.enableWrapping=r.enableWrapping,this.texHeight=Math.floor(this.atlasSize/this.rows),this.maxTexWidth=this.atlasSize,this.texture=null,this.canvas=null,this.needsBuffer=!0,this.freePointer={x:0,row:0},this.keyToLocation=new Map,this.canvas=r.createTextureCanvas(e,this.atlasSize,this.atlasSize),this.scratch=r.createTextureCanvas(e,this.atlasSize,this.texHeight,"scratch")}return o(t,"Atlas"),If(t,[{key:"getKeys",value:o(function(){return new Set(this.keyToLocation.keys())},"getKeys")},{key:"getScale",value:o(function(r){var n=r.w,i=r.h,a=this.texHeight,s=this.maxTexWidth,l=a/i,u=n*l,h=i*l;return u>s&&(l=s/n,u=n*l,h=i*l),{scale:l,texW:u,texH:h}},"getScale")},{key:"draw",value:o(function(r,n,i){var a=this,s=this.atlasSize,l=this.rows,u=this.texHeight,h=this.getScale(n),f=h.scale,d=h.texW,p=h.texH,m=[null,null],g=o(function(w,C){if(i&&C){var T=C.context,E=w.x,A=w.row,S=E,_=u*A;T.save(),T.translate(S,_),T.scale(f,f),i(T,n),T.restore()}},"drawAt"),y=o(function(){g(a.freePointer,a.canvas),m[0]={x:a.freePointer.x,y:a.freePointer.row*u,w:d,h:p},m[1]={x:a.freePointer.x+d,y:a.freePointer.row*u,w:0,h:p},a.freePointer.x+=d,a.freePointer.x==s&&(a.freePointer.x=0,a.freePointer.row++)},"drawNormal"),v=o(function(){var w=a.scratch,C=a.canvas;w.clear(),g({x:0,row:0},w);var T=s-a.freePointer.x,E=d-T,A=u;{var S=a.freePointer.x,_=a.freePointer.row*u,I=T;C.context.drawImage(w,0,0,I,A,S,_,I,A),m[0]={x:S,y:_,w:I,h:p}}{var D=T,k=(a.freePointer.row+1)*u,L=E;C&&C.context.drawImage(w,D,0,L,A,0,k,L,A),m[1]={x:0,y:k,w:L,h:p}}a.freePointer.x=E,a.freePointer.row++},"drawWrapped"),x=o(function(){a.freePointer.x=0,a.freePointer.row++},"moveToStartOfNextRow");if(this.freePointer.x+d<=s)y();else{if(this.freePointer.row>=l-1)return!1;this.freePointer.x===s?(x(),y()):this.enableWrapping?v():(x(),y())}return this.keyToLocation.set(r,m),this.needsBuffer=!0,m},"draw")},{key:"getOffsets",value:o(function(r){return this.keyToLocation.get(r)},"getOffsets")},{key:"isEmpty",value:o(function(){return this.freePointer.x===0&&this.freePointer.row===0},"isEmpty")},{key:"canFit",value:o(function(r){var n=this.atlasSize,i=this.rows,a=this.getScale(r),s=a.texW;return this.freePointer.x+s>n?this.freePointer.row<i-1:!0},"canFit")},{key:"bufferIfNeeded",value:o(function(r){this.texture||(this.texture=yZe(r,this.debugID)),this.needsBuffer&&(this.texture.buffer(this.canvas),this.needsBuffer=!1)},"bufferIfNeeded")},{key:"dispose",value:o(function(){this.texture&&(this.texture.deleteTexture(),this.texture=null,this.needsBuffer=!0)},"dispose")}]),t}(),EZe=function(){function t(e,r){Mf(this,t),this.r=e,this.opts=r,this.keyToIds=new Map,this.idToKey=new Map,this.atlases=[],this.styleKeyToAtlas=new Map,this.styleKeyNeedsRedraw=new Set,this.forceGC=!1}return o(t,"AtlasCollection"),If(t,[{key:"getKeys",value:o(function(){return new Set(this.styleKeyToAtlas.keys())},"getKeys")},{key:"getIdsFor",value:o(function(r){var n=this.keyToIds.get(r);return n||(n=new Set,this.keyToIds.set(r,n)),n},"getIdsFor")},{key:"_createAtlas",value:o(function(){var r=this.r,n=this.opts;return new kZe(r,n)},"_createAtlas")},{key:"_getScratchCanvas",value:o(function(){if(!this.scratch){var r=this.r,n=this.opts,i=n.webglTexSize,a=Math.floor(i/n.webglTexRows);this.scratch=n.createTextureCanvas(r,i,a,"scratch")}return this.scratch},"_getScratchCanvas")},{key:"draw",value:o(function(r,n,i,a){if(this.styleKeyNeedsRedraw.has(n)){this.styleKeyNeedsRedraw.delete(n),this.deleteKey(r,n);var s=this.styleKeyToAtlas.get(n);s&&(s.forceGC=!0),this.styleKeyToAtlas.delete(n)}var l=this.styleKeyToAtlas.get(n);return l||(l=this.atlases[this.atlases.length-1],(!l||!l.canFit(i))&&(l=this._createAtlas(),this.atlases.push(l)),l.draw(n,i,a),this.styleKeyToAtlas.set(n,l),this.getIdsFor(n).add(r),this.idToKey.set(r,n)),l},"draw")},{key:"getAtlas",value:o(function(r){return this.styleKeyToAtlas.get(r)},"getAtlas")},{key:"hasAtlas",value:o(function(r){return this.styleKeyToAtlas.has(r)},"hasAtlas")},{key:"deleteKey",value:o(function(r,n){this.idToKey.delete(r),this.getIdsFor(n).delete(r)},"deleteKey")},{key:"checkKeyIsInvalid",value:o(function(r,n){if(!this.idToKey.has(r))return!1;var i=this.idToKey.get(r);return i!=n?(this.deleteKey(r,i),!0):!1},"checkKeyIsInvalid")},{key:"_getKeysToCollect",value:o(function(){var r=new Set,n=mo(this.styleKeyToAtlas.keys()),i;try{for(n.s();!(i=n.n()).done;){var a=i.value;this.getIdsFor(a).size==0&&r.add(a)}}catch(s){n.e(s)}finally{n.f()}return r},"_getKeysToCollect")},{key:"gc",value:o(function(){var r=this,n=this.atlases.some(function(p){return p.forceGC}),i=this._getKeysToCollect();if(i.size===0&&!n){console.log("nothing to garbage collect");return}var a=[],s=new Map,l=null,u=mo(this.atlases),h;try{var f=o(function(){var m=h.value,g=m.getKeys(),y=SZe(i,g);if(y.size===0&&!m.forceGC)return a.push(m),g.forEach(function(A){return s.set(A,m)}),"continue";l||(l=r._createAtlas(),a.push(l));var v=mo(g),x;try{for(v.s();!(x=v.n()).done;){var b=x.value;if(!y.has(b)){var w=m.getOffsets(b),C=_i(w,2),T=C[0],E=C[1];l.canFit({w:T.w+E.w,h:T.h})||(l=r._createAtlas(),a.push(l)),r._copyTextureToNewAtlas(b,m,l),s.set(b,l)}}}catch(A){v.e(A)}finally{v.f()}},"_loop");for(u.s();!(h=u.n()).done;)var d=f()}catch(p){u.e(p)}finally{u.f()}this.atlases=a,this.styleKeyToAtlas=s},"gc")},{key:"_copyTextureToNewAtlas",value:o(function(r,n,i){var a=n.getOffsets(r),s=_i(a,2),l=s[0],u=s[1];if(u.w===0)i.draw(r,l,function(p){p.drawImage(n.canvas,l.x,l.y,l.w,l.h,0,0,l.w,l.h)});else{var h=this._getScratchCanvas();h.clear(),h.context.drawImage(n.canvas,l.x,l.y,l.w,l.h,0,0,l.w,l.h),h.context.drawImage(n.canvas,u.x,u.y,u.w,u.h,l.w,0,u.w,u.h);var f=l.w+u.w,d=l.h;i.draw(r,{w:f,h:d},function(p){p.drawImage(h,0,0,f,d,0,0,f,d)})}},"_copyTextureToNewAtlas")},{key:"getCounts",value:o(function(){return{keyCount:this.styleKeyToAtlas.size,atlasCount:new Set(this.styleKeyToAtlas.values()).size}},"getCounts")}]),t}();o(SZe,"intersection");CZe=function(){function t(e,r){Mf(this,t),this.r=e;var n=r;this.globalOptions=n,this.maxAtlases=n.webglTexPerBatch,this.atlasSize=n.webglTexSize,this.renderTypes=new Map,this.maxAtlasesPerBatch=r.webglTexPerBatch,this.batchAtlases=[],this._cacheScratchCanvas(n)}return o(t,"AtlasManager"),If(t,[{key:"_cacheScratchCanvas",value:o(function(r){var n=-1,i=-1,a=null,s=r.createTextureCanvas;r.createTextureCanvas=function(l,u,h,f){return f?((!a||u!=n||h!=i)&&(n=u,i=h,a=s(l,u,h)),a):s(l,u,h)}},"_cacheScratchCanvas")},{key:"addRenderType",value:o(function(r,n){var i=new EZe(this.r,this.globalOptions),a=n;this.renderTypes.set(r,rr({type:r,atlasCollection:i},a))},"addRenderType")},{key:"getRenderTypes",value:o(function(){return j0e(this.renderTypes.values())},"getRenderTypes")},{key:"getRenderTypeOpts",value:o(function(r){return this.renderTypes.get(r)},"getRenderTypeOpts")},{key:"invalidate",value:o(function(r){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=n.forceRedraw,a=i===void 0?!1:i,s=n.filterEle,l=s===void 0?function(){return!0}:s,u=n.filterType,h=u===void 0?function(){return!0}:u,f=!1,d=mo(r),p;try{for(d.s();!(p=d.n()).done;){var m=p.value;if(l(m)){var g=m.id(),y=mo(this.getRenderTypes()),v;try{for(y.s();!(v=y.n()).done;){var x=v.value;if(h(x.type)){var b=x.getKey(m);a?(x.atlasCollection.deleteKey(g,b),x.atlasCollection.styleKeyNeedsRedraw.add(b),f=!0):f|=x.atlasCollection.checkKeyIsInvalid(g,b)}}}catch(w){y.e(w)}finally{y.f()}}}}catch(w){d.e(w)}finally{d.f()}return f},"invalidate")},{key:"gc",value:o(function(){var r=mo(this.getRenderTypes()),n;try{for(r.s();!(n=r.n()).done;){var i=n.value;i.atlasCollection.gc()}}catch(a){r.e(a)}finally{r.f()}},"gc")},{key:"isRenderable",value:o(function(r,n){var i=this.getRenderTypeOpts(n);return i&&i.isVisible(r)},"isRenderable")},{key:"startBatch",value:o(function(){this.batchAtlases=[]},"startBatch")},{key:"getAtlasCount",value:o(function(){return this.batchAtlases.length},"getAtlasCount")},{key:"getAtlases",value:o(function(){return this.batchAtlases},"getAtlases")},{key:"getOrCreateAtlas",value:o(function(r,n,i){var a=this.renderTypes.get(i),s=a.getKey(r),l=r.id();return a.atlasCollection.draw(l,s,n,function(u){a.drawElement(u,r,n,!0,!0)})},"getOrCreateAtlas")},{key:"getAtlasIndexForBatch",value:o(function(r){var n=this.batchAtlases.indexOf(r);if(n<0){if(this.batchAtlases.length===this.maxAtlasesPerBatch)return;this.batchAtlases.push(r),n=this.batchAtlases.length-1}return n},"getAtlasIndexForBatch")},{key:"getIndexArray",value:o(function(){return Array.from({length:this.maxAtlases},function(r,n){return n})},"getIndexArray")},{key:"getAtlasInfo",value:o(function(r,n){var i=this.renderTypes.get(n),a=i.getBoundingBox(r),s=this.getOrCreateAtlas(r,a,n),l=this.getAtlasIndexForBatch(s);if(l!==void 0){var u=i.getKey(r),h=s.getOffsets(u),f=_i(h,2),d=f[0],p=f[1];return{atlasID:l,tex:d,tex1:d,tex2:p,bb:a,type:n,styleKey:u}}},"getAtlasInfo")},{key:"canAddToCurrentBatch",value:o(function(r,n){if(this.batchAtlases.length===this.maxAtlasesPerBatch){var i=this.renderTypes.get(n),a=i.getKey(r),s=i.atlasCollection.getAtlas(a);return s&&this.batchAtlases.includes(s)}return!0},"canAddToCurrentBatch")},{key:"setTransformMatrix",value:o(function(r,n,i){var a=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,s=n.bb,l=n.type,u=n.tex1,h=n.tex2,f=this.getRenderTypeOpts(l),d=f.getPadding?f.getPadding(i):0,p=u.w/(u.w+h.w);a||(p=1-p);var m=this.getAdjustedBB(s,d,a,p),g,y;Age(r);var v=f.getRotation?f.getRotation(i):0;if(v!==0){var x=f.getRotationPoint(i),b=x.x,w=x.y;DS(r,r,[b,w]),_ge(r,r,v);var C=f.getRotationOffset(i);g=C.x+m.xOffset,y=C.y}else g=m.x1,y=m.y1;DS(r,r,[g,y]),TB(r,r,[m.w,m.h])},"setTransformMatrix")},{key:"getTransformMatrix",value:o(function(r,n){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,a=Gb();return this.setTransformMatrix(a,r,n,i),a},"getTransformMatrix")},{key:"getAdjustedBB",value:o(function(r,n,i,a){var s=r.x1,l=r.y1,u=r.w,h=r.h;n&&(s-=n,l-=n,u+=2*n,h+=2*n);var f=0,d=u*a;return i&&a<1?u=d:!i&&a<1&&(f=u-d,s+=f,u=d),{x1:s,y1:l,w:u,h,xOffset:f}},"getAdjustedBB")},{key:"getDebugInfo",value:o(function(){var r=[],n=mo(this.renderTypes),i;try{for(n.s();!(i=n.n()).done;){var a=_i(i.value,2),s=a[0],l=a[1],u=l.atlasCollection.getCounts(),h=u.keyCount,f=u.atlasCount;r.push({type:s,keyCount:h,atlasCount:f})}}catch(d){n.e(d)}finally{n.f()}return r},"getDebugInfo")}]),t}(),MP=0,V0e=1,U0e=2,IP=3,AZe=function(){function t(e,r,n){Mf(this,t),this.r=e,this.gl=r,this.maxInstances=n.webglBatchSize,this.maxAtlases=n.webglTexPerBatch,this.atlasSize=n.webglTexSize,this.bgColor=n.bgColor,n.enableWrapping=!0,n.createTextureCanvas=mZe,this.atlasManager=new CZe(e,n),this.program=this.createShaderProgram(Vb.SCREEN),this.pickingProgram=this.createShaderProgram(Vb.PICKING),this.vao=this.createVAO(),this.debugInfo=[]}return o(t,"ElementDrawingWebGL"),If(t,[{key:"addTextureRenderType",value:o(function(r,n){this.atlasManager.addRenderType(r,n)},"addTextureRenderType")},{key:"invalidate",value:o(function(r){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=n.type,a=this.atlasManager;return i?a.invalidate(r,{filterType:o(function(l){return l===i},"filterType"),forceRedraw:!0}):a.invalidate(r)},"invalidate")},{key:"gc",value:o(function(){this.atlasManager.gc()},"gc")},{key:"createShaderProgram",value:o(function(r){var n=this.gl,i=`#version 300 es
+ precision highp float;
+
+ uniform mat3 uPanZoomMatrix;
+ uniform int uAtlasSize;
+
+ // instanced
+ in vec2 aPosition;
+
+ // what are we rendering?
+ in int aVertType;
+
+ // for picking
+ in vec4 aIndex;
+
+ // For textures
+ in int aAtlasId; // which shader unit/atlas to use
+ in vec4 aTex1; // x/y/w/h of texture in atlas
+ in vec4 aTex2;
+
+ // for any transforms that are needed
+ in vec4 aScaleRotate1; // vectors use fewer attributes than matrices
+ in vec2 aTranslate1;
+ in vec4 aScaleRotate2;
+ in vec2 aTranslate2;
+
+ // for edges
+ in vec4 aPointAPointB;
+ in vec4 aPointCPointD;
+ in float aLineWidth;
+ in vec4 aEdgeColor;
+
+ out vec2 vTexCoord;
+ out vec4 vEdgeColor;
+ flat out int vAtlasId;
+ flat out vec4 vIndex;
+ flat out int vVertType;
+
+ void main(void) {
+ int vid = gl_VertexID;
+ vec2 position = aPosition;
+
+ if(aVertType == `.concat(MP,`) {
+ float texX;
+ float texY;
+ float texW;
+ float texH;
+ mat3 texMatrix;
+
+ int vid = gl_VertexID;
+ if(vid <= 5) {
+ texX = aTex1.x;
+ texY = aTex1.y;
+ texW = aTex1.z;
+ texH = aTex1.w;
+ texMatrix = mat3(
+ vec3(aScaleRotate1.xy, 0.0),
+ vec3(aScaleRotate2.zw, 0.0),
+ vec3(aTranslate1, 1.0)
+ );
+ } else {
+ texX = aTex2.x;
+ texY = aTex2.y;
+ texW = aTex2.z;
+ texH = aTex2.w;
+ texMatrix = mat3(
+ vec3(aScaleRotate2.xy, 0.0),
+ vec3(aScaleRotate2.zw, 0.0),
+ vec3(aTranslate2, 1.0)
+ );
+ }
+
+ if(vid == 1 || vid == 2 || vid == 4 || vid == 7 || vid == 8 || vid == 10) {
+ texX += texW;
+ }
+ if(vid == 2 || vid == 4 || vid == 5 || vid == 8 || vid == 10 || vid == 11) {
+ texY += texH;
+ }
+
+ float d = float(uAtlasSize);
+ vTexCoord = vec2(texX / d, texY / d); // tex coords must be between 0 and 1
+
+ gl_Position = vec4(uPanZoomMatrix * texMatrix * vec3(position, 1.0), 1.0);
+ }
+ else if(aVertType == `).concat(V0e,` && vid < 6) {
+ vec2 source = aPointAPointB.xy;
+ vec2 target = aPointAPointB.zw;
+
+ // adjust the geometry so that the line is centered on the edge
+ position.y = position.y - 0.5;
+
+ vec2 xBasis = target - source;
+ vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));
+ vec2 point = source + xBasis * position.x + yBasis * aLineWidth * position.y;
+
+ gl_Position = vec4(uPanZoomMatrix * vec3(point, 1.0), 1.0);
+ vEdgeColor = aEdgeColor;
+ }
+ else if(aVertType == `).concat(U0e,` && vid < 6) {
+ vec2 pointA = aPointAPointB.xy;
+ vec2 pointB = aPointAPointB.zw;
+ vec2 pointC = aPointCPointD.xy;
+ vec2 pointD = aPointCPointD.zw;
+
+ // adjust the geometry so that the line is centered on the edge
+ position.y = position.y - 0.5;
+
+ vec2 p0 = pointA;
+ vec2 p1 = pointB;
+ vec2 p2 = pointC;
+ vec2 pos = position;
+ if(position.x == 1.0) {
+ p0 = pointD;
+ p1 = pointC;
+ p2 = pointB;
+ pos = vec2(0.0, -position.y);
+ }
+
+ vec2 p01 = p1 - p0;
+ vec2 p12 = p2 - p1;
+ vec2 p21 = p1 - p2;
+
+ // Find the normal vector.
+ vec2 tangent = normalize(normalize(p12) + normalize(p01));
+ vec2 normal = vec2(-tangent.y, tangent.x);
+
+ // Find the vector perpendicular to p0 -> p1.
+ vec2 p01Norm = normalize(vec2(-p01.y, p01.x));
+
+ // Determine the bend direction.
+ float sigma = sign(dot(p01 + p21, normal));
+ float width = aLineWidth;
+
+ if(sign(pos.y) == -sigma) {
+ // This is an intersecting vertex. Adjust the position so that there's no overlap.
+ vec2 point = 0.5 * width * normal * -sigma / dot(normal, p01Norm);
+ gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0);
+ } else {
+ // This is a non-intersecting vertex. Treat it like a mitre join.
+ vec2 point = 0.5 * width * normal * sigma * dot(normal, p01Norm);
+ gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0);
+ }
+
+ vEdgeColor = aEdgeColor;
+ }
+ else if(aVertType == `).concat(IP,` && vid < 3) {
+ // massage the first triangle into an edge arrow
+ if(vid == 0)
+ position = vec2(-0.15, -0.3);
+ if(vid == 1)
+ position = vec2( 0.0, 0.0);
+ if(vid == 2)
+ position = vec2( 0.15, -0.3);
+
+ mat3 transform = mat3(
+ vec3(aScaleRotate1.xy, 0.0),
+ vec3(aScaleRotate1.zw, 0.0),
+ vec3(aTranslate1, 1.0)
+ );
+ gl_Position = vec4(uPanZoomMatrix * transform * vec3(position, 1.0), 1.0);
+ vEdgeColor = aEdgeColor;
+ } else {
+ gl_Position = vec4(2.0, 0.0, 0.0, 1.0); // discard vertex by putting it outside webgl clip space
+ }
+
+ vAtlasId = aAtlasId;
+ vIndex = aIndex;
+ vVertType = aVertType;
+ }
+ `),a=this.atlasManager.getIndexArray(),s=`#version 300 es
+ precision highp float;
+
+ // define texture unit for each node in the batch
+ `.concat(a.map(function(h){return"uniform sampler2D uTexture".concat(h,";")}).join(`
+ `),`
+
+ uniform vec4 uBGColor;
+
+ in vec2 vTexCoord;
+ in vec4 vEdgeColor;
+ flat in int vAtlasId;
+ flat in vec4 vIndex;
+ flat in int vVertType;
+
+ out vec4 outColor;
+
+ void main(void) {
+ if(vVertType == `).concat(MP,`) {
+ `).concat(a.map(function(h){return"if(vAtlasId == ".concat(h,") outColor = texture(uTexture").concat(h,", vTexCoord);")}).join(`
+ else `),`
+ } else if(vVertType == `).concat(IP,`) {
+ // blend arrow color with background (using premultiplied alpha)
+ outColor.rgb = vEdgeColor.rgb + (uBGColor.rgb * (1.0 - vEdgeColor.a));
+ outColor.a = 1.0; // make opaque, masks out line under arrow
+ } else {
+ outColor = vEdgeColor;
+ }
+
+ `).concat(r.picking?`if(outColor.a == 0.0) discard;
+ else outColor = vIndex;`:"",`
+ }
+ `),l=pZe(n,i,s);l.aPosition=n.getAttribLocation(l,"aPosition"),l.aIndex=n.getAttribLocation(l,"aIndex"),l.aVertType=n.getAttribLocation(l,"aVertType"),l.aAtlasId=n.getAttribLocation(l,"aAtlasId"),l.aTex1=n.getAttribLocation(l,"aTex1"),l.aTex2=n.getAttribLocation(l,"aTex2"),l.aScaleRotate1=n.getAttribLocation(l,"aScaleRotate1"),l.aTranslate1=n.getAttribLocation(l,"aTranslate1"),l.aScaleRotate2=n.getAttribLocation(l,"aScaleRotate2"),l.aTranslate2=n.getAttribLocation(l,"aTranslate2"),l.aPointAPointB=n.getAttribLocation(l,"aPointAPointB"),l.aPointCPointD=n.getAttribLocation(l,"aPointCPointD"),l.aLineWidth=n.getAttribLocation(l,"aLineWidth"),l.aEdgeColor=n.getAttribLocation(l,"aEdgeColor"),l.uPanZoomMatrix=n.getUniformLocation(l,"uPanZoomMatrix"),l.uAtlasSize=n.getUniformLocation(l,"uAtlasSize"),l.uBGColor=n.getUniformLocation(l,"uBGColor"),l.uTextures=[];for(var u=0;u<this.atlasManager.maxAtlases;u++)l.uTextures.push(n.getUniformLocation(l,"uTexture".concat(u)));return l},"createShaderProgram")},{key:"createVAO",value:o(function(){var r=[0,0,1,0,1,1,0,0,1,1,0,1],n=[].concat(r,r);this.vertexCount=n.length/2;var i=this.maxInstances,a=this.gl,s=this.program,l=a.createVertexArray();return a.bindVertexArray(l),xZe(a,"vec2",s.aPosition,n),this.indexBuffer=po(a,i,"vec4",s.aIndex),this.vertTypeBuffer=po(a,i,"int",s.aVertType),this.atlasIdBuffer=po(a,i,"int",s.aAtlasId),this.tex1Buffer=po(a,i,"vec4",s.aTex1),this.tex2Buffer=po(a,i,"vec4",s.aTex2),this.scaleRotate1Buffer=po(a,i,"vec4",s.aScaleRotate1),this.translate1Buffer=po(a,i,"vec2",s.aTranslate1),this.scaleRotate2Buffer=po(a,i,"vec4",s.aScaleRotate2),this.translate2Buffer=po(a,i,"vec2",s.aTranslate2),this.pointAPointBBuffer=po(a,i,"vec4",s.aPointAPointB),this.pointCPointDBuffer=po(a,i,"vec4",s.aPointCPointD),this.lineWidthBuffer=po(a,i,"float",s.aLineWidth),this.edgeColorBuffer=po(a,i,"vec4",s.aEdgeColor),a.bindVertexArray(null),l},"createVAO")},{key:"buffers",get:o(function(){var r=this;return this._buffers||(this._buffers=Object.keys(this).filter(function(n){return n.endsWith("Buffer")}).map(function(n){return r[n]})),this._buffers},"get")},{key:"startFrame",value:o(function(r,n){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Vb.SCREEN;this.panZoomMatrix=r,this.debugInfo=n,this.renderTarget=i,this.startBatch()},"startFrame")},{key:"startBatch",value:o(function(){this.instanceCount=0,this.atlasManager.startBatch()},"startBatch")},{key:"endFrame",value:o(function(){this.endBatch()},"endFrame")},{key:"getTempMatrix",value:o(function(){return this.tempMatrix=this.tempMatrix||Gb()},"getTempMatrix")},{key:"drawTexture",value:o(function(r,n,i){var a=this.atlasManager;if(a.isRenderable(r,i)){a.canAddToCurrentBatch(r,i)||this.endBatch();var s=this.instanceCount;this.vertTypeBuffer.getView(s)[0]=MP;var l=this.indexBuffer.getView(s);lS(n,l);var u=a.getAtlasInfo(r,i,u),h=u.atlasID,f=u.tex1,d=u.tex2,p=this.atlasIdBuffer.getView(s);p[0]=h;var m=this.tex1Buffer.getView(s);m[0]=f.x,m[1]=f.y,m[2]=f.w,m[3]=f.h;var g=this.tex2Buffer.getView(s);g[0]=d.x,g[1]=d.y,g[2]=d.w,g[3]=d.h;for(var y=this.getTempMatrix(),v=0,x=[1,2];v<x.length;v++){var b=x[v];a.setTransformMatrix(y,u,r,b===1);var w=this["scaleRotate".concat(b,"Buffer")].getView(s);w[0]=y[0],w[1]=y[1],w[2]=y[3],w[3]=y[4];var C=this["translate".concat(b,"Buffer")].getView(s);C[0]=y[6],C[1]=y[7]}this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}},"drawTexture")},{key:"drawEdgeArrow",value:o(function(r,n,i){var a=r._private.rscratch,s,l,u;if(i==="source"?(s=a.arrowStartX,l=a.arrowStartY,u=a.srcArrowAngle):(s=a.arrowEndX,l=a.arrowEndY,u=a.tgtArrowAngle),!(isNaN(s)||s==null||isNaN(l)||l==null||isNaN(u)||u==null)){var h=r.pstyle(i+"-arrow-shape").value;if(h!=="none"){var f=r.pstyle(i+"-arrow-color").value,d=r.pstyle("opacity").value,p=r.pstyle("line-opacity").value,m=d*p,g=r.pstyle("width").pfValue,y=r.pstyle("arrow-scale").value,v=this.r.getArrowWidth(g,y),x=this.getTempMatrix();Age(x),DS(x,x,[s,l]),TB(x,x,[v,v]),_ge(x,x,u);var b=this.instanceCount;this.vertTypeBuffer.getView(b)[0]=IP;var w=this.indexBuffer.getView(b);lS(n,w);var C=this.edgeColorBuffer.getView(b);oS(f,m,C);var T=this.scaleRotate1Buffer.getView(b);T[0]=x[0],T[1]=x[1],T[2]=x[3],T[3]=x[4];var E=this.translate1Buffer.getView(b);E[0]=x[6],E[1]=x[7],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}},"drawEdgeArrow")},{key:"drawEdgeLine",value:o(function(r,n){var i=r.pstyle("opacity").value,a=r.pstyle("line-opacity").value,s=r.pstyle("width").pfValue,l=r.pstyle("line-color").value,u=i*a,h=this.getEdgePoints(r);if(h.length/2+this.instanceCount>this.maxInstances&&this.endBatch(),h.length==4){var f=this.instanceCount;this.vertTypeBuffer.getView(f)[0]=V0e;var d=this.indexBuffer.getView(f);lS(n,d);var p=this.edgeColorBuffer.getView(f);oS(l,u,p);var m=this.lineWidthBuffer.getView(f);m[0]=s;var g=this.pointAPointBBuffer.getView(f);g[0]=h[0],g[1]=h[1],g[2]=h[2],g[3]=h[3],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}else for(var y=0;y<h.length-2;y+=2){var v=this.instanceCount;this.vertTypeBuffer.getView(v)[0]=U0e;var x=this.indexBuffer.getView(v);lS(n,x);var b=this.edgeColorBuffer.getView(v);oS(l,u,b);var w=this.lineWidthBuffer.getView(v);w[0]=s;var C=h[y-2],T=h[y-1],E=h[y],A=h[y+1],S=h[y+2],_=h[y+3],I=h[y+4],D=h[y+5];y==0&&(C=2*E-S+.001,T=2*A-_+.001),y==h.length-4&&(I=2*S-E+.001,D=2*_-A+.001);var k=this.pointAPointBBuffer.getView(v);k[0]=C,k[1]=T,k[2]=E,k[3]=A;var L=this.pointCPointDBuffer.getView(v);L[0]=S,L[1]=_,L[2]=I,L[3]=D,this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}},"drawEdgeLine")},{key:"getEdgePoints",value:o(function(r){var n=r._private.rscratch,i=n.allpts;if(i.length==4)return i;var a=this.getNumSegments(r);return this.getCurveSegmentPoints(i,a)},"getEdgePoints")},{key:"getNumSegments",value:o(function(r){var n=15;return Math.min(Math.max(n,5),this.maxInstances)},"getNumSegments")},{key:"getCurveSegmentPoints",value:o(function(r,n){if(r.length==4)return r;for(var i=Array((n+1)*2),a=0;a<=n;a++)if(a==0)i[0]=r[0],i[1]=r[1];else if(a==n)i[a*2]=r[r.length-2],i[a*2+1]=r[r.length-1];else{var s=a/n;this.setCurvePoint(r,s,i,a*2)}return i},"getCurveSegmentPoints")},{key:"setCurvePoint",value:o(function(r,n,i,a){if(r.length<=2)i[a]=r[0],i[a+1]=r[1];else{for(var s=Array(r.length-2),l=0;l<s.length;l+=2){var u=(1-n)*r[l]+n*r[l+2],h=(1-n)*r[l+1]+n*r[l+3];s[l]=u,s[l+1]=h}return this.setCurvePoint(s,n,i,a)}},"setCurvePoint")},{key:"endBatch",value:o(function(){var r=this.gl,n=this.vao,i=this.vertexCount,a=this.instanceCount;if(a!==0){var s=this.renderTarget.picking?this.pickingProgram:this.program;r.useProgram(s),r.bindVertexArray(n);var l=mo(this.buffers),u;try{for(l.s();!(u=l.n()).done;){var h=u.value;h.bufferSubData(a)}}catch(g){l.e(g)}finally{l.f()}for(var f=this.atlasManager.getAtlases(),d=0;d<f.length;d++)f[d].bufferIfNeeded(r);for(var p=0;p<f.length;p++)r.activeTexture(r.TEXTURE0+p),r.bindTexture(r.TEXTURE_2D,f[p].texture),r.uniform1i(s.uTextures[p],p);r.uniformMatrix3fv(s.uPanZoomMatrix,!1,this.panZoomMatrix),r.uniform1i(s.uAtlasSize,this.atlasManager.atlasSize);var m=oS(this.bgColor,1);r.uniform4fv(s.uBGColor,m),r.drawArraysInstanced(r.TRIANGLES,0,i,a),r.bindVertexArray(null),r.bindTexture(r.TEXTURE_2D,null),this.debugInfo&&this.debugInfo.push({count:a,atlasCount:f.length}),this.startBatch()}},"endBatch")},{key:"getDebugInfo",value:o(function(){return this.debugInfo},"getDebugInfo")},{key:"getAtlasDebugInfo",value:o(function(){return this.atlasManager.getDebugInfo()},"getAtlasDebugInfo")}]),t}();o(H0e,"fillStyle");_Ze=function(){function t(e){Mf(this,t),this.r=e}return o(t,"OverlayUnderlayRenderer"),If(t,[{key:"getStyleKey",value:o(function(r,n){var i=this.getStyle(r,n),a=i.shape,s=i.opacity,l=i.color;if(!a)return null;var u=n.width(),h=n.height(),f=H0e(l,s);return _f("".concat(a,"-").concat(u,"-").concat(h,"-").concat(f))},"getStyleKey")},{key:"isVisible",value:o(function(r,n){var i=n.pstyle("".concat(r,"-opacity")).value;return i>0},"isVisible")},{key:"getStyle",value:o(function(r,n){var i=n.pstyle("".concat(r,"-opacity")).value,a=n.pstyle("".concat(r,"-color")).value,s=n.pstyle("".concat(r,"-shape")).value;return{opacity:i,color:a,shape:s}},"getStyle")},{key:"getPadding",value:o(function(r,n){return n.pstyle("".concat(r,"-padding")).pfValue},"getPadding")},{key:"draw",value:o(function(r,n,i,a){if(this.isVisible(r,i)){var s=this.r,l=a.w,u=a.h,h=l/2,f=u/2,d=this.getStyle(r,i),p=d.shape,m=d.color,g=d.opacity;n.save(),n.fillStyle=H0e(m,g),p==="round-rectangle"||p==="roundrectangle"?s.drawRoundRectanglePath(n,h,f,l,u,"auto"):p==="ellipse"&&s.drawEllipsePath(n,h,f,l,u),n.fill(),n.restore()}},"draw")}]),t}();o(DZe,"getBGColor");Dge={};Dge.initWebgl=function(t,e){var r=this,n=r.data.contexts[r.WEBGL],i=t.cy.container();t.bgColor=DZe(i),t.webglTexSize=Math.min(t.webglTexSize,n.getParameter(n.MAX_TEXTURE_SIZE)),t.webglTexRows=Math.min(t.webglTexRows,54),t.webglBatchSize=Math.min(t.webglBatchSize,16384),t.webglTexPerBatch=Math.min(t.webglTexPerBatch,n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),r.webglDebug=t.webglDebug,r.webglDebugShowAtlases=t.webglDebugShowAtlases,console.log("max texture units",n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)),console.log("max texture size",n.getParameter(n.MAX_TEXTURE_SIZE)),console.log("webgl options",t),r.pickingFrameBuffer=bZe(n),r.pickingFrameBuffer.needsDraw=!0;var a=o(function(f){return r.getTextAngle(f,null)},"getLabelRotation"),s=o(function(f){var d=f.pstyle("label");return d&&d.value},"isLabelVisible");r.eleDrawing=new AZe(r,n,t);var l=new _Ze(r);r.eleDrawing.addTextureRenderType("node-body",Mb({getKey:e.getStyleKey,getBoundingBox:e.getElementBox,drawElement:e.drawElement,isVisible:o(function(f){return f.visible()},"isVisible")})),r.eleDrawing.addTextureRenderType("node-label",Mb({getKey:e.getLabelKey,getBoundingBox:e.getLabelBox,drawElement:e.drawLabel,getRotation:a,getRotationPoint:e.getLabelRotationPoint,getRotationOffset:e.getLabelRotationOffset,isVisible:s})),r.eleDrawing.addTextureRenderType("node-overlay",Mb({getBoundingBox:e.getElementBox,getKey:o(function(f){return l.getStyleKey("overlay",f)},"getKey"),drawElement:o(function(f,d,p){return l.draw("overlay",f,d,p)},"drawElement"),isVisible:o(function(f){return l.isVisible("overlay",f)},"isVisible"),getPadding:o(function(f){return l.getPadding("overlay",f)},"getPadding")})),r.eleDrawing.addTextureRenderType("node-underlay",Mb({getBoundingBox:e.getElementBox,getKey:o(function(f){return l.getStyleKey("underlay",f)},"getKey"),drawElement:o(function(f,d,p){return l.draw("underlay",f,d,p)},"drawElement"),isVisible:o(function(f){return l.isVisible("underlay",f)},"isVisible"),getPadding:o(function(f){return l.getPadding("underlay",f)},"getPadding")})),r.eleDrawing.addTextureRenderType("edge-label",Mb({getKey:e.getLabelKey,getBoundingBox:e.getLabelBox,drawElement:e.drawLabel,getRotation:a,getRotationPoint:e.getLabelRotationPoint,getRotationOffset:e.getLabelRotationOffset,isVisible:s}));var u=n4(function(){console.log("garbage collect flag set"),r.data.gc=!0},1e4);r.onUpdateEleCalcs(function(h,f){var d=!1;f&&f.length>0&&(d|=r.eleDrawing.invalidate(f)),d&&u()}),LZe(r)};o(LZe,"overrideCanvasRendererFunctions");o(RZe,"clearWebgl");o(NZe,"clearCanvas");o(MZe,"createPanZoomMatrix");o(Lge,"setContextTransform");o(IZe,"drawSelectionRectangle");o(OZe,"drawAxes");o(PZe,"drawAtlases");o(BZe,"getPickingIndexes");o(FZe,"findNearestElementsWebgl");o(Rge,"renderWebgl");Pf={};Pf.drawPolygonPath=function(t,e,r,n,i,a){var s=n/2,l=i/2;t.beginPath&&t.beginPath(),t.moveTo(e+s*a[0],r+l*a[1]);for(var u=1;u<a.length/2;u++)t.lineTo(e+s*a[u*2],r+l*a[u*2+1]);t.closePath()};Pf.drawRoundPolygonPath=function(t,e,r,n,i,a,s){s.forEach(function(l){return hge(t,l)}),t.closePath()};Pf.drawRoundRectanglePath=function(t,e,r,n,i,a){var s=n/2,l=i/2,u=a==="auto"?Vp(n,i):Math.min(a,l,s);t.beginPath&&t.beginPath(),t.moveTo(e,r-l),t.arcTo(e+s,r-l,e+s,r,u),t.arcTo(e+s,r+l,e,r+l,u),t.arcTo(e-s,r+l,e-s,r,u),t.arcTo(e-s,r-l,e,r-l,u),t.lineTo(e,r-l),t.closePath()};Pf.drawBottomRoundRectanglePath=function(t,e,r,n,i,a){var s=n/2,l=i/2,u=a==="auto"?Vp(n,i):a;t.beginPath&&t.beginPath(),t.moveTo(e,r-l),t.lineTo(e+s,r-l),t.lineTo(e+s,r),t.arcTo(e+s,r+l,e,r+l,u),t.arcTo(e-s,r+l,e-s,r,u),t.lineTo(e-s,r-l),t.lineTo(e,r-l),t.closePath()};Pf.drawCutRectanglePath=function(t,e,r,n,i,a,s){var l=n/2,u=i/2,h=s==="auto"?sB():s;t.beginPath&&t.beginPath(),t.moveTo(e-l+h,r-u),t.lineTo(e+l-h,r-u),t.lineTo(e+l,r-u+h),t.lineTo(e+l,r+u-h),t.lineTo(e+l-h,r+u),t.lineTo(e-l+h,r+u),t.lineTo(e-l,r+u-h),t.lineTo(e-l,r-u+h),t.closePath()};Pf.drawBarrelPath=function(t,e,r,n,i){var a=n/2,s=i/2,l=e-a,u=e+a,h=r-s,f=r+s,d=BP(n,i),p=d.widthOffset,m=d.heightOffset,g=d.ctrlPtOffsetPct*p;t.beginPath&&t.beginPath(),t.moveTo(l,h+m),t.lineTo(l,f-m),t.quadraticCurveTo(l+g,f,l+p,f),t.lineTo(u-p,f),t.quadraticCurveTo(u-g,f,u,f-m),t.lineTo(u,h+m),t.quadraticCurveTo(u-g,h,u-p,h),t.lineTo(l+p,h),t.quadraticCurveTo(l+g,h,l,h+m),t.closePath()};W0e=Math.sin(0),q0e=Math.cos(0),jP={},KP={},Nge=Math.PI/40;for(Ip=0*Math.PI;Ip<2*Math.PI;Ip+=Nge)jP[Ip]=Math.sin(Ip),KP[Ip]=Math.cos(Ip);Pf.drawEllipsePath=function(t,e,r,n,i){if(t.beginPath&&t.beginPath(),t.ellipse)t.ellipse(e,r,n/2,i/2,0,0,2*Math.PI);else for(var a,s,l=n/2,u=i/2,h=0*Math.PI;h<2*Math.PI;h+=Nge)a=e-l*jP[h]*W0e+l*KP[h]*q0e,s=r+u*KP[h]*W0e+u*jP[h]*q0e,h===0?t.moveTo(a,s):t.lineTo(a,s);t.closePath()};c4={};c4.createBuffer=function(t,e){var r=document.createElement("canvas");return r.width=t,r.height=e,[r,r.getContext("2d")]};c4.bufferCanvasImage=function(t){var e=this.cy,r=e.mutableElements(),n=r.boundingBox(),i=this.findContainerClientCoords(),a=t.full?Math.ceil(n.w):i[2],s=t.full?Math.ceil(n.h):i[3],l=Ct(t.maxWidth)||Ct(t.maxHeight),u=this.getPixelRatio(),h=1;if(t.scale!==void 0)a*=t.scale,s*=t.scale,h=t.scale;else if(l){var f=1/0,d=1/0;Ct(t.maxWidth)&&(f=h*t.maxWidth/a),Ct(t.maxHeight)&&(d=h*t.maxHeight/s),h=Math.min(f,d),a*=h,s*=h}l||(a*=u,s*=u,h*=u);var p=document.createElement("canvas");p.width=a,p.height=s,p.style.width=a+"px",p.style.height=s+"px";var m=p.getContext("2d");if(a>0&&s>0){m.clearRect(0,0,a,s),m.globalCompositeOperation="source-over";var g=this.getCachedZSortedEles();if(t.full)m.translate(-n.x1*h,-n.y1*h),m.scale(h,h),this.drawElements(m,g),m.scale(1/h,1/h),m.translate(n.x1*h,n.y1*h);else{var y=e.pan(),v={x:y.x*h,y:y.y*h};h*=e.zoom(),m.translate(v.x,v.y),m.scale(h,h),this.drawElements(m,g),m.scale(1/h,1/h),m.translate(-v.x,-v.y)}t.bg&&(m.globalCompositeOperation="destination-over",m.fillStyle=t.bg,m.rect(0,0,a,s),m.fill())}return p};o($Ze,"b64ToBlob");o(Y0e,"b64UriToB64");o(Mge,"output");c4.png=function(t){return Mge(t,this.bufferCanvasImage(t),"image/png")};c4.jpg=function(t){return Mge(t,this.bufferCanvasImage(t),"image/jpeg")};Ige={};Ige.nodeShapeImpl=function(t,e,r,n,i,a,s,l){switch(t){case"ellipse":return this.drawEllipsePath(e,r,n,i,a);case"polygon":return this.drawPolygonPath(e,r,n,i,a,s);case"round-polygon":return this.drawRoundPolygonPath(e,r,n,i,a,s,l);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(e,r,n,i,a,l);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(e,r,n,i,a,s,l);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(e,r,n,i,a,l);case"barrel":return this.drawBarrelPath(e,r,n,i,a)}};zZe=Oge,Er=Oge.prototype;Er.CANVAS_LAYERS=3;Er.SELECT_BOX=0;Er.DRAG=1;Er.NODE=2;Er.WEBGL=3;Er.CANVAS_TYPES=["2d","2d","2d","webgl2"];Er.BUFFER_COUNT=3;Er.TEXTURE_BUFFER=0;Er.MOTIONBLUR_BUFFER_NODE=1;Er.MOTIONBLUR_BUFFER_DRAG=2;o(Oge,"CanvasRenderer");Er.redrawHint=function(t,e){var r=this;switch(t){case"eles":r.data.canvasNeedsRedraw[Er.NODE]=e;break;case"drag":r.data.canvasNeedsRedraw[Er.DRAG]=e;break;case"select":r.data.canvasNeedsRedraw[Er.SELECT_BOX]=e;break;case"gc":r.data.gc=!0;break}};GZe=typeof Path2D<"u";Er.path2dEnabled=function(t){if(t===void 0)return this.pathsEnabled;this.pathsEnabled=!!t};Er.usePaths=function(){return GZe&&this.pathsEnabled};Er.setImgSmoothing=function(t,e){t.imageSmoothingEnabled!=null?t.imageSmoothingEnabled=e:(t.webkitImageSmoothingEnabled=e,t.mozImageSmoothingEnabled=e,t.msImageSmoothingEnabled=e)};Er.getImgSmoothing=function(t){return t.imageSmoothingEnabled!=null?t.imageSmoothingEnabled:t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled};Er.makeOffscreenCanvas=function(t,e){var r;if((typeof OffscreenCanvas>"u"?"undefined":Wi(OffscreenCanvas))!=="undefined")r=new OffscreenCanvas(t,e);else{var n=this.cy.window(),i=n.document;r=i.createElement("canvas"),r.width=t,r.height=e}return r};[Tge,Qc,th,bB,Yp,ly,ys,Dge,Pf,c4,Ige].forEach(function(t){rr(Er,t)});VZe=[{name:"null",impl:lge},{name:"base",impl:vge},{name:"canvas",impl:zZe}],UZe=[{type:"layout",extensions:SQe},{type:"renderer",extensions:VZe}],Pge={},Bge={};o(Fge,"setExtension");o($ge,"getExtension");o(HZe,"setModule");o(WZe,"getModule");QP=o(function(){if(arguments.length===2)return $ge.apply(null,arguments);if(arguments.length===3)return Fge.apply(null,arguments);if(arguments.length===4)return WZe.apply(null,arguments);if(arguments.length===5)return HZe.apply(null,arguments);ai("Invalid extension access syntax")},"extension");Jb.prototype.extension=QP;UZe.forEach(function(t){t.extensions.forEach(function(e){Fge(t.type,e.name,e.impl)})});zge=o(function t(){if(!(this instanceof t))return new t;this.length=0},"Stylesheet"),Wp=zge.prototype;Wp.instanceString=function(){return"stylesheet"};Wp.selector=function(t){var e=this.length++;return this[e]={selector:t,properties:[]},this};Wp.css=function(t,e){var r=this.length-1;if(Zt(t))this[r].properties.push({name:t,value:e});else if(Ur(t))for(var n=t,i=Object.keys(n),a=0;a<i.length;a++){var s=i[a],l=n[s];if(l!=null){var u=Fa.properties[s]||Fa.properties[LS(s)];if(u!=null){var h=u.name,f=l;this[r].properties.push({name:h,value:f})}}}return this};Wp.style=Wp.css;Wp.generateStyle=function(t){var e=new Fa(t);return this.appendToStyle(e)};Wp.appendToStyle=function(t){for(var e=0;e<this.length;e++){var r=this[e],n=r.selector,i=r.properties;t.selector(n);for(var a=0;a<i.length;a++){var s=i[a];t.css(s.name,s.value)}}return t};qZe="3.31.0",rl=o(function(e){if(e===void 0&&(e={}),Ur(e))return new Jb(e);if(Zt(e))return QP.apply(QP,arguments)},"cytoscape");rl.use=function(t){var e=Array.prototype.slice.call(arguments,1);return e.unshift(rl),t.apply(null,e),this};rl.warnings=function(t){return hme(t)};rl.version=qZe;rl.stylesheet=rl.Stylesheet=zge});var SB=Mi((u4,EB)=>{"use strict";o(function(e,r){typeof u4=="object"&&typeof EB=="object"?EB.exports=r():typeof define=="function"&&define.amd?define([],r):typeof u4=="object"?u4.layoutBase=r():e.layoutBase=r()},"webpackUniversalModuleDefinition")(u4,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return o(r,"__webpack_require__"),r.m=t,r.c=e,r.i=function(n){return n},r.d=function(n,i,a){r.o(n,i)||Object.defineProperty(n,i,{configurable:!1,enumerable:!0,get:a})},r.n=function(n){var i=n&&n.__esModule?o(function(){return n.default},"getDefault"):o(function(){return n},"getModuleExports");return r.d(i,"a",i),i},r.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},r.p="",r(r.s=26)}([function(t,e,r){"use strict";function n(){}o(n,"LayoutConstants"),n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(8),a=r(9);function s(u,h,f){n.call(this,f),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=f,this.bendpoints=[],this.source=u,this.target=h}o(s,"LEdge"),s.prototype=Object.create(n.prototype);for(var l in n)s[l]=n[l];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(u){if(this.source===u)return this.target;if(this.target===u)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(u,h){for(var f=this.getOtherEnd(u),d=h.getGraphManager().getRoot();;){if(f.getOwner()==h)return f;if(f.getOwner()==d)break;f=f.getOwner().getParent()}return null},s.prototype.updateLength=function(){var u=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),u),this.isOverlapingSourceAndTarget||(this.lengthX=u[0]-u[2],this.lengthY=u[1]-u[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,r){"use strict";function n(i){this.vGraphObject=i}o(n,"LGraphObject"),t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(13),s=r(0),l=r(16),u=r(4);function h(d,p,m,g){m==null&&g==null&&(g=p),n.call(this,g),d.graphManager!=null&&(d=d.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=g,this.edges=[],this.graphManager=d,m!=null&&p!=null?this.rect=new a(p.x,p.y,m.width,m.height):this.rect=new a}o(h,"LNode"),h.prototype=Object.create(n.prototype);for(var f in n)h[f]=n[f];h.prototype.getEdges=function(){return this.edges},h.prototype.getChild=function(){return this.child},h.prototype.getOwner=function(){return this.owner},h.prototype.getWidth=function(){return this.rect.width},h.prototype.setWidth=function(d){this.rect.width=d},h.prototype.getHeight=function(){return this.rect.height},h.prototype.setHeight=function(d){this.rect.height=d},h.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},h.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},h.prototype.getCenter=function(){return new u(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},h.prototype.getLocation=function(){return new u(this.rect.x,this.rect.y)},h.prototype.getRect=function(){return this.rect},h.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},h.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},h.prototype.setRect=function(d,p){this.rect.x=d.x,this.rect.y=d.y,this.rect.width=p.width,this.rect.height=p.height},h.prototype.setCenter=function(d,p){this.rect.x=d-this.rect.width/2,this.rect.y=p-this.rect.height/2},h.prototype.setLocation=function(d,p){this.rect.x=d,this.rect.y=p},h.prototype.moveBy=function(d,p){this.rect.x+=d,this.rect.y+=p},h.prototype.getEdgeListToNode=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(y.target==d){if(y.source!=g)throw"Incorrect edge source!";p.push(y)}}),p},h.prototype.getEdgesBetween=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(!(y.source==g||y.target==g))throw"Incorrect edge source and/or target";(y.target==d||y.source==d)&&p.push(y)}),p},h.prototype.getNeighborsList=function(){var d=new Set,p=this;return p.edges.forEach(function(m){if(m.source==p)d.add(m.target);else{if(m.target!=p)throw"Incorrect incidency!";d.add(m.source)}}),d},h.prototype.withChildren=function(){var d=new Set,p,m;if(d.add(this),this.child!=null)for(var g=this.child.getNodes(),y=0;y<g.length;y++)p=g[y],m=p.withChildren(),m.forEach(function(v){d.add(v)});return d},h.prototype.getNoOfChildren=function(){var d=0,p;if(this.child==null)d=1;else for(var m=this.child.getNodes(),g=0;g<m.length;g++)p=m[g],d+=p.getNoOfChildren();return d==0&&(d=1),d},h.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},h.prototype.calcEstimatedSize=function(){return this.child==null?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},h.prototype.scatter=function(){var d,p,m=-s.INITIAL_WORLD_BOUNDARY,g=s.INITIAL_WORLD_BOUNDARY;d=s.WORLD_CENTER_X+l.nextDouble()*(g-m)+m;var y=-s.INITIAL_WORLD_BOUNDARY,v=s.INITIAL_WORLD_BOUNDARY;p=s.WORLD_CENTER_Y+l.nextDouble()*(v-y)+y,this.rect.x=d,this.rect.y=p},h.prototype.updateBounds=function(){if(this.getChild()==null)throw"assert failed";if(this.getChild().getNodes().length!=0){var d=this.getChild();if(d.updateBounds(!0),this.rect.x=d.getLeft(),this.rect.y=d.getTop(),this.setWidth(d.getRight()-d.getLeft()),this.setHeight(d.getBottom()-d.getTop()),s.NODE_DIMENSIONS_INCLUDE_LABELS){var p=d.getRight()-d.getLeft(),m=d.getBottom()-d.getTop();this.labelWidth>p&&(this.rect.x-=(this.labelWidth-p)/2,this.setWidth(this.labelWidth)),this.labelHeight>m&&(this.labelPos=="center"?this.rect.y-=(this.labelHeight-m)/2:this.labelPos=="top"&&(this.rect.y-=this.labelHeight-m),this.setHeight(this.labelHeight))}}},h.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},h.prototype.transform=function(d){var p=this.rect.x;p>s.WORLD_BOUNDARY?p=s.WORLD_BOUNDARY:p<-s.WORLD_BOUNDARY&&(p=-s.WORLD_BOUNDARY);var m=this.rect.y;m>s.WORLD_BOUNDARY?m=s.WORLD_BOUNDARY:m<-s.WORLD_BOUNDARY&&(m=-s.WORLD_BOUNDARY);var g=new u(p,m),y=d.inverseTransformPoint(g);this.setLocation(y.x,y.y)},h.prototype.getLeft=function(){return this.rect.x},h.prototype.getRight=function(){return this.rect.x+this.rect.width},h.prototype.getTop=function(){return this.rect.y},h.prototype.getBottom=function(){return this.rect.y+this.rect.height},h.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},t.exports=h},function(t,e,r){"use strict";function n(i,a){i==null&&a==null?(this.x=0,this.y=0):(this.x=i,this.y=a)}o(n,"PointD"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(i){this.x=i},n.prototype.setY=function(i){this.y=i},n.prototype.getDifference=function(i){return new DimensionD(this.x-i.x,this.y-i.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(i){return this.x+=i.width,this.y+=i.height,this},t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(0),s=r(6),l=r(3),u=r(1),h=r(13),f=r(12),d=r(11);function p(g,y,v){n.call(this,v),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=g,y!=null&&y instanceof s?this.graphManager=y:y!=null&&y instanceof Layout&&(this.graphManager=y.graphManager)}o(p,"LGraph"),p.prototype=Object.create(n.prototype);for(var m in n)p[m]=n[m];p.prototype.getNodes=function(){return this.nodes},p.prototype.getEdges=function(){return this.edges},p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getParent=function(){return this.parent},p.prototype.getLeft=function(){return this.left},p.prototype.getRight=function(){return this.right},p.prototype.getTop=function(){return this.top},p.prototype.getBottom=function(){return this.bottom},p.prototype.isConnected=function(){return this.isConnected},p.prototype.add=function(g,y,v){if(y==null&&v==null){var x=g;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(x)>-1)throw"Node already in graph!";return x.owner=this,this.getNodes().push(x),x}else{var b=g;if(!(this.getNodes().indexOf(y)>-1&&this.getNodes().indexOf(v)>-1))throw"Source or target not in graph!";if(!(y.owner==v.owner&&y.owner==this))throw"Both owners must be this graph!";return y.owner!=v.owner?null:(b.source=y,b.target=v,b.isInterGraph=!1,this.getEdges().push(b),y.edges.push(b),v!=y&&v.edges.push(b),b)}},p.prototype.remove=function(g){var y=g;if(g instanceof l){if(y==null)throw"Node is null!";if(!(y.owner!=null&&y.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var v=y.edges.slice(),x,b=v.length,w=0;w<b;w++)x=v[w],x.isInterGraph?this.graphManager.remove(x):x.source.owner.remove(x);var C=this.nodes.indexOf(y);if(C==-1)throw"Node not in owner node list!";this.nodes.splice(C,1)}else if(g instanceof u){var x=g;if(x==null)throw"Edge is null!";if(!(x.source!=null&&x.target!=null))throw"Source and/or target is null!";if(!(x.source.owner!=null&&x.target.owner!=null&&x.source.owner==this&&x.target.owner==this))throw"Source and/or target owner is invalid!";var T=x.source.edges.indexOf(x),E=x.target.edges.indexOf(x);if(!(T>-1&&E>-1))throw"Source and/or target doesn't know this edge!";x.source.edges.splice(T,1),x.target!=x.source&&x.target.edges.splice(E,1);var C=x.source.owner.getEdges().indexOf(x);if(C==-1)throw"Not in owner's edge list!";x.source.owner.getEdges().splice(C,1)}},p.prototype.updateLeftTop=function(){for(var g=i.MAX_VALUE,y=i.MAX_VALUE,v,x,b,w=this.getNodes(),C=w.length,T=0;T<C;T++){var E=w[T];v=E.getTop(),x=E.getLeft(),g>v&&(g=v),y>x&&(y=x)}return g==i.MAX_VALUE?null:(w[0].getParent().paddingLeft!=null?b=w[0].getParent().paddingLeft:b=this.margin,this.left=y-b,this.top=g-b,new f(this.left,this.top))},p.prototype.updateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,w,C,T,E,A,S=this.nodes,_=S.length,I=0;I<_;I++){var D=S[I];g&&D.child!=null&&D.updateBounds(),w=D.getLeft(),C=D.getRight(),T=D.getTop(),E=D.getBottom(),y>w&&(y=w),v<C&&(v=C),x>T&&(x=T),b<E&&(b=E)}var k=new h(y,x,v-y,b-x);y==i.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),S[0].getParent().paddingLeft!=null?A=S[0].getParent().paddingLeft:A=this.margin,this.left=k.x-A,this.right=k.x+k.width+A,this.top=k.y-A,this.bottom=k.y+k.height+A},p.calculateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,w,C,T,E,A=g.length,S=0;S<A;S++){var _=g[S];w=_.getLeft(),C=_.getRight(),T=_.getTop(),E=_.getBottom(),y>w&&(y=w),v<C&&(v=C),x>T&&(x=T),b<E&&(b=E)}var I=new h(y,x,v-y,b-x);return I},p.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},p.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},p.prototype.calcEstimatedSize=function(){for(var g=0,y=this.nodes,v=y.length,x=0;x<v;x++){var b=y[x];g+=b.calcEstimatedSize()}return g==0?this.estimatedSize=a.EMPTY_COMPOUND_NODE_SIZE:this.estimatedSize=g/Math.sqrt(this.nodes.length),this.estimatedSize},p.prototype.updateConnected=function(){var g=this;if(this.nodes.length==0){this.isConnected=!0;return}var y=new d,v=new Set,x=this.nodes[0],b,w,C=x.withChildren();for(C.forEach(function(I){y.push(I),v.add(I)});y.length!==0;){x=y.shift(),b=x.getEdges();for(var T=b.length,E=0;E<T;E++){var A=b[E];if(w=A.getOtherEndInGraph(x,this),w!=null&&!v.has(w)){var S=w.withChildren();S.forEach(function(I){y.push(I),v.add(I)})}}}if(this.isConnected=!1,v.size>=this.nodes.length){var _=0;v.forEach(function(I){I.owner==g&&_++}),_==this.nodes.length&&(this.isConnected=!0)}},t.exports=p},function(t,e,r){"use strict";var n,i=r(1);function a(s){n=r(5),this.layout=s,this.graphs=[],this.edges=[]}o(a,"LGraphManager"),a.prototype.addRoot=function(){var s=this.layout.newGraph(),l=this.layout.newNode(null),u=this.add(s,l);return this.setRootGraph(u),this.rootGraph},a.prototype.add=function(s,l,u,h,f){if(u==null&&h==null&&f==null){if(s==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(s)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(s),s.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return s.parent=l,l.child=s,s}else{f=u,h=l,u=s;var d=h.getOwner(),p=f.getOwner();if(!(d!=null&&d.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(p!=null&&p.getGraphManager()==this))throw"Target not in this graph mgr!";if(d==p)return u.isInterGraph=!1,d.add(u,h,f);if(u.isInterGraph=!0,u.source=h,u.target=f,this.edges.indexOf(u)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(u),!(u.source!=null&&u.target!=null))throw"Edge source and/or target is null!";if(!(u.source.edges.indexOf(u)==-1&&u.target.edges.indexOf(u)==-1))throw"Edge already in source and/or target incidency list!";return u.source.edges.push(u),u.target.edges.push(u),u}},a.prototype.remove=function(s){if(s instanceof n){var l=s;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var u=[];u=u.concat(l.getEdges());for(var h,f=u.length,d=0;d<f;d++)h=u[d],l.remove(h);var p=[];p=p.concat(l.getNodes());var m;f=p.length;for(var d=0;d<f;d++)m=p[d],l.remove(m);l==this.rootGraph&&this.setRootGraph(null);var g=this.graphs.indexOf(l);this.graphs.splice(g,1),l.parent=null}else if(s instanceof i){if(h=s,h==null)throw"Edge is null!";if(!h.isInterGraph)throw"Not an inter-graph edge!";if(!(h.source!=null&&h.target!=null))throw"Source and/or target is null!";if(!(h.source.edges.indexOf(h)!=-1&&h.target.edges.indexOf(h)!=-1))throw"Source and/or target doesn't know this edge!";var g=h.source.edges.indexOf(h);if(h.source.edges.splice(g,1),g=h.target.edges.indexOf(h),h.target.edges.splice(g,1),!(h.source.owner!=null&&h.source.owner.getGraphManager()!=null))throw"Edge owner graph or owner graph manager is null!";if(h.source.owner.getGraphManager().edges.indexOf(h)==-1)throw"Not in owner graph manager's edge list!";var g=h.source.owner.getGraphManager().edges.indexOf(h);h.source.owner.getGraphManager().edges.splice(g,1)}},a.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},a.prototype.getGraphs=function(){return this.graphs},a.prototype.getAllNodes=function(){if(this.allNodes==null){for(var s=[],l=this.getGraphs(),u=l.length,h=0;h<u;h++)s=s.concat(l[h].getNodes());this.allNodes=s}return this.allNodes},a.prototype.resetAllNodes=function(){this.allNodes=null},a.prototype.resetAllEdges=function(){this.allEdges=null},a.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},a.prototype.getAllEdges=function(){if(this.allEdges==null){for(var s=[],l=this.getGraphs(),u=l.length,h=0;h<l.length;h++)s=s.concat(l[h].getEdges());s=s.concat(this.edges),this.allEdges=s}return this.allEdges},a.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},a.prototype.setAllNodesToApplyGravitation=function(s){if(this.allNodesToApplyGravitation!=null)throw"assert failed";this.allNodesToApplyGravitation=s},a.prototype.getRoot=function(){return this.rootGraph},a.prototype.setRootGraph=function(s){if(s.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=s,s.parent==null&&(s.parent=this.layout.newNode("Root node"))},a.prototype.getLayout=function(){return this.layout},a.prototype.isOneAncestorOfOther=function(s,l){if(!(s!=null&&l!=null))throw"assert failed";if(s==l)return!0;var u=s.getOwner(),h;do{if(h=u.getParent(),h==null)break;if(h==l)return!0;if(u=h.getOwner(),u==null)break}while(!0);u=l.getOwner();do{if(h=u.getParent(),h==null)break;if(h==s)return!0;if(u=h.getOwner(),u==null)break}while(!0);return!1},a.prototype.calcLowestCommonAncestors=function(){for(var s,l,u,h,f,d=this.getAllEdges(),p=d.length,m=0;m<p;m++){if(s=d[m],l=s.source,u=s.target,s.lca=null,s.sourceInLca=l,s.targetInLca=u,l==u){s.lca=l.getOwner();continue}for(h=l.getOwner();s.lca==null;){for(s.targetInLca=u,f=u.getOwner();s.lca==null;){if(f==h){s.lca=f;break}if(f==this.rootGraph)break;if(s.lca!=null)throw"assert failed";s.targetInLca=f.getParent(),f=s.targetInLca.getOwner()}if(h==this.rootGraph)break;s.lca==null&&(s.sourceInLca=h.getParent(),h=s.sourceInLca.getOwner())}if(s.lca==null)throw"assert failed"}},a.prototype.calcLowestCommonAncestor=function(s,l){if(s==l)return s.getOwner();var u=s.getOwner();do{if(u==null)break;var h=l.getOwner();do{if(h==null)break;if(h==u)return h;h=h.getParent().getOwner()}while(!0);u=u.getParent().getOwner()}while(!0);return u},a.prototype.calcInclusionTreeDepths=function(s,l){s==null&&l==null&&(s=this.rootGraph,l=1);for(var u,h=s.getNodes(),f=h.length,d=0;d<f;d++)u=h[d],u.inclusionTreeDepth=l,u.child!=null&&this.calcInclusionTreeDepths(u.child,l+1)},a.prototype.includesInvalidEdge=function(){for(var s,l=this.edges.length,u=0;u<l;u++)if(s=this.edges[u],this.isOneAncestorOfOther(s.source,s.target))return!0;return!1},t.exports=a},function(t,e,r){"use strict";var n=r(0);function i(){}o(i,"FDLayoutConstants");for(var a in n)i[a]=n[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=i.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=i},function(t,e,r){"use strict";var n=r(12);function i(){}o(i,"IGeometry"),i.calcSeparationAmount=function(a,s,l,u){if(!a.intersects(s))throw"assert failed";var h=new Array(2);this.decideDirectionsForOverlappingNodes(a,s,h),l[0]=Math.min(a.getRight(),s.getRight())-Math.max(a.x,s.x),l[1]=Math.min(a.getBottom(),s.getBottom())-Math.max(a.y,s.y),a.getX()<=s.getX()&&a.getRight()>=s.getRight()?l[0]+=Math.min(s.getX()-a.getX(),a.getRight()-s.getRight()):s.getX()<=a.getX()&&s.getRight()>=a.getRight()&&(l[0]+=Math.min(a.getX()-s.getX(),s.getRight()-a.getRight())),a.getY()<=s.getY()&&a.getBottom()>=s.getBottom()?l[1]+=Math.min(s.getY()-a.getY(),a.getBottom()-s.getBottom()):s.getY()<=a.getY()&&s.getBottom()>=a.getBottom()&&(l[1]+=Math.min(a.getY()-s.getY(),s.getBottom()-a.getBottom()));var f=Math.abs((s.getCenterY()-a.getCenterY())/(s.getCenterX()-a.getCenterX()));s.getCenterY()===a.getCenterY()&&s.getCenterX()===a.getCenterX()&&(f=1);var d=f*l[0],p=l[1]/f;l[0]<p?p=l[0]:d=l[1],l[0]=-1*h[0]*(p/2+u),l[1]=-1*h[1]*(d/2+u)},i.decideDirectionsForOverlappingNodes=function(a,s,l){a.getCenterX()<s.getCenterX()?l[0]=-1:l[0]=1,a.getCenterY()<s.getCenterY()?l[1]=-1:l[1]=1},i.getIntersection2=function(a,s,l){var u=a.getCenterX(),h=a.getCenterY(),f=s.getCenterX(),d=s.getCenterY();if(a.intersects(s))return l[0]=u,l[1]=h,l[2]=f,l[3]=d,!0;var p=a.getX(),m=a.getY(),g=a.getRight(),y=a.getX(),v=a.getBottom(),x=a.getRight(),b=a.getWidthHalf(),w=a.getHeightHalf(),C=s.getX(),T=s.getY(),E=s.getRight(),A=s.getX(),S=s.getBottom(),_=s.getRight(),I=s.getWidthHalf(),D=s.getHeightHalf(),k=!1,L=!1;if(u===f){if(h>d)return l[0]=u,l[1]=m,l[2]=f,l[3]=S,!1;if(h<d)return l[0]=u,l[1]=v,l[2]=f,l[3]=T,!1}else if(h===d){if(u>f)return l[0]=p,l[1]=h,l[2]=E,l[3]=d,!1;if(u<f)return l[0]=g,l[1]=h,l[2]=C,l[3]=d,!1}else{var R=a.height/a.width,O=s.height/s.width,M=(d-h)/(f-u),B=void 0,F=void 0,P=void 0,z=void 0,$=void 0,H=void 0;if(-R===M?u>f?(l[0]=y,l[1]=v,k=!0):(l[0]=g,l[1]=m,k=!0):R===M&&(u>f?(l[0]=p,l[1]=m,k=!0):(l[0]=x,l[1]=v,k=!0)),-O===M?f>u?(l[2]=A,l[3]=S,L=!0):(l[2]=E,l[3]=T,L=!0):O===M&&(f>u?(l[2]=C,l[3]=T,L=!0):(l[2]=_,l[3]=S,L=!0)),k&&L)return!1;if(u>f?h>d?(B=this.getCardinalDirection(R,M,4),F=this.getCardinalDirection(O,M,2)):(B=this.getCardinalDirection(-R,M,3),F=this.getCardinalDirection(-O,M,1)):h>d?(B=this.getCardinalDirection(-R,M,1),F=this.getCardinalDirection(-O,M,3)):(B=this.getCardinalDirection(R,M,2),F=this.getCardinalDirection(O,M,4)),!k)switch(B){case 1:z=m,P=u+-w/M,l[0]=P,l[1]=z;break;case 2:P=x,z=h+b*M,l[0]=P,l[1]=z;break;case 3:z=v,P=u+w/M,l[0]=P,l[1]=z;break;case 4:P=y,z=h+-b*M,l[0]=P,l[1]=z;break}if(!L)switch(F){case 1:H=T,$=f+-D/M,l[2]=$,l[3]=H;break;case 2:$=_,H=d+I*M,l[2]=$,l[3]=H;break;case 3:H=S,$=f+D/M,l[2]=$,l[3]=H;break;case 4:$=A,H=d+-I*M,l[2]=$,l[3]=H;break}}return!1},i.getCardinalDirection=function(a,s,l){return a>s?l:1+l%4},i.getIntersection=function(a,s,l,u){if(u==null)return this.getIntersection2(a,s,l);var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=void 0,b=void 0,w=void 0,C=void 0,T=void 0,E=void 0,A=void 0,S=void 0,_=void 0;return w=p-f,T=h-d,A=d*f-h*p,C=v-g,E=m-y,S=y*g-m*v,_=w*E-C*T,_===0?null:(x=(T*S-E*A)/_,b=(C*A-w*S)/_,new n(x,b))},i.angleOfVector=function(a,s,l,u){var h=void 0;return a!==l?(h=Math.atan((u-s)/(l-a)),l<a?h+=Math.PI:u<s&&(h+=this.TWO_PI)):u<s?h=this.ONE_AND_HALF_PI:h=this.HALF_PI,h},i.doIntersect=function(a,s,l,u){var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=(d-h)*(v-g)-(y-m)*(p-f);if(x===0)return!1;var b=((v-g)*(y-h)+(m-y)*(v-f))/x,w=((f-p)*(y-h)+(d-h)*(v-f))/x;return 0<b&&b<1&&0<w&&w<1},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,t.exports=i},function(t,e,r){"use strict";function n(){}o(n,"IMath"),n.sign=function(i){return i>0?1:i<0?-1:0},n.floor=function(i){return i<0?Math.ceil(i):Math.floor(i)},n.ceil=function(i){return i<0?Math.floor(i):Math.ceil(i)},t.exports=n},function(t,e,r){"use strict";function n(){}o(n,"Integer"),n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,r){"use strict";var n=function(){function h(f,d){for(var p=0;p<d.length;p++){var m=d[p];m.enumerable=m.enumerable||!1,m.configurable=!0,"value"in m&&(m.writable=!0),Object.defineProperty(f,m.key,m)}}return o(h,"defineProperties"),function(f,d,p){return d&&h(f.prototype,d),p&&h(f,p),f}}();function i(h,f){if(!(h instanceof f))throw new TypeError("Cannot call a class as a function")}o(i,"_classCallCheck");var a=o(function(f){return{value:f,next:null,prev:null}},"nodeFrom"),s=o(function(f,d,p,m){return f!==null?f.next=d:m.head=d,p!==null?p.prev=d:m.tail=d,d.prev=f,d.next=p,m.length++,d},"add"),l=o(function(f,d){var p=f.prev,m=f.next;return p!==null?p.next=m:d.head=m,m!==null?m.prev=p:d.tail=p,f.prev=f.next=null,d.length--,f},"_remove"),u=function(){function h(f){var d=this;i(this,h),this.length=0,this.head=null,this.tail=null,f?.forEach(function(p){return d.push(p)})}return o(h,"LinkedList"),n(h,[{key:"size",value:o(function(){return this.length},"size")},{key:"insertBefore",value:o(function(d,p){return s(p.prev,a(d),p,this)},"insertBefore")},{key:"insertAfter",value:o(function(d,p){return s(p,a(d),p.next,this)},"insertAfter")},{key:"insertNodeBefore",value:o(function(d,p){return s(p.prev,d,p,this)},"insertNodeBefore")},{key:"insertNodeAfter",value:o(function(d,p){return s(p,d,p.next,this)},"insertNodeAfter")},{key:"push",value:o(function(d){return s(this.tail,a(d),null,this)},"push")},{key:"unshift",value:o(function(d){return s(null,a(d),this.head,this)},"unshift")},{key:"remove",value:o(function(d){return l(d,this)},"remove")},{key:"pop",value:o(function(){return l(this.tail,this).value},"pop")},{key:"popNode",value:o(function(){return l(this.tail,this)},"popNode")},{key:"shift",value:o(function(){return l(this.head,this).value},"shift")},{key:"shiftNode",value:o(function(){return l(this.head,this)},"shiftNode")},{key:"get_object_at",value:o(function(d){if(d<=this.length()){for(var p=1,m=this.head;p<d;)m=m.next,p++;return m.value}},"get_object_at")},{key:"set_object_at",value:o(function(d,p){if(d<=this.length()){for(var m=1,g=this.head;m<d;)g=g.next,m++;g.value=p}},"set_object_at")}]),h}();t.exports=u},function(t,e,r){"use strict";function n(i,a,s){this.x=null,this.y=null,i==null&&a==null&&s==null?(this.x=0,this.y=0):typeof i=="number"&&typeof a=="number"&&s==null?(this.x=i,this.y=a):i.constructor.name=="Point"&&a==null&&s==null&&(s=i,this.x=s.x,this.y=s.y)}o(n,"Point"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.getLocation=function(){return new n(this.x,this.y)},n.prototype.setLocation=function(i,a,s){i.constructor.name=="Point"&&a==null&&s==null?(s=i,this.setLocation(s.x,s.y)):typeof i=="number"&&typeof a=="number"&&s==null&&(parseInt(i)==i&&parseInt(a)==a?this.move(i,a):(this.x=Math.floor(i+.5),this.y=Math.floor(a+.5)))},n.prototype.move=function(i,a){this.x=i,this.y=a},n.prototype.translate=function(i,a){this.x+=i,this.y+=a},n.prototype.equals=function(i){if(i.constructor.name=="Point"){var a=i;return this.x==a.x&&this.y==a.y}return this==i},n.prototype.toString=function(){return new n().constructor.name+"[x="+this.x+",y="+this.y+"]"},t.exports=n},function(t,e,r){"use strict";function n(i,a,s,l){this.x=0,this.y=0,this.width=0,this.height=0,i!=null&&a!=null&&s!=null&&l!=null&&(this.x=i,this.y=a,this.width=s,this.height=l)}o(n,"RectangleD"),n.prototype.getX=function(){return this.x},n.prototype.setX=function(i){this.x=i},n.prototype.getY=function(){return this.y},n.prototype.setY=function(i){this.y=i},n.prototype.getWidth=function(){return this.width},n.prototype.setWidth=function(i){this.width=i},n.prototype.getHeight=function(){return this.height},n.prototype.setHeight=function(i){this.height=i},n.prototype.getRight=function(){return this.x+this.width},n.prototype.getBottom=function(){return this.y+this.height},n.prototype.intersects=function(i){return!(this.getRight()<i.x||this.getBottom()<i.y||i.getRight()<this.x||i.getBottom()<this.y)},n.prototype.getCenterX=function(){return this.x+this.width/2},n.prototype.getMinX=function(){return this.getX()},n.prototype.getMaxX=function(){return this.getX()+this.width},n.prototype.getCenterY=function(){return this.y+this.height/2},n.prototype.getMinY=function(){return this.getY()},n.prototype.getMaxY=function(){return this.getY()+this.height},n.prototype.getWidthHalf=function(){return this.width/2},n.prototype.getHeightHalf=function(){return this.height/2},t.exports=n},function(t,e,r){"use strict";var n=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};function i(){}o(i,"UniqueIDGeneretor"),i.lastID=0,i.createID=function(a){return i.isPrimitive(a)?a:(a.uniqueID!=null||(a.uniqueID=i.getString(),i.lastID++),a.uniqueID)},i.getString=function(a){return a==null&&(a=i.lastID),"Object#"+a},i.isPrimitive=function(a){var s=typeof a>"u"?"undefined":n(a);return a==null||s!="object"&&s!="function"},t.exports=i},function(t,e,r){"use strict";function n(m){if(Array.isArray(m)){for(var g=0,y=Array(m.length);g<m.length;g++)y[g]=m[g];return y}else return Array.from(m)}o(n,"_toConsumableArray");var i=r(0),a=r(6),s=r(3),l=r(1),u=r(5),h=r(4),f=r(17),d=r(27);function p(m){d.call(this),this.layoutQuality=i.QUALITY,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=i.DEFAULT_INCREMENTAL,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new a(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,m!=null&&(this.isRemoteUse=m)}o(p,"Layout"),p.RANDOM_SEED=1,p.prototype=Object.create(d.prototype),p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},p.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},p.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},p.prototype.newGraphManager=function(){var m=new a(this);return this.graphManager=m,m},p.prototype.newGraph=function(m){return new u(null,this.graphManager,m)},p.prototype.newNode=function(m){return new s(this.graphManager,m)},p.prototype.newEdge=function(m){return new l(null,null,m)},p.prototype.checkLayoutSuccess=function(){return this.graphManager.getRoot()==null||this.graphManager.getRoot().getNodes().length==0||this.graphManager.includesInvalidEdge()},p.prototype.runLayout=function(){this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters();var m;return this.checkLayoutSuccess()?m=!1:m=this.layout(),i.ANIMATE==="during"?!1:(m&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,m)},p.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},p.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var m,g=this.graphManager.getAllEdges(),y=0;y<g.length;y++)m=g[y];for(var v,x=this.graphManager.getRoot().getNodes(),y=0;y<x.length;y++)v=x[y];this.update(this.graphManager.getRoot())}},p.prototype.update=function(m){if(m==null)this.update2();else if(m instanceof s){var g=m;if(g.getChild()!=null)for(var y=g.getChild().getNodes(),v=0;v<y.length;v++)update(y[v]);if(g.vGraphObject!=null){var x=g.vGraphObject;x.update(g)}}else if(m instanceof l){var b=m;if(b.vGraphObject!=null){var w=b.vGraphObject;w.update(b)}}else if(m instanceof u){var C=m;if(C.vGraphObject!=null){var T=C.vGraphObject;T.update(C)}}},p.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=i.QUALITY,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=i.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},p.prototype.transform=function(m){if(m==null)this.transform(new h(0,0));else{var g=new f,y=this.graphManager.getRoot().updateLeftTop();if(y!=null){g.setWorldOrgX(m.x),g.setWorldOrgY(m.y),g.setDeviceOrgX(y.x),g.setDeviceOrgY(y.y);for(var v=this.getAllNodes(),x,b=0;b<v.length;b++)x=v[b],x.transform(g)}}},p.prototype.positionNodesRandomly=function(m){if(m==null)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var g,y,v=m.getNodes(),x=0;x<v.length;x++)g=v[x],y=g.getChild(),y==null||y.getNodes().length==0?g.scatter():(this.positionNodesRandomly(y),g.updateBounds())},p.prototype.getFlatForest=function(){for(var m=[],g=!0,y=this.graphManager.getRoot().getNodes(),v=!0,x=0;x<y.length;x++)y[x].getChild()!=null&&(v=!1);if(!v)return m;var b=new Set,w=[],C=new Map,T=[];for(T=T.concat(y);T.length>0&&g;){for(w.push(T[0]);w.length>0&&g;){var E=w[0];w.splice(0,1),b.add(E);for(var A=E.getEdges(),x=0;x<A.length;x++){var S=A[x].getOtherEnd(E);if(C.get(E)!=S)if(!b.has(S))w.push(S),C.set(S,E);else{g=!1;break}}}if(!g)m=[];else{var _=[].concat(n(b));m.push(_);for(var x=0;x<_.length;x++){var I=_[x],D=T.indexOf(I);D>-1&&T.splice(D,1)}b=new Set,C=new Map}}return m},p.prototype.createDummyNodesForBendpoints=function(m){for(var g=[],y=m.source,v=this.graphManager.calcLowestCommonAncestor(m.source,m.target),x=0;x<m.bendpoints.length;x++){var b=this.newNode(null);b.setRect(new Point(0,0),new Dimension(1,1)),v.add(b);var w=this.newEdge(null);this.graphManager.add(w,y,b),g.add(b),y=b}var w=this.newEdge(null);return this.graphManager.add(w,y,m.target),this.edgeToDummyNodes.set(m,g),m.isInterGraph()?this.graphManager.remove(m):v.remove(m),g},p.prototype.createBendpointsFromDummyNodes=function(){var m=[];m=m.concat(this.graphManager.getAllEdges()),m=[].concat(n(this.edgeToDummyNodes.keys())).concat(m);for(var g=0;g<m.length;g++){var y=m[g];if(y.bendpoints.length>0){for(var v=this.edgeToDummyNodes.get(y),x=0;x<v.length;x++){var b=v[x],w=new h(b.getCenterX(),b.getCenterY()),C=y.bendpoints.get(x);C.x=w.x,C.y=w.y,b.getOwner().remove(b)}this.graphManager.add(y,y.source,y.target)}}},p.transform=function(m,g,y,v){if(y!=null&&v!=null){var x=g;if(m<=50){var b=g/y;x-=(g-b)/50*(50-m)}else{var w=g*v;x+=(w-g)/50*(m-50)}return x}else{var C,T;return m<=50?(C=9*g/500,T=g/10):(C=9*g/50,T=-8*g),C*m+T}},p.findCenterOfTree=function(m){var g=[];g=g.concat(m);var y=[],v=new Map,x=!1,b=null;(g.length==1||g.length==2)&&(x=!0,b=g[0]);for(var w=0;w<g.length;w++){var C=g[w],T=C.getNeighborsList().size;v.set(C,C.getNeighborsList().size),T==1&&y.push(C)}var E=[];for(E=E.concat(y);!x;){var A=[];A=A.concat(E),E=[];for(var w=0;w<g.length;w++){var C=g[w],S=g.indexOf(C);S>=0&&g.splice(S,1);var _=C.getNeighborsList();_.forEach(function(k){if(y.indexOf(k)<0){var L=v.get(k),R=L-1;R==1&&E.push(k),v.set(k,R)}})}y=y.concat(E),(g.length==1||g.length==2)&&(x=!0,b=g[0])}return b},p.prototype.setGraphManager=function(m){this.graphManager=m},t.exports=p},function(t,e,r){"use strict";function n(){}o(n,"RandomSeed"),n.seed=1,n.x=0,n.nextDouble=function(){return n.x=Math.sin(n.seed++)*1e4,n.x-Math.floor(n.x)},t.exports=n},function(t,e,r){"use strict";var n=r(4);function i(a,s){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}o(i,"Transform"),i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(a){this.lworldOrgX=a},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(a){this.lworldOrgY=a},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(a){this.lworldExtX=a},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(a){this.lworldExtY=a},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(a){this.ldeviceOrgX=a},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(a){this.ldeviceOrgY=a},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(a){this.ldeviceExtX=a},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(a){this.ldeviceExtY=a},i.prototype.transformX=function(a){var s=0,l=this.lworldExtX;return l!=0&&(s=this.ldeviceOrgX+(a-this.lworldOrgX)*this.ldeviceExtX/l),s},i.prototype.transformY=function(a){var s=0,l=this.lworldExtY;return l!=0&&(s=this.ldeviceOrgY+(a-this.lworldOrgY)*this.ldeviceExtY/l),s},i.prototype.inverseTransformX=function(a){var s=0,l=this.ldeviceExtX;return l!=0&&(s=this.lworldOrgX+(a-this.ldeviceOrgX)*this.lworldExtX/l),s},i.prototype.inverseTransformY=function(a){var s=0,l=this.ldeviceExtY;return l!=0&&(s=this.lworldOrgY+(a-this.ldeviceOrgY)*this.lworldExtY/l),s},i.prototype.inverseTransformPoint=function(a){var s=new n(this.inverseTransformX(a.x),this.inverseTransformY(a.y));return s},t.exports=i},function(t,e,r){"use strict";function n(d){if(Array.isArray(d)){for(var p=0,m=Array(d.length);p<d.length;p++)m[p]=d[p];return m}else return Array.from(d)}o(n,"_toConsumableArray");var i=r(15),a=r(7),s=r(0),l=r(8),u=r(9);function h(){i.call(this),this.useSmartIdealEdgeLengthCalculation=a.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=a.DEFAULT_EDGE_LENGTH,this.springConstant=a.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=a.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=a.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=a.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=a.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*a.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=a.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=a.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=a.MAX_ITERATIONS}o(h,"FDLayout"),h.prototype=Object.create(i.prototype);for(var f in i)h[f]=i[f];h.prototype.initParameters=function(){i.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=a.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},h.prototype.calcIdealEdgeLengths=function(){for(var d,p,m,g,y,v,x=this.getGraphManager().getAllEdges(),b=0;b<x.length;b++)d=x[b],d.idealLength=this.idealEdgeLength,d.isInterGraph&&(m=d.getSource(),g=d.getTarget(),y=d.getSourceInLca().getEstimatedSize(),v=d.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(d.idealLength+=y+v-2*s.SIMPLE_NODE_SIZE),p=d.getLca().getInclusionTreeDepth(),d.idealLength+=a.DEFAULT_EDGE_LENGTH*a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(m.getInclusionTreeDepth()+g.getInclusionTreeDepth()-2*p))},h.prototype.initSpringEmbedder=function(){var d=this.getAllNodes().length;this.incremental?(d>a.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*a.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-a.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT_INCREMENTAL):(d>a.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(a.COOLING_ADAPTATION_FACTOR,1-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*(1-a.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var d=this.getAllEdges(),p,m=0;m<d.length;m++)p=d[m],this.calcSpringForce(p,p.idealLength)},h.prototype.calcRepulsionForces=function(){var d=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,p=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,m,g,y,v,x=this.getAllNodes(),b;if(this.useFRGridVariant)for(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&d&&this.updateGrid(),b=new Set,m=0;m<x.length;m++)y=x[m],this.calculateRepulsionForceOfANode(y,b,d,p),b.add(y);else for(m=0;m<x.length;m++)for(y=x[m],g=m+1;g<x.length;g++)v=x[g],y.getOwner()==v.getOwner()&&this.calcRepulsionForce(y,v)},h.prototype.calcGravitationalForces=function(){for(var d,p=this.getAllNodesToApplyGravitation(),m=0;m<p.length;m++)d=p[m],this.calcGravitationalForce(d)},h.prototype.moveNodes=function(){for(var d=this.getAllNodes(),p,m=0;m<d.length;m++)p=d[m],p.move()},h.prototype.calcSpringForce=function(d,p){var m=d.getSource(),g=d.getTarget(),y,v,x,b;if(this.uniformLeafNodeSizes&&m.getChild()==null&&g.getChild()==null)d.updateLengthSimple();else if(d.updateLength(),d.isOverlapingSourceAndTarget)return;y=d.getLength(),y!=0&&(v=this.springConstant*(y-p),x=v*(d.lengthX/y),b=v*(d.lengthY/y),m.springForceX+=x,m.springForceY+=b,g.springForceX-=x,g.springForceY-=b)},h.prototype.calcRepulsionForce=function(d,p){var m=d.getRect(),g=p.getRect(),y=new Array(2),v=new Array(4),x,b,w,C,T,E,A;if(m.intersects(g)){l.calcSeparationAmount(m,g,y,a.DEFAULT_EDGE_LENGTH/2),E=2*y[0],A=2*y[1];var S=d.noOfChildren*p.noOfChildren/(d.noOfChildren+p.noOfChildren);d.repulsionForceX-=S*E,d.repulsionForceY-=S*A,p.repulsionForceX+=S*E,p.repulsionForceY+=S*A}else this.uniformLeafNodeSizes&&d.getChild()==null&&p.getChild()==null?(x=g.getCenterX()-m.getCenterX(),b=g.getCenterY()-m.getCenterY()):(l.getIntersection(m,g,v),x=v[2]-v[0],b=v[3]-v[1]),Math.abs(x)<a.MIN_REPULSION_DIST&&(x=u.sign(x)*a.MIN_REPULSION_DIST),Math.abs(b)<a.MIN_REPULSION_DIST&&(b=u.sign(b)*a.MIN_REPULSION_DIST),w=x*x+b*b,C=Math.sqrt(w),T=this.repulsionConstant*d.noOfChildren*p.noOfChildren/w,E=T*x/C,A=T*b/C,d.repulsionForceX-=E,d.repulsionForceY-=A,p.repulsionForceX+=E,p.repulsionForceY+=A},h.prototype.calcGravitationalForce=function(d){var p,m,g,y,v,x,b,w;p=d.getOwner(),m=(p.getRight()+p.getLeft())/2,g=(p.getTop()+p.getBottom())/2,y=d.getCenterX()-m,v=d.getCenterY()-g,x=Math.abs(y)+d.getWidth()/2,b=Math.abs(v)+d.getHeight()/2,d.getOwner()==this.graphManager.getRoot()?(w=p.getEstimatedSize()*this.gravityRangeFactor,(x>w||b>w)&&(d.gravitationForceX=-this.gravityConstant*y,d.gravitationForceY=-this.gravityConstant*v)):(w=p.getEstimatedSize()*this.compoundGravityRangeFactor,(x>w||b>w)&&(d.gravitationForceX=-this.gravityConstant*y*this.compoundGravityConstant,d.gravitationForceY=-this.gravityConstant*v*this.compoundGravityConstant))},h.prototype.isConverged=function(){var d,p=!1;return this.totalIterations>this.maxIterations/3&&(p=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),d=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,d||p},h.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},h.prototype.calcNoOfChildrenForAllNodes=function(){for(var d,p=this.graphManager.getAllNodes(),m=0;m<p.length;m++)d=p[m],d.noOfChildren=d.getNoOfChildren()},h.prototype.calcGrid=function(d){var p=0,m=0;p=parseInt(Math.ceil((d.getRight()-d.getLeft())/this.repulsionRange)),m=parseInt(Math.ceil((d.getBottom()-d.getTop())/this.repulsionRange));for(var g=new Array(p),y=0;y<p;y++)g[y]=new Array(m);for(var y=0;y<p;y++)for(var v=0;v<m;v++)g[y][v]=new Array;return g},h.prototype.addNodeToGrid=function(d,p,m){var g=0,y=0,v=0,x=0;g=parseInt(Math.floor((d.getRect().x-p)/this.repulsionRange)),y=parseInt(Math.floor((d.getRect().width+d.getRect().x-p)/this.repulsionRange)),v=parseInt(Math.floor((d.getRect().y-m)/this.repulsionRange)),x=parseInt(Math.floor((d.getRect().height+d.getRect().y-m)/this.repulsionRange));for(var b=g;b<=y;b++)for(var w=v;w<=x;w++)this.grid[b][w].push(d),d.setGridCoordinates(g,y,v,x)},h.prototype.updateGrid=function(){var d,p,m=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),d=0;d<m.length;d++)p=m[d],this.addNodeToGrid(p,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},h.prototype.calculateRepulsionForceOfANode=function(d,p,m,g){if(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&m||g){var y=new Set;d.surrounding=new Array;for(var v,x=this.grid,b=d.startX-1;b<d.finishX+2;b++)for(var w=d.startY-1;w<d.finishY+2;w++)if(!(b<0||w<0||b>=x.length||w>=x[0].length)){for(var C=0;C<x[b][w].length;C++)if(v=x[b][w][C],!(d.getOwner()!=v.getOwner()||d==v)&&!p.has(v)&&!y.has(v)){var T=Math.abs(d.getCenterX()-v.getCenterX())-(d.getWidth()/2+v.getWidth()/2),E=Math.abs(d.getCenterY()-v.getCenterY())-(d.getHeight()/2+v.getHeight()/2);T<=this.repulsionRange&&E<=this.repulsionRange&&y.add(v)}}d.surrounding=[].concat(n(y))}for(b=0;b<d.surrounding.length;b++)this.calcRepulsionForce(d,d.surrounding[b])},h.prototype.calcRepulsionRange=function(){return 0},t.exports=h},function(t,e,r){"use strict";var n=r(1),i=r(7);function a(l,u,h){n.call(this,l,u,h),this.idealLength=i.DEFAULT_EDGE_LENGTH}o(a,"FDLayoutEdge"),a.prototype=Object.create(n.prototype);for(var s in n)a[s]=n[s];t.exports=a},function(t,e,r){"use strict";var n=r(3);function i(s,l,u,h){n.call(this,s,l,u,h),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}o(i,"FDLayoutNode"),i.prototype=Object.create(n.prototype);for(var a in n)i[a]=n[a];i.prototype.setGridCoordinates=function(s,l,u,h){this.startX=s,this.finishX=l,this.startY=u,this.finishY=h},t.exports=i},function(t,e,r){"use strict";function n(i,a){this.width=0,this.height=0,i!==null&&a!==null&&(this.height=a,this.width=i)}o(n,"DimensionD"),n.prototype.getWidth=function(){return this.width},n.prototype.setWidth=function(i){this.width=i},n.prototype.getHeight=function(){return this.height},n.prototype.setHeight=function(i){this.height=i},t.exports=n},function(t,e,r){"use strict";var n=r(14);function i(){this.map={},this.keys=[]}o(i,"HashMap"),i.prototype.put=function(a,s){var l=n.createID(a);this.contains(l)||(this.map[l]=s,this.keys.push(a))},i.prototype.contains=function(a){var s=n.createID(a);return this.map[a]!=null},i.prototype.get=function(a){var s=n.createID(a);return this.map[s]},i.prototype.keySet=function(){return this.keys},t.exports=i},function(t,e,r){"use strict";var n=r(14);function i(){this.set={}}o(i,"HashSet"),i.prototype.add=function(a){var s=n.createID(a);this.contains(s)||(this.set[s]=a)},i.prototype.remove=function(a){delete this.set[n.createID(a)]},i.prototype.clear=function(){this.set={}},i.prototype.contains=function(a){return this.set[n.createID(a)]==a},i.prototype.isEmpty=function(){return this.size()===0},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAllTo=function(a){for(var s=Object.keys(this.set),l=s.length,u=0;u<l;u++)a.push(this.set[s[u]])},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAll=function(a){for(var s=a.length,l=0;l<s;l++){var u=a[l];this.add(u)}},t.exports=i},function(t,e,r){"use strict";var n=function(){function l(u,h){for(var f=0;f<h.length;f++){var d=h[f];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(u,d.key,d)}}return o(l,"defineProperties"),function(u,h,f){return h&&l(u.prototype,h),f&&l(u,f),u}}();function i(l,u){if(!(l instanceof u))throw new TypeError("Cannot call a class as a function")}o(i,"_classCallCheck");var a=r(11),s=function(){function l(u,h){i(this,l),(h!==null||h!==void 0)&&(this.compareFunction=this._defaultCompareFunction);var f=void 0;u instanceof a?f=u.size():f=u.length,this._quicksort(u,0,f-1)}return o(l,"Quicksort"),n(l,[{key:"_quicksort",value:o(function(h,f,d){if(f<d){var p=this._partition(h,f,d);this._quicksort(h,f,p),this._quicksort(h,p+1,d)}},"_quicksort")},{key:"_partition",value:o(function(h,f,d){for(var p=this._get(h,f),m=f,g=d;;){for(;this.compareFunction(p,this._get(h,g));)g--;for(;this.compareFunction(this._get(h,m),p);)m++;if(m<g)this._swap(h,m,g),m++,g--;else return g}},"_partition")},{key:"_get",value:o(function(h,f){return h instanceof a?h.get_object_at(f):h[f]},"_get")},{key:"_set",value:o(function(h,f,d){h instanceof a?h.set_object_at(f,d):h[f]=d},"_set")},{key:"_swap",value:o(function(h,f,d){var p=this._get(h,f);this._set(h,f,this._get(h,d)),this._set(h,d,p)},"_swap")},{key:"_defaultCompareFunction",value:o(function(h,f){return f>h},"_defaultCompareFunction")}]),l}();t.exports=s},function(t,e,r){"use strict";var n=function(){function s(l,u){for(var h=0;h<u.length;h++){var f=u[h];f.enumerable=f.enumerable||!1,f.configurable=!0,"value"in f&&(f.writable=!0),Object.defineProperty(l,f.key,f)}}return o(s,"defineProperties"),function(l,u,h){return u&&s(l.prototype,u),h&&s(l,h),l}}();function i(s,l){if(!(s instanceof l))throw new TypeError("Cannot call a class as a function")}o(i,"_classCallCheck");var a=function(){function s(l,u){var h=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,f=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,d=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;i(this,s),this.sequence1=l,this.sequence2=u,this.match_score=h,this.mismatch_penalty=f,this.gap_penalty=d,this.iMax=l.length+1,this.jMax=u.length+1,this.grid=new Array(this.iMax);for(var p=0;p<this.iMax;p++){this.grid[p]=new Array(this.jMax);for(var m=0;m<this.jMax;m++)this.grid[p][m]=0}this.tracebackGrid=new Array(this.iMax);for(var g=0;g<this.iMax;g++){this.tracebackGrid[g]=new Array(this.jMax);for(var y=0;y<this.jMax;y++)this.tracebackGrid[g][y]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return o(s,"NeedlemanWunsch"),n(s,[{key:"getScore",value:o(function(){return this.score},"getScore")},{key:"getAlignments",value:o(function(){return this.alignments},"getAlignments")},{key:"computeGrids",value:o(function(){for(var u=1;u<this.jMax;u++)this.grid[0][u]=this.grid[0][u-1]+this.gap_penalty,this.tracebackGrid[0][u]=[!1,!1,!0];for(var h=1;h<this.iMax;h++)this.grid[h][0]=this.grid[h-1][0]+this.gap_penalty,this.tracebackGrid[h][0]=[!1,!0,!1];for(var f=1;f<this.iMax;f++)for(var d=1;d<this.jMax;d++){var p=void 0;this.sequence1[f-1]===this.sequence2[d-1]?p=this.grid[f-1][d-1]+this.match_score:p=this.grid[f-1][d-1]+this.mismatch_penalty;var m=this.grid[f-1][d]+this.gap_penalty,g=this.grid[f][d-1]+this.gap_penalty,y=[p,m,g],v=this.arrayAllMaxIndexes(y);this.grid[f][d]=y[v[0]],this.tracebackGrid[f][d]=[v.includes(0),v.includes(1),v.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]},"computeGrids")},{key:"alignmentTraceback",value:o(function(){var u=[];for(u.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});u[0];){var h=u[0],f=this.tracebackGrid[h.pos[0]][h.pos[1]];f[0]&&u.push({pos:[h.pos[0]-1,h.pos[1]-1],seq1:this.sequence1[h.pos[0]-1]+h.seq1,seq2:this.sequence2[h.pos[1]-1]+h.seq2}),f[1]&&u.push({pos:[h.pos[0]-1,h.pos[1]],seq1:this.sequence1[h.pos[0]-1]+h.seq1,seq2:"-"+h.seq2}),f[2]&&u.push({pos:[h.pos[0],h.pos[1]-1],seq1:"-"+h.seq1,seq2:this.sequence2[h.pos[1]-1]+h.seq2}),h.pos[0]===0&&h.pos[1]===0&&this.alignments.push({sequence1:h.seq1,sequence2:h.seq2}),u.shift()}return this.alignments},"alignmentTraceback")},{key:"getAllIndexes",value:o(function(u,h){for(var f=[],d=-1;(d=u.indexOf(h,d+1))!==-1;)f.push(d);return f},"getAllIndexes")},{key:"arrayAllMaxIndexes",value:o(function(u){return this.getAllIndexes(u,Math.max.apply(null,u))},"arrayAllMaxIndexes")}]),s}();t.exports=a},function(t,e,r){"use strict";var n=o(function(){},"layoutBase");n.FDLayout=r(18),n.FDLayoutConstants=r(7),n.FDLayoutEdge=r(19),n.FDLayoutNode=r(20),n.DimensionD=r(21),n.HashMap=r(22),n.HashSet=r(23),n.IGeometry=r(8),n.IMath=r(9),n.Integer=r(10),n.Point=r(12),n.PointD=r(4),n.RandomSeed=r(16),n.RectangleD=r(13),n.Transform=r(17),n.UniqueIDGeneretor=r(14),n.Quicksort=r(24),n.LinkedList=r(11),n.LGraphObject=r(2),n.LGraph=r(5),n.LEdge=r(1),n.LGraphManager=r(6),n.LNode=r(3),n.Layout=r(15),n.LayoutConstants=r(0),n.NeedlemanWunsch=r(25),t.exports=n},function(t,e,r){"use strict";function n(){this.listeners=[]}o(n,"Emitter");var i=n.prototype;i.addListener=function(a,s){this.listeners.push({event:a,callback:s})},i.removeListener=function(a,s){for(var l=this.listeners.length;l>=0;l--){var u=this.listeners[l];u.event===a&&u.callback===s&&this.listeners.splice(l,1)}},i.emit=function(a,s){for(var l=0;l<this.listeners.length;l++){var u=this.listeners[l];a===u.event&&u.callback(s)}},t.exports=n}])})});var AB=Mi((h4,CB)=>{"use strict";o(function(e,r){typeof h4=="object"&&typeof CB=="object"?CB.exports=r(SB()):typeof define=="function"&&define.amd?define(["layout-base"],r):typeof h4=="object"?h4.coseBase=r(SB()):e.coseBase=r(e.layoutBase)},"webpackUniversalModuleDefinition")(h4,function(t){return function(e){var r={};function n(i){if(r[i])return r[i].exports;var a=r[i]={i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return o(n,"__webpack_require__"),n.m=e,n.c=r,n.i=function(i){return i},n.d=function(i,a,s){n.o(i,a)||Object.defineProperty(i,a,{configurable:!1,enumerable:!0,get:s})},n.n=function(i){var a=i&&i.__esModule?o(function(){return i.default},"getDefault"):o(function(){return i},"getModuleExports");return n.d(a,"a",a),a},n.o=function(i,a){return Object.prototype.hasOwnProperty.call(i,a)},n.p="",n(n.s=7)}([function(e,r){e.exports=t},function(e,r,n){"use strict";var i=n(0).FDLayoutConstants;function a(){}o(a,"CoSEConstants");for(var s in i)a[s]=i[s];a.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,a.DEFAULT_RADIAL_SEPARATION=i.DEFAULT_EDGE_LENGTH,a.DEFAULT_COMPONENT_SEPERATION=60,a.TILE=!0,a.TILING_PADDING_VERTICAL=10,a.TILING_PADDING_HORIZONTAL=10,a.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=a},function(e,r,n){"use strict";var i=n(0).FDLayoutEdge;function a(l,u,h){i.call(this,l,u,h)}o(a,"CoSEEdge"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).LGraph;function a(l,u,h){i.call(this,l,u,h)}o(a,"CoSEGraph"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).LGraphManager;function a(l){i.call(this,l)}o(a,"CoSEGraphManager"),a.prototype=Object.create(i.prototype);for(var s in i)a[s]=i[s];e.exports=a},function(e,r,n){"use strict";var i=n(0).FDLayoutNode,a=n(0).IMath;function s(u,h,f,d){i.call(this,u,h,f,d)}o(s,"CoSENode"),s.prototype=Object.create(i.prototype);for(var l in i)s[l]=i[l];s.prototype.move=function(){var u=this.graphManager.getLayout();this.displacementX=u.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=u.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>u.coolingFactor*u.maxNodeDisplacement&&(this.displacementX=u.coolingFactor*u.maxNodeDisplacement*a.sign(this.displacementX)),Math.abs(this.displacementY)>u.coolingFactor*u.maxNodeDisplacement&&(this.displacementY=u.coolingFactor*u.maxNodeDisplacement*a.sign(this.displacementY)),this.child==null?this.moveBy(this.displacementX,this.displacementY):this.child.getNodes().length==0?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),u.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},s.prototype.propogateDisplacementToChildren=function(u,h){for(var f=this.getChild().getNodes(),d,p=0;p<f.length;p++)d=f[p],d.getChild()==null?(d.moveBy(u,h),d.displacementX+=u,d.displacementY+=h):d.propogateDisplacementToChildren(u,h)},s.prototype.setPred1=function(u){this.pred1=u},s.prototype.getPred1=function(){return pred1},s.prototype.getPred2=function(){return pred2},s.prototype.setNext=function(u){this.next=u},s.prototype.getNext=function(){return next},s.prototype.setProcessed=function(u){this.processed=u},s.prototype.isProcessed=function(){return processed},e.exports=s},function(e,r,n){"use strict";var i=n(0).FDLayout,a=n(4),s=n(3),l=n(5),u=n(2),h=n(1),f=n(0).FDLayoutConstants,d=n(0).LayoutConstants,p=n(0).Point,m=n(0).PointD,g=n(0).Layout,y=n(0).Integer,v=n(0).IGeometry,x=n(0).LGraph,b=n(0).Transform;function w(){i.call(this),this.toBeTiled={}}o(w,"CoSELayout"),w.prototype=Object.create(i.prototype);for(var C in i)w[C]=i[C];w.prototype.newGraphManager=function(){var T=new a(this);return this.graphManager=T,T},w.prototype.newGraph=function(T){return new s(null,this.graphManager,T)},w.prototype.newNode=function(T){return new l(this.graphManager,T)},w.prototype.newEdge=function(T){return new u(null,null,T)},w.prototype.initParameters=function(){i.prototype.initParameters.call(this,arguments),this.isSubLayout||(h.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=h.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=h.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=f.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=f.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=f.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=f.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=f.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=f.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/f.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=f.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},w.prototype.layout=function(){var T=d.DEFAULT_CREATE_BENDS_AS_NEEDED;return T&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},w.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(h.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),A=this.nodesWithGravity.filter(function(I){return E.has(I)});this.graphManager.setAllNodesToApplyGravitation(A)}}else{var T=this.getFlatForest();if(T.length>0)this.positionNodesRadially(T);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),A=this.nodesWithGravity.filter(function(S){return E.has(S)});this.graphManager.setAllNodesToApplyGravitation(A),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},w.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%f.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var T=new Set(this.getAllNodes()),E=this.nodesWithGravity.filter(function(_){return T.has(_)});this.graphManager.setAllNodesToApplyGravitation(E),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=f.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=f.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var A=!this.isTreeGrowing&&!this.isGrowthFinished,S=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(A,S),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},w.prototype.getPositionsData=function(){for(var T=this.graphManager.getAllNodes(),E={},A=0;A<T.length;A++){var S=T[A].rect,_=T[A].id;E[_]={id:_,x:S.getCenterX(),y:S.getCenterY(),w:S.width,h:S.height}}return E},w.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var T=!1;if(f.ANIMATE==="during")this.emit("layoutstarted");else{for(;!T;)T=this.tick();this.graphManager.updateBounds()}},w.prototype.calculateNodesToApplyGravitationTo=function(){var T=[],E,A=this.graphManager.getGraphs(),S=A.length,_;for(_=0;_<S;_++)E=A[_],E.updateConnected(),E.isConnected||(T=T.concat(E.getNodes()));return T},w.prototype.createBendpoints=function(){var T=[];T=T.concat(this.graphManager.getAllEdges());var E=new Set,A;for(A=0;A<T.length;A++){var S=T[A];if(!E.has(S)){var _=S.getSource(),I=S.getTarget();if(_==I)S.getBendpoints().push(new m),S.getBendpoints().push(new m),this.createDummyNodesForBendpoints(S),E.add(S);else{var D=[];if(D=D.concat(_.getEdgeListToNode(I)),D=D.concat(I.getEdgeListToNode(_)),!E.has(D[0])){if(D.length>1){var k;for(k=0;k<D.length;k++){var L=D[k];L.getBendpoints().push(new m),this.createDummyNodesForBendpoints(L)}}D.forEach(function(R){E.add(R)})}}}if(E.size==T.length)break}},w.prototype.positionNodesRadially=function(T){for(var E=new p(0,0),A=Math.ceil(Math.sqrt(T.length)),S=0,_=0,I=0,D=new m(0,0),k=0;k<T.length;k++){k%A==0&&(I=0,_=S,k!=0&&(_+=h.DEFAULT_COMPONENT_SEPERATION),S=0);var L=T[k],R=g.findCenterOfTree(L);E.x=I,E.y=_,D=w.radialLayout(L,R,E),D.y>S&&(S=Math.floor(D.y)),I=Math.floor(D.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new m(d.WORLD_CENTER_X-D.x/2,d.WORLD_CENTER_Y-D.y/2))},w.radialLayout=function(T,E,A){var S=Math.max(this.maxDiagonalInTree(T),h.DEFAULT_RADIAL_SEPARATION);w.branchRadialLayout(E,null,0,359,0,S);var _=x.calculateBounds(T),I=new b;I.setDeviceOrgX(_.getMinX()),I.setDeviceOrgY(_.getMinY()),I.setWorldOrgX(A.x),I.setWorldOrgY(A.y);for(var D=0;D<T.length;D++){var k=T[D];k.transform(I)}var L=new m(_.getMaxX(),_.getMaxY());return I.inverseTransformPoint(L)},w.branchRadialLayout=function(T,E,A,S,_,I){var D=(S-A+1)/2;D<0&&(D+=180);var k=(D+A)%360,L=k*v.TWO_PI/360,R=Math.cos(L),O=_*Math.cos(L),M=_*Math.sin(L);T.setCenter(O,M);var B=[];B=B.concat(T.getEdges());var F=B.length;E!=null&&F--;for(var P=0,z=B.length,$,H=T.getEdgesBetween(E);H.length>1;){var Q=H[0];H.splice(0,1);var j=B.indexOf(Q);j>=0&&B.splice(j,1),z--,F--}E!=null?$=(B.indexOf(H[0])+1)%z:$=0;for(var ie=Math.abs(S-A)/F,ne=$;P!=F;ne=++ne%z){var le=B[ne].getOtherEnd(T);if(le!=E){var he=(A+P*ie)%360,K=(he+ie)%360;w.branchRadialLayout(le,T,he,K,_+I,I),P++}}},w.maxDiagonalInTree=function(T){for(var E=y.MIN_VALUE,A=0;A<T.length;A++){var S=T[A],_=S.getDiagonal();_>E&&(E=_)}return E},w.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},w.prototype.groupZeroDegreeMembers=function(){var T=this,E={};this.memberGroups={},this.idToDummyNode={};for(var A=[],S=this.graphManager.getAllNodes(),_=0;_<S.length;_++){var I=S[_],D=I.getParent();this.getNodeDegreeWithChildren(I)===0&&(D.id==null||!this.getToBeTiled(D))&&A.push(I)}for(var _=0;_<A.length;_++){var I=A[_],k=I.getParent().id;typeof E[k]>"u"&&(E[k]=[]),E[k]=E[k].concat(I)}Object.keys(E).forEach(function(L){if(E[L].length>1){var R="DummyCompound_"+L;T.memberGroups[R]=E[L];var O=E[L][0].getParent(),M=new l(T.graphManager);M.id=R,M.paddingLeft=O.paddingLeft||0,M.paddingRight=O.paddingRight||0,M.paddingBottom=O.paddingBottom||0,M.paddingTop=O.paddingTop||0,T.idToDummyNode[R]=M;var B=T.getGraphManager().add(T.newGraph(),M),F=O.getChild();F.add(M);for(var P=0;P<E[L].length;P++){var z=E[L][P];F.remove(z),B.add(z)}}})},w.prototype.clearCompounds=function(){var T={},E={};this.performDFSOnCompounds();for(var A=0;A<this.compoundOrder.length;A++)E[this.compoundOrder[A].id]=this.compoundOrder[A],T[this.compoundOrder[A].id]=[].concat(this.compoundOrder[A].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[A].getChild()),this.compoundOrder[A].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(T,E)},w.prototype.clearZeroDegreeMembers=function(){var T=this,E=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(A){var S=T.idToDummyNode[A];E[A]=T.tileNodes(T.memberGroups[A],S.paddingLeft+S.paddingRight),S.rect.width=E[A].width,S.rect.height=E[A].height})},w.prototype.repopulateCompounds=function(){for(var T=this.compoundOrder.length-1;T>=0;T--){var E=this.compoundOrder[T],A=E.id,S=E.paddingLeft,_=E.paddingTop;this.adjustLocations(this.tiledMemberPack[A],E.rect.x,E.rect.y,S,_)}},w.prototype.repopulateZeroDegreeMembers=function(){var T=this,E=this.tiledZeroDegreePack;Object.keys(E).forEach(function(A){var S=T.idToDummyNode[A],_=S.paddingLeft,I=S.paddingTop;T.adjustLocations(E[A],S.rect.x,S.rect.y,_,I)})},w.prototype.getToBeTiled=function(T){var E=T.id;if(this.toBeTiled[E]!=null)return this.toBeTiled[E];var A=T.getChild();if(A==null)return this.toBeTiled[E]=!1,!1;for(var S=A.getNodes(),_=0;_<S.length;_++){var I=S[_];if(this.getNodeDegree(I)>0)return this.toBeTiled[E]=!1,!1;if(I.getChild()==null){this.toBeTiled[I.id]=!1;continue}if(!this.getToBeTiled(I))return this.toBeTiled[E]=!1,!1}return this.toBeTiled[E]=!0,!0},w.prototype.getNodeDegree=function(T){for(var E=T.id,A=T.getEdges(),S=0,_=0;_<A.length;_++){var I=A[_];I.getSource().id!==I.getTarget().id&&(S=S+1)}return S},w.prototype.getNodeDegreeWithChildren=function(T){var E=this.getNodeDegree(T);if(T.getChild()==null)return E;for(var A=T.getChild().getNodes(),S=0;S<A.length;S++){var _=A[S];E+=this.getNodeDegreeWithChildren(_)}return E},w.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},w.prototype.fillCompexOrderByDFS=function(T){for(var E=0;E<T.length;E++){var A=T[E];A.getChild()!=null&&this.fillCompexOrderByDFS(A.getChild().getNodes()),this.getToBeTiled(A)&&this.compoundOrder.push(A)}},w.prototype.adjustLocations=function(T,E,A,S,_){E+=S,A+=_;for(var I=E,D=0;D<T.rows.length;D++){var k=T.rows[D];E=I;for(var L=0,R=0;R<k.length;R++){var O=k[R];O.rect.x=E,O.rect.y=A,E+=O.rect.width+T.horizontalPadding,O.rect.height>L&&(L=O.rect.height)}A+=L+T.verticalPadding}},w.prototype.tileCompoundMembers=function(T,E){var A=this;this.tiledMemberPack=[],Object.keys(T).forEach(function(S){var _=E[S];A.tiledMemberPack[S]=A.tileNodes(T[S],_.paddingLeft+_.paddingRight),_.rect.width=A.tiledMemberPack[S].width,_.rect.height=A.tiledMemberPack[S].height})},w.prototype.tileNodes=function(T,E){var A=h.TILING_PADDING_VERTICAL,S=h.TILING_PADDING_HORIZONTAL,_={rows:[],rowWidth:[],rowHeight:[],width:0,height:E,verticalPadding:A,horizontalPadding:S};T.sort(function(k,L){return k.rect.width*k.rect.height>L.rect.width*L.rect.height?-1:k.rect.width*k.rect.height<L.rect.width*L.rect.height?1:0});for(var I=0;I<T.length;I++){var D=T[I];_.rows.length==0?this.insertNodeToRow(_,D,0,E):this.canAddHorizontal(_,D.rect.width,D.rect.height)?this.insertNodeToRow(_,D,this.getShortestRowIndex(_),E):this.insertNodeToRow(_,D,_.rows.length,E),this.shiftToLastRow(_)}return _},w.prototype.insertNodeToRow=function(T,E,A,S){var _=S;if(A==T.rows.length){var I=[];T.rows.push(I),T.rowWidth.push(_),T.rowHeight.push(0)}var D=T.rowWidth[A]+E.rect.width;T.rows[A].length>0&&(D+=T.horizontalPadding),T.rowWidth[A]=D,T.width<D&&(T.width=D);var k=E.rect.height;A>0&&(k+=T.verticalPadding);var L=0;k>T.rowHeight[A]&&(L=T.rowHeight[A],T.rowHeight[A]=k,L=T.rowHeight[A]-L),T.height+=L,T.rows[A].push(E)},w.prototype.getShortestRowIndex=function(T){for(var E=-1,A=Number.MAX_VALUE,S=0;S<T.rows.length;S++)T.rowWidth[S]<A&&(E=S,A=T.rowWidth[S]);return E},w.prototype.getLongestRowIndex=function(T){for(var E=-1,A=Number.MIN_VALUE,S=0;S<T.rows.length;S++)T.rowWidth[S]>A&&(E=S,A=T.rowWidth[S]);return E},w.prototype.canAddHorizontal=function(T,E,A){var S=this.getShortestRowIndex(T);if(S<0)return!0;var _=T.rowWidth[S];if(_+T.horizontalPadding+E<=T.width)return!0;var I=0;T.rowHeight[S]<A&&S>0&&(I=A+T.verticalPadding-T.rowHeight[S]);var D;T.width-_>=E+T.horizontalPadding?D=(T.height+I)/(_+E+T.horizontalPadding):D=(T.height+I)/T.width,I=A+T.verticalPadding;var k;return T.width<E?k=(T.height+I)/E:k=(T.height+I)/T.width,k<1&&(k=1/k),D<1&&(D=1/D),D<k},w.prototype.shiftToLastRow=function(T){var E=this.getLongestRowIndex(T),A=T.rowWidth.length-1,S=T.rows[E],_=S[S.length-1],I=_.width+T.horizontalPadding;if(T.width-T.rowWidth[A]>I&&E!=A){S.splice(-1,1),T.rows[A].push(_),T.rowWidth[E]=T.rowWidth[E]-I,T.rowWidth[A]=T.rowWidth[A]+I,T.width=T.rowWidth[instance.getLongestRowIndex(T)];for(var D=Number.MIN_VALUE,k=0;k<S.length;k++)S[k].height>D&&(D=S[k].height);E>0&&(D+=T.verticalPadding);var L=T.rowHeight[E]+T.rowHeight[A];T.rowHeight[E]=D,T.rowHeight[A]<_.height+T.verticalPadding&&(T.rowHeight[A]=_.height+T.verticalPadding);var R=T.rowHeight[E]+T.rowHeight[A];T.height+=R-L,this.shiftToLastRow(T)}},w.prototype.tilingPreLayout=function(){h.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},w.prototype.tilingPostLayout=function(){h.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},w.prototype.reduceTrees=function(){for(var T=[],E=!0,A;E;){var S=this.graphManager.getAllNodes(),_=[];E=!1;for(var I=0;I<S.length;I++)A=S[I],A.getEdges().length==1&&!A.getEdges()[0].isInterGraph&&A.getChild()==null&&(_.push([A,A.getEdges()[0],A.getOwner()]),E=!0);if(E==!0){for(var D=[],k=0;k<_.length;k++)_[k][0].getEdges().length==1&&(D.push(_[k]),_[k][0].getOwner().remove(_[k][0]));T.push(D),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=T},w.prototype.growTree=function(T){for(var E=T.length,A=T[E-1],S,_=0;_<A.length;_++)S=A[_],this.findPlaceforPrunedNode(S),S[2].add(S[0]),S[2].add(S[1],S[1].source,S[1].target);T.splice(T.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},w.prototype.findPlaceforPrunedNode=function(T){var E,A,S=T[0];S==T[1].source?A=T[1].target:A=T[1].source;var _=A.startX,I=A.finishX,D=A.startY,k=A.finishY,L=0,R=0,O=0,M=0,B=[L,O,R,M];if(D>0)for(var F=_;F<=I;F++)B[0]+=this.grid[F][D-1].length+this.grid[F][D].length-1;if(I<this.grid.length-1)for(var F=D;F<=k;F++)B[1]+=this.grid[I+1][F].length+this.grid[I][F].length-1;if(k<this.grid[0].length-1)for(var F=_;F<=I;F++)B[2]+=this.grid[F][k+1].length+this.grid[F][k].length-1;if(_>0)for(var F=D;F<=k;F++)B[3]+=this.grid[_-1][F].length+this.grid[_][F].length-1;for(var P=y.MAX_VALUE,z,$,H=0;H<B.length;H++)B[H]<P?(P=B[H],z=1,$=H):B[H]==P&&z++;if(z==3&&P==0)B[0]==0&&B[1]==0&&B[2]==0?E=1:B[0]==0&&B[1]==0&&B[3]==0?E=0:B[0]==0&&B[2]==0&&B[3]==0?E=3:B[1]==0&&B[2]==0&&B[3]==0&&(E=2);else if(z==2&&P==0){var Q=Math.floor(Math.random()*2);B[0]==0&&B[1]==0?Q==0?E=0:E=1:B[0]==0&&B[2]==0?Q==0?E=0:E=2:B[0]==0&&B[3]==0?Q==0?E=0:E=3:B[1]==0&&B[2]==0?Q==0?E=1:E=2:B[1]==0&&B[3]==0?Q==0?E=1:E=3:Q==0?E=2:E=3}else if(z==4&&P==0){var Q=Math.floor(Math.random()*4);E=Q}else E=$;E==0?S.setCenter(A.getCenterX(),A.getCenterY()-A.getHeight()/2-f.DEFAULT_EDGE_LENGTH-S.getHeight()/2):E==1?S.setCenter(A.getCenterX()+A.getWidth()/2+f.DEFAULT_EDGE_LENGTH+S.getWidth()/2,A.getCenterY()):E==2?S.setCenter(A.getCenterX(),A.getCenterY()+A.getHeight()/2+f.DEFAULT_EDGE_LENGTH+S.getHeight()/2):S.setCenter(A.getCenterX()-A.getWidth()/2-f.DEFAULT_EDGE_LENGTH-S.getWidth()/2,A.getCenterY())},e.exports=w},function(e,r,n){"use strict";var i={};i.layoutBase=n(0),i.CoSEConstants=n(1),i.CoSEEdge=n(2),i.CoSEGraph=n(3),i.CoSEGraphManager=n(4),i.CoSELayout=n(6),i.CoSENode=n(5),e.exports=i}])})});var Gge=Mi((f4,_B)=>{"use strict";o(function(e,r){typeof f4=="object"&&typeof _B=="object"?_B.exports=r(AB()):typeof define=="function"&&define.amd?define(["cose-base"],r):typeof f4=="object"?f4.cytoscapeCoseBilkent=r(AB()):e.cytoscapeCoseBilkent=r(e.coseBase)},"webpackUniversalModuleDefinition")(f4,function(t){return function(e){var r={};function n(i){if(r[i])return r[i].exports;var a=r[i]={i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return o(n,"__webpack_require__"),n.m=e,n.c=r,n.i=function(i){return i},n.d=function(i,a,s){n.o(i,a)||Object.defineProperty(i,a,{configurable:!1,enumerable:!0,get:s})},n.n=function(i){var a=i&&i.__esModule?o(function(){return i.default},"getDefault"):o(function(){return i},"getModuleExports");return n.d(a,"a",a),a},n.o=function(i,a){return Object.prototype.hasOwnProperty.call(i,a)},n.p="",n(n.s=1)}([function(e,r){e.exports=t},function(e,r,n){"use strict";var i=n(0).layoutBase.LayoutConstants,a=n(0).layoutBase.FDLayoutConstants,s=n(0).CoSEConstants,l=n(0).CoSELayout,u=n(0).CoSENode,h=n(0).layoutBase.PointD,f=n(0).layoutBase.DimensionD,d={ready:o(function(){},"ready"),stop:o(function(){},"stop"),quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function p(v,x){var b={};for(var w in v)b[w]=v[w];for(var w in x)b[w]=x[w];return b}o(p,"extend");function m(v){this.options=p(d,v),g(this.options)}o(m,"_CoSELayout");var g=o(function(x){x.nodeRepulsion!=null&&(s.DEFAULT_REPULSION_STRENGTH=a.DEFAULT_REPULSION_STRENGTH=x.nodeRepulsion),x.idealEdgeLength!=null&&(s.DEFAULT_EDGE_LENGTH=a.DEFAULT_EDGE_LENGTH=x.idealEdgeLength),x.edgeElasticity!=null&&(s.DEFAULT_SPRING_STRENGTH=a.DEFAULT_SPRING_STRENGTH=x.edgeElasticity),x.nestingFactor!=null&&(s.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=x.nestingFactor),x.gravity!=null&&(s.DEFAULT_GRAVITY_STRENGTH=a.DEFAULT_GRAVITY_STRENGTH=x.gravity),x.numIter!=null&&(s.MAX_ITERATIONS=a.MAX_ITERATIONS=x.numIter),x.gravityRange!=null&&(s.DEFAULT_GRAVITY_RANGE_FACTOR=a.DEFAULT_GRAVITY_RANGE_FACTOR=x.gravityRange),x.gravityCompound!=null&&(s.DEFAULT_COMPOUND_GRAVITY_STRENGTH=a.DEFAULT_COMPOUND_GRAVITY_STRENGTH=x.gravityCompound),x.gravityRangeCompound!=null&&(s.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=x.gravityRangeCompound),x.initialEnergyOnIncremental!=null&&(s.DEFAULT_COOLING_FACTOR_INCREMENTAL=a.DEFAULT_COOLING_FACTOR_INCREMENTAL=x.initialEnergyOnIncremental),x.quality=="draft"?i.QUALITY=0:x.quality=="proof"?i.QUALITY=2:i.QUALITY=1,s.NODE_DIMENSIONS_INCLUDE_LABELS=a.NODE_DIMENSIONS_INCLUDE_LABELS=i.NODE_DIMENSIONS_INCLUDE_LABELS=x.nodeDimensionsIncludeLabels,s.DEFAULT_INCREMENTAL=a.DEFAULT_INCREMENTAL=i.DEFAULT_INCREMENTAL=!x.randomize,s.ANIMATE=a.ANIMATE=i.ANIMATE=x.animate,s.TILE=x.tile,s.TILING_PADDING_VERTICAL=typeof x.tilingPaddingVertical=="function"?x.tilingPaddingVertical.call():x.tilingPaddingVertical,s.TILING_PADDING_HORIZONTAL=typeof x.tilingPaddingHorizontal=="function"?x.tilingPaddingHorizontal.call():x.tilingPaddingHorizontal},"getUserOptions");m.prototype.run=function(){var v,x,b=this.options,w=this.idToLNode={},C=this.layout=new l,T=this;T.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var E=C.newGraphManager();this.gm=E;var A=this.options.eles.nodes(),S=this.options.eles.edges();this.root=E.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(A),C);for(var _=0;_<S.length;_++){var I=S[_],D=this.idToLNode[I.data("source")],k=this.idToLNode[I.data("target")];if(D!==k&&D.getEdgesBetween(k).length==0){var L=E.add(C.newEdge(),D,k);L.id=I.id()}}var R=o(function(B,F){typeof B=="number"&&(B=F);var P=B.data("id"),z=T.idToLNode[P];return{x:z.getRect().getCenterX(),y:z.getRect().getCenterY()}},"getPositions"),O=o(function M(){for(var B=o(function(){b.fit&&b.cy.fit(b.eles,b.padding),v||(v=!0,T.cy.one("layoutready",b.ready),T.cy.trigger({type:"layoutready",layout:T}))},"afterReposition"),F=T.options.refresh,P,z=0;z<F&&!P;z++)P=T.stopped||T.layout.tick();if(P){C.checkLayoutSuccess()&&!C.isSubLayout&&C.doPostLayout(),C.tilingPostLayout&&C.tilingPostLayout(),C.isLayoutFinished=!0,T.options.eles.nodes().positions(R),B(),T.cy.one("layoutstop",T.options.stop),T.cy.trigger({type:"layoutstop",layout:T}),x&&cancelAnimationFrame(x),v=!1;return}var $=T.layout.getPositionsData();b.eles.nodes().positions(function(H,Q){if(typeof H=="number"&&(H=Q),!H.isParent()){for(var j=H.id(),ie=$[j],ne=H;ie==null&&(ie=$[ne.data("parent")]||$["DummyCompound_"+ne.data("parent")],$[j]=ie,ne=ne.parent()[0],ne!=null););return ie!=null?{x:ie.x,y:ie.y}:{x:H.position("x"),y:H.position("y")}}}),B(),x=requestAnimationFrame(M)},"iterateAnimated");return C.addListener("layoutstarted",function(){T.options.animate==="during"&&(x=requestAnimationFrame(O))}),C.runLayout(),this.options.animate!=="during"&&(T.options.eles.nodes().not(":parent").layoutPositions(T,T.options,R),v=!1),this},m.prototype.getTopMostNodes=function(v){for(var x={},b=0;b<v.length;b++)x[v[b].id()]=!0;var w=v.filter(function(C,T){typeof C=="number"&&(C=T);for(var E=C.parent()[0];E!=null;){if(x[E.id()])return!1;E=E.parent()[0]}return!0});return w},m.prototype.processChildrenList=function(v,x,b){for(var w=x.length,C=0;C<w;C++){var T=x[C],E=T.children(),A,S=T.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if(T.outerWidth()!=null&&T.outerHeight()!=null?A=v.add(new u(b.graphManager,new h(T.position("x")-S.w/2,T.position("y")-S.h/2),new f(parseFloat(S.w),parseFloat(S.h)))):A=v.add(new u(this.graphManager)),A.id=T.data("id"),A.paddingLeft=parseInt(T.css("padding")),A.paddingTop=parseInt(T.css("padding")),A.paddingRight=parseInt(T.css("padding")),A.paddingBottom=parseInt(T.css("padding")),this.options.nodeDimensionsIncludeLabels&&T.isParent()){var _=T.boundingBox({includeLabels:!0,includeNodes:!1}).w,I=T.boundingBox({includeLabels:!0,includeNodes:!1}).h,D=T.css("text-halign");A.labelWidth=_,A.labelHeight=I,A.labelPos=D}if(this.idToLNode[T.data("id")]=A,isNaN(A.rect.x)&&(A.rect.x=0),isNaN(A.rect.y)&&(A.rect.y=0),E!=null&&E.length>0){var k;k=b.getGraphManager().add(b.newGraph(),A),this.processChildrenList(k,E,b)}}},m.prototype.stop=function(){return this.stopped=!0,this};var y=o(function(x){x("layout","cose-bilkent",m)},"register");typeof cytoscape<"u"&&y(cytoscape),e.exports=y}])})});function JZe(t,e,r,n,i){return t.insert("polygon",":first-child").attr("points",n.map(function(a){return a.x+","+a.y}).join(" ")).attr("transform","translate("+(i.width-e)/2+", "+r+")")}var YZe,XZe,jZe,KZe,QZe,ZZe,eJe,tJe,Vge,Uge,Hge=N(()=>{"use strict";to();ir();YZe=12,XZe=o(function(t,e,r,n){e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 ${r.height-5} v${-r.height+2*5} q0,-5 5,-5 h${r.width-2*5} q5,0 5,5 v${r.height-5} H0 Z`),e.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",r.height).attr("x2",r.width).attr("y2",r.height)},"defaultBkg"),jZe=o(function(t,e,r){e.append("rect").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("height",r.height).attr("width",r.width)},"rectBkg"),KZe=o(function(t,e,r){let n=r.width,i=r.height,a=.15*n,s=.25*n,l=.35*n,u=.2*n;e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 0 a${a},${a} 0 0,1 ${n*.25},${-1*n*.1}
+ a${l},${l} 1 0,1 ${n*.4},${-1*n*.1}
+ a${s},${s} 1 0,1 ${n*.35},${1*n*.2}
+
+ a${a},${a} 1 0,1 ${n*.15},${1*i*.35}
+ a${u},${u} 1 0,1 ${-1*n*.15},${1*i*.65}
+
+ a${s},${a} 1 0,1 ${-1*n*.25},${n*.15}
+ a${l},${l} 1 0,1 ${-1*n*.5},0
+ a${a},${a} 1 0,1 ${-1*n*.25},${-1*n*.15}
+
+ a${a},${a} 1 0,1 ${-1*n*.1},${-1*i*.35}
+ a${u},${u} 1 0,1 ${n*.1},${-1*i*.65}
+
+ H0 V0 Z`)},"cloudBkg"),QZe=o(function(t,e,r){let n=r.width,i=r.height,a=.15*n;e.append("path").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("d",`M0 0 a${a},${a} 1 0,0 ${n*.25},${-1*i*.1}
+ a${a},${a} 1 0,0 ${n*.25},0
+ a${a},${a} 1 0,0 ${n*.25},0
+ a${a},${a} 1 0,0 ${n*.25},${1*i*.1}
+
+ a${a},${a} 1 0,0 ${n*.15},${1*i*.33}
+ a${a*.8},${a*.8} 1 0,0 0,${1*i*.34}
+ a${a},${a} 1 0,0 ${-1*n*.15},${1*i*.33}
+
+ a${a},${a} 1 0,0 ${-1*n*.25},${i*.15}
+ a${a},${a} 1 0,0 ${-1*n*.25},0
+ a${a},${a} 1 0,0 ${-1*n*.25},0
+ a${a},${a} 1 0,0 ${-1*n*.25},${-1*i*.15}
+
+ a${a},${a} 1 0,0 ${-1*n*.1},${-1*i*.33}
+ a${a*.8},${a*.8} 1 0,0 0,${-1*i*.34}
+ a${a},${a} 1 0,0 ${n*.1},${-1*i*.33}
+
+ H0 V0 Z`)},"bangBkg"),ZZe=o(function(t,e,r){e.append("circle").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("r",r.width/2)},"circleBkg");o(JZe,"insertPolygonShape");eJe=o(function(t,e,r){let n=r.height,a=n/4,s=r.width-r.padding+2*a,l=[{x:a,y:0},{x:s-a,y:0},{x:s,y:-n/2},{x:s-a,y:-n},{x:a,y:-n},{x:0,y:-n/2}];JZe(e,s,n,l,r)},"hexagonBkg"),tJe=o(function(t,e,r){e.append("rect").attr("id","node-"+r.id).attr("class","node-bkg node-"+t.type2Str(r.type)).attr("height",r.height).attr("rx",r.padding).attr("ry",r.padding).attr("width",r.width)},"roundedRectBkg"),Vge=o(async function(t,e,r,n,i){let a=i.htmlLabels,s=n%(YZe-1),l=e.append("g");r.section=s;let u="section-"+s;s<0&&(u+=" section-root"),l.attr("class",(r.class?r.class+" ":"")+"mindmap-node "+u);let h=l.append("g"),f=l.append("g"),d=r.descr.replace(/(<br\/*>)/g,`
+`);await Hn(f,d,{useHtmlLabels:a,width:r.width,classes:"mindmap-node-label"},i),a||f.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");let p=f.node().getBBox(),[m]=Bo(i.fontSize);if(r.height=p.height+m*1.1*.5+r.padding,r.width=p.width+2*r.padding,r.icon)if(r.type===t.nodeType.CIRCLE)r.height+=50,r.width+=50,l.append("foreignObject").attr("height","50px").attr("width",r.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+s+" "+r.icon),f.attr("transform","translate("+r.width/2+", "+(r.height/2-1.5*r.padding)+")");else{r.width+=50;let g=r.height;r.height=Math.max(g,60);let y=Math.abs(r.height-g);l.append("foreignObject").attr("width","60px").attr("height",r.height).attr("style","text-align: center;margin-top:"+y/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+s+" "+r.icon),f.attr("transform","translate("+(25+r.width/2)+", "+(y/2+r.padding/2)+")")}else if(a){let g=(r.width-p.width)/2,y=(r.height-p.height)/2;f.attr("transform","translate("+g+", "+y+")")}else{let g=r.width/2,y=r.padding/2;f.attr("transform","translate("+g+", "+y+")")}switch(r.type){case t.nodeType.DEFAULT:XZe(t,h,r,s);break;case t.nodeType.ROUNDED_RECT:tJe(t,h,r,s);break;case t.nodeType.RECT:jZe(t,h,r,s);break;case t.nodeType.CIRCLE:h.attr("transform","translate("+r.width/2+", "+ +r.height/2+")"),ZZe(t,h,r,s);break;case t.nodeType.CLOUD:KZe(t,h,r,s);break;case t.nodeType.BANG:QZe(t,h,r,s);break;case t.nodeType.HEXAGON:eJe(t,h,r,s);break}return t.setElementForId(r.id,l),r.height},"drawNode"),Uge=o(function(t,e){let r=t.getElementById(e.id),n=e.x||0,i=e.y||0;r.attr("transform","translate("+n+","+i+")")},"positionNode")});async function qge(t,e,r,n,i){await Vge(t,e,r,n,i),r.children&&await Promise.all(r.children.map((a,s)=>qge(t,e,a,n<0?s:n,i)))}function rJe(t,e){e.edges().map((r,n)=>{let i=r.data();if(r[0]._private.bodyBounds){let a=r[0]._private.rscratch;Y.trace("Edge: ",n,i),t.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}})}function Yge(t,e,r,n){e.add({group:"nodes",data:{id:t.id.toString(),labelText:t.descr,height:t.height,width:t.width,level:n,nodeId:t.id,padding:t.padding,type:t.type},position:{x:t.x,y:t.y}}),t.children&&t.children.forEach(i=>{Yge(i,e,r,n+1),e.add({group:"edges",data:{id:`${t.id}_${i.id}`,source:t.id,target:i.id,depth:n,section:i.section}})})}function nJe(t,e){return new Promise(r=>{let n=Ge("body").append("div").attr("id","cy").attr("style","display:none"),i=rl({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});n.remove(),Yge(t,i,e,0),i.nodes().forEach(function(a){a.layoutDimensions=()=>{let s=a.data();return{w:s.width,h:s.height}}}),i.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),i.ready(a=>{Y.info("Ready",a),r(i)})})}function iJe(t,e){e.nodes().map((r,n)=>{let i=r.data();i.x=r.position().x,i.y=r.position().y,Uge(t,i);let a=t.getElementById(i.nodeId);Y.info("Id:",n,"Position: (",r.position().x,", ",r.position().y,")",i),a.attr("transform",`translate(${r.position().x-i.width/2}, ${r.position().y-i.height/2})`),a.attr("attr",`apa-${n})`)})}var Wge,aJe,Xge,jge=N(()=>{"use strict";kB();Wge=Sa(Gge(),1);dr();zt();vt();Vc();Ei();Hge();Ya();rl.use(Wge.default);o(qge,"drawNodes");o(rJe,"drawEdges");o(Yge,"addNodes");o(nJe,"layoutMindmap");o(iJe,"positionNodes");aJe=o(async(t,e,r,n)=>{Y.debug(`Rendering mindmap diagram
+`+t);let i=n.db,a=i.getMindmap();if(!a)return;let s=me();s.htmlLabels=!1;let l=sa(e),u=l.append("g");u.attr("class","mindmap-edges");let h=l.append("g");h.attr("class","mindmap-nodes"),await qge(i,h,a,-1,s);let f=await nJe(a,s);rJe(u,f),iJe(i,f),Ao(void 0,l,s.mindmap?.padding??or.mindmap.padding,s.mindmap?.useMaxWidth??or.mindmap.useMaxWidth)},"draw"),Xge={draw:aJe}});var sJe,oJe,Kge,Qge=N(()=>{"use strict";Ys();sJe=o(t=>{let e="";for(let r=0;r<t.THEME_COLOR_LIMIT;r++)t["lineColor"+r]=t["lineColor"+r]||t["cScaleInv"+r],ca(t["lineColor"+r])?t["lineColor"+r]=Dt(t["lineColor"+r],20):t["lineColor"+r]=Ot(t["lineColor"+r],20);for(let r=0;r<t.THEME_COLOR_LIMIT;r++){let n=""+(17-3*r);e+=`
+ .section-${r-1} rect, .section-${r-1} path, .section-${r-1} circle, .section-${r-1} polygon, .section-${r-1} path {
+ fill: ${t["cScale"+r]};
+ }
+ .section-${r-1} text {
+ fill: ${t["cScaleLabel"+r]};
+ }
+ .node-icon-${r-1} {
+ font-size: 40px;
+ color: ${t["cScaleLabel"+r]};
+ }
+ .section-edge-${r-1}{
+ stroke: ${t["cScale"+r]};
+ }
+ .edge-depth-${r-1}{
+ stroke-width: ${n};
+ }
+ .section-${r-1} line {
+ stroke: ${t["cScaleInv"+r]} ;
+ stroke-width: 3;
+ }
+
+ .disabled, .disabled circle, .disabled text {
+ fill: lightgray;
+ }
+ .disabled text {
+ fill: #efefef;
+ }
+ `}return e},"genSections"),oJe=o(t=>`
+ .edge {
+ stroke-width: 3;
+ }
+ ${sJe(t)}
+ .section-root rect, .section-root path, .section-root circle, .section-root polygon {
+ fill: ${t.git0};
+ }
+ .section-root text {
+ fill: ${t.gitBranchLabel0};
+ }
+ .icon-container {
+ height:100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ .edge {
+ fill: none;
+ }
+ .mindmap-node-label {
+ dy: 1em;
+ alignment-baseline: middle;
+ text-anchor: middle;
+ dominant-baseline: middle;
+ text-align: center;
+ }
+`,"getStyles"),Kge=oJe});var Zge={};hr(Zge,{diagram:()=>lJe});var lJe,Jge=N(()=>{"use strict";Spe();_pe();jge();Qge();lJe={db:Ape,renderer:Xge,parser:Epe,styles:Kge}});var DB,r1e,n1e=N(()=>{"use strict";DB=function(){var t=o(function(A,S,_,I){for(_=_||{},I=A.length;I--;_[A[I]]=S);return _},"o"),e=[1,4],r=[1,13],n=[1,12],i=[1,15],a=[1,16],s=[1,20],l=[1,19],u=[6,7,8],h=[1,26],f=[1,24],d=[1,25],p=[6,7,11],m=[1,31],g=[6,7,11,24],y=[1,6,13,16,17,20,23],v=[1,35],x=[1,36],b=[1,6,7,11,13,16,17,20,23],w=[1,38],C={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:o(function(S,_,I,D,k,L,R){var O=L.length-1;switch(k){case 6:case 7:return D;case 8:D.getLogger().trace("Stop NL ");break;case 9:D.getLogger().trace("Stop EOF ");break;case 11:D.getLogger().trace("Stop NL2 ");break;case 12:D.getLogger().trace("Stop EOF2 ");break;case 15:D.getLogger().info("Node: ",L[O-1].id),D.addNode(L[O-2].length,L[O-1].id,L[O-1].descr,L[O-1].type,L[O]);break;case 16:D.getLogger().info("Node: ",L[O].id),D.addNode(L[O-1].length,L[O].id,L[O].descr,L[O].type);break;case 17:D.getLogger().trace("Icon: ",L[O]),D.decorateNode({icon:L[O]});break;case 18:case 23:D.decorateNode({class:L[O]});break;case 19:D.getLogger().trace("SPACELIST");break;case 20:D.getLogger().trace("Node: ",L[O-1].id),D.addNode(0,L[O-1].id,L[O-1].descr,L[O-1].type,L[O]);break;case 21:D.getLogger().trace("Node: ",L[O].id),D.addNode(0,L[O].id,L[O].descr,L[O].type);break;case 22:D.decorateNode({icon:L[O]});break;case 27:D.getLogger().trace("node found ..",L[O-2]),this.$={id:L[O-1],descr:L[O-1],type:D.getType(L[O-2],L[O])};break;case 28:this.$={id:L[O],descr:L[O],type:0};break;case 29:D.getLogger().trace("node found ..",L[O-3]),this.$={id:L[O-3],descr:L[O-1],type:D.getType(L[O-2],L[O])};break;case 30:this.$=L[O-1]+L[O];break;case 31:this.$=L[O];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:r,7:[1,10],9:9,12:11,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},t(u,[2,3]),{1:[2,2]},t(u,[2,4]),t(u,[2,5]),{1:[2,6],6:r,12:21,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},{6:r,9:22,12:11,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},{6:h,7:f,10:23,11:d},t(p,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:s,23:l}),t(p,[2,19]),t(p,[2,21],{15:30,24:m}),t(p,[2,22]),t(p,[2,23]),t(g,[2,25]),t(g,[2,26]),t(g,[2,28],{20:[1,32]}),{21:[1,33]},{6:h,7:f,10:34,11:d},{1:[2,7],6:r,12:21,13:n,14:14,16:i,17:a,18:17,19:18,20:s,23:l},t(y,[2,14],{7:v,11:x}),t(b,[2,8]),t(b,[2,9]),t(b,[2,10]),t(p,[2,16],{15:37,24:m}),t(p,[2,17]),t(p,[2,18]),t(p,[2,20],{24:w}),t(g,[2,31]),{21:[1,39]},{22:[1,40]},t(y,[2,13],{7:v,11:x}),t(b,[2,11]),t(b,[2,12]),t(p,[2,15],{24:w}),t(g,[2,30]),{22:[1,41]},t(g,[2,27]),t(g,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(S,_){if(_.recoverable)this.trace(S);else{var I=new Error(S);throw I.hash=_,I}},"parseError"),parse:o(function(S){var _=this,I=[0],D=[],k=[null],L=[],R=this.table,O="",M=0,B=0,F=0,P=2,z=1,$=L.slice.call(arguments,1),H=Object.create(this.lexer),Q={yy:{}};for(var j in this.yy)Object.prototype.hasOwnProperty.call(this.yy,j)&&(Q.yy[j]=this.yy[j]);H.setInput(S,Q.yy),Q.yy.lexer=H,Q.yy.parser=this,typeof H.yylloc>"u"&&(H.yylloc={});var ie=H.yylloc;L.push(ie);var ne=H.options&&H.options.ranges;typeof Q.yy.parseError=="function"?this.parseError=Q.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function le(ze){I.length=I.length-2*ze,k.length=k.length-ze,L.length=L.length-ze}o(le,"popStack");function he(){var ze;return ze=D.pop()||H.lex()||z,typeof ze!="number"&&(ze instanceof Array&&(D=ze,ze=D.pop()),ze=_.symbols_[ze]||ze),ze}o(he,"lex");for(var K,X,te,J,se,ue,Z={},Se,ce,ae,Oe;;){if(te=I[I.length-1],this.defaultActions[te]?J=this.defaultActions[te]:((K===null||typeof K>"u")&&(K=he()),J=R[te]&&R[te][K]),typeof J>"u"||!J.length||!J[0]){var ge="";Oe=[];for(Se in R[te])this.terminals_[Se]&&Se>P&&Oe.push("'"+this.terminals_[Se]+"'");H.showPosition?ge="Parse error on line "+(M+1)+`:
+`+H.showPosition()+`
+Expecting `+Oe.join(", ")+", got '"+(this.terminals_[K]||K)+"'":ge="Parse error on line "+(M+1)+": Unexpected "+(K==z?"end of input":"'"+(this.terminals_[K]||K)+"'"),this.parseError(ge,{text:H.match,token:this.terminals_[K]||K,line:H.yylineno,loc:ie,expected:Oe})}if(J[0]instanceof Array&&J.length>1)throw new Error("Parse Error: multiple actions possible at state: "+te+", token: "+K);switch(J[0]){case 1:I.push(K),k.push(H.yytext),L.push(H.yylloc),I.push(J[1]),K=null,X?(K=X,X=null):(B=H.yyleng,O=H.yytext,M=H.yylineno,ie=H.yylloc,F>0&&F--);break;case 2:if(ce=this.productions_[J[1]][1],Z.$=k[k.length-ce],Z._$={first_line:L[L.length-(ce||1)].first_line,last_line:L[L.length-1].last_line,first_column:L[L.length-(ce||1)].first_column,last_column:L[L.length-1].last_column},ne&&(Z._$.range=[L[L.length-(ce||1)].range[0],L[L.length-1].range[1]]),ue=this.performAction.apply(Z,[O,B,M,Q.yy,J[1],k,L].concat($)),typeof ue<"u")return ue;ce&&(I=I.slice(0,-1*ce*2),k=k.slice(0,-1*ce),L=L.slice(0,-1*ce)),I.push(this.productions_[J[1]][0]),k.push(Z.$),L.push(Z._$),ae=R[I[I.length-2]][I[I.length-1]],I.push(ae);break;case 3:return!0}}return!0},"parse")},T=function(){var A={EOF:1,parseError:o(function(_,I){if(this.yy.parser)this.yy.parser.parseError(_,I);else throw new Error(_)},"parseError"),setInput:o(function(S,_){return this.yy=_||this.yy||{},this._input=S,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var S=this._input[0];this.yytext+=S,this.yyleng++,this.offset++,this.match+=S,this.matched+=S;var _=S.match(/(?:\r\n?|\n).*/g);return _?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),S},"input"),unput:o(function(S){var _=S.length,I=S.split(/(?:\r\n?|\n)/g);this._input=S+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-_),this.offset-=_;var D=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),I.length-1&&(this.yylineno-=I.length-1);var k=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:I?(I.length===D.length?this.yylloc.first_column:0)+D[D.length-I.length].length-I[0].length:this.yylloc.first_column-_},this.options.ranges&&(this.yylloc.range=[k[0],k[0]+this.yyleng-_]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(S){this.unput(this.match.slice(S))},"less"),pastInput:o(function(){var S=this.matched.substr(0,this.matched.length-this.match.length);return(S.length>20?"...":"")+S.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var S=this.match;return S.length<20&&(S+=this._input.substr(0,20-S.length)),(S.substr(0,20)+(S.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var S=this.pastInput(),_=new Array(S.length+1).join("-");return S+this.upcomingInput()+`
+`+_+"^"},"showPosition"),test_match:o(function(S,_){var I,D,k;if(this.options.backtrack_lexer&&(k={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(k.yylloc.range=this.yylloc.range.slice(0))),D=S[0].match(/(?:\r\n?|\n).*/g),D&&(this.yylineno+=D.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:D?D[D.length-1].length-D[D.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+S[0].length},this.yytext+=S[0],this.match+=S[0],this.matches=S,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(S[0].length),this.matched+=S[0],I=this.performAction.call(this,this.yy,this,_,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),I)return I;if(this._backtrack){for(var L in k)this[L]=k[L];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var S,_,I,D;this._more||(this.yytext="",this.match="");for(var k=this._currentRules(),L=0;L<k.length;L++)if(I=this._input.match(this.rules[k[L]]),I&&(!_||I[0].length>_[0].length)){if(_=I,D=L,this.options.backtrack_lexer){if(S=this.test_match(I,k[L]),S!==!1)return S;if(this._backtrack){_=!1;continue}else return!1}else if(!this.options.flex)break}return _?(S=this.test_match(_,k[D]),S!==!1?S:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var _=this.next();return _||this.lex()},"lex"),begin:o(function(_){this.conditionStack.push(_)},"begin"),popState:o(function(){var _=this.conditionStack.length-1;return _>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(_){return _=this.conditionStack.length-1-Math.abs(_||0),_>=0?this.conditionStack[_]:"INITIAL"},"topState"),pushState:o(function(_){this.begin(_)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(_,I,D,k){var L=k;switch(D){case 0:return this.pushState("shapeData"),I.yytext="",24;break;case 1:return this.pushState("shapeDataStr"),24;break;case 2:return this.popState(),24;break;case 3:let R=/\n\s*/g;return I.yytext=I.yytext.replace(R,"<br/>"),24;break;case 4:return 24;case 5:this.popState();break;case 6:return _.getLogger().trace("Found comment",I.yytext),6;break;case 7:return 8;case 8:this.begin("CLASS");break;case 9:return this.popState(),17;break;case 10:this.popState();break;case 11:_.getLogger().trace("Begin icon"),this.begin("ICON");break;case 12:return _.getLogger().trace("SPACELINE"),6;break;case 13:return 7;case 14:return 16;case 15:_.getLogger().trace("end icon"),this.popState();break;case 16:return _.getLogger().trace("Exploding node"),this.begin("NODE"),20;break;case 17:return _.getLogger().trace("Cloud"),this.begin("NODE"),20;break;case 18:return _.getLogger().trace("Explosion Bang"),this.begin("NODE"),20;break;case 19:return _.getLogger().trace("Cloud Bang"),this.begin("NODE"),20;break;case 20:return this.begin("NODE"),20;break;case 21:return this.begin("NODE"),20;break;case 22:return this.begin("NODE"),20;break;case 23:return this.begin("NODE"),20;break;case 24:return 13;case 25:return 23;case 26:return 11;case 27:this.begin("NSTR2");break;case 28:return"NODE_DESCR";case 29:this.popState();break;case 30:_.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 31:return _.getLogger().trace("description:",I.yytext),"NODE_DESCR";break;case 32:this.popState();break;case 33:return this.popState(),_.getLogger().trace("node end ))"),"NODE_DEND";break;case 34:return this.popState(),_.getLogger().trace("node end )"),"NODE_DEND";break;case 35:return this.popState(),_.getLogger().trace("node end ...",I.yytext),"NODE_DEND";break;case 36:return this.popState(),_.getLogger().trace("node end (("),"NODE_DEND";break;case 37:return this.popState(),_.getLogger().trace("node end (-"),"NODE_DEND";break;case 38:return this.popState(),_.getLogger().trace("node end (-"),"NODE_DEND";break;case 39:return this.popState(),_.getLogger().trace("node end (("),"NODE_DEND";break;case 40:return this.popState(),_.getLogger().trace("node end (("),"NODE_DEND";break;case 41:return _.getLogger().trace("Long description:",I.yytext),21;break;case 42:return _.getLogger().trace("Long description:",I.yytext),21;break}},"anonymous"),rules:[/^(?:@\{)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^\"]+)/i,/^(?:[^}^"]+)/i,/^(?:\})/i,/^(?:\s*%%.*)/i,/^(?:kanban\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}@]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{shapeDataEndBracket:{rules:[],inclusive:!1},shapeDataStr:{rules:[2,3],inclusive:!1},shapeData:{rules:[1,4,5],inclusive:!1},CLASS:{rules:[9,10],inclusive:!1},ICON:{rules:[14,15],inclusive:!1},NSTR2:{rules:[28,29],inclusive:!1},NSTR:{rules:[31,32],inclusive:!1},NODE:{rules:[27,30,33,34,35,36,37,38,39,40,41,42],inclusive:!1},INITIAL:{rules:[0,6,7,8,11,12,13,16,17,18,19,20,21,22,23,24,25,26],inclusive:!0}}};return A}();C.lexer=T;function E(){this.yy={}}return o(E,"Parser"),E.prototype=C,C.Parser=E,new E}();DB.parser=DB;r1e=DB});var nl,RB,LB,NB,fJe,dJe,i1e,pJe,mJe,Yi,gJe,yJe,vJe,xJe,bJe,wJe,TJe,a1e,s1e=N(()=>{"use strict";zt();gr();vt();Ya();Ew();nl=[],RB=[],LB=0,NB={},fJe=o(()=>{nl=[],RB=[],LB=0,NB={}},"clear"),dJe=o(t=>{if(nl.length===0)return null;let e=nl[0].level,r=null;for(let n=nl.length-1;n>=0;n--)if(nl[n].level===e&&!r&&(r=nl[n]),nl[n].level<e)throw new Error('Items without section detected, found section ("'+nl[n].label+'")');return t===r?.level?null:r},"getSection"),i1e=o(function(){return RB},"getSections"),pJe=o(function(){let t=[],e=[],r=i1e(),n=me();for(let i of r){let a={id:i.id,label:Tr(i.label??"",n),isGroup:!0,ticket:i.ticket,shape:"kanbanSection",level:i.level,look:n.look};e.push(a);let s=nl.filter(l=>l.parentId===i.id);for(let l of s){let u={id:l.id,parentId:i.id,label:Tr(l.label??"",n),isGroup:!1,ticket:l?.ticket,priority:l?.priority,assigned:l?.assigned,icon:l?.icon,shape:"kanbanItem",level:l.level,rx:5,ry:5,cssStyles:["text-align: left"]};e.push(u)}}return{nodes:e,edges:t,other:{},config:me()}},"getData"),mJe=o((t,e,r,n,i)=>{let a=me(),s=a.mindmap?.padding??or.mindmap.padding;switch(n){case Yi.ROUNDED_RECT:case Yi.RECT:case Yi.HEXAGON:s*=2}let l={id:Tr(e,a)||"kbn"+LB++,level:t,label:Tr(r,a),width:a.mindmap?.maxNodeWidth??or.mindmap.maxNodeWidth,padding:s,isGroup:!1};if(i!==void 0){let h;i.includes(`
+`)?h=i+`
+`:h=`{
+`+i+`
+}`;let f=cm(h,{schema:lm});if(f.shape&&(f.shape!==f.shape.toLowerCase()||f.shape.includes("_")))throw new Error(`No such shape: ${f.shape}. Shape names should be lowercase.`);f?.shape&&f.shape==="kanbanItem"&&(l.shape=f?.shape),f?.label&&(l.label=f?.label),f?.icon&&(l.icon=f?.icon.toString()),f?.assigned&&(l.assigned=f?.assigned.toString()),f?.ticket&&(l.ticket=f?.ticket.toString()),f?.priority&&(l.priority=f?.priority)}let u=dJe(t);u?l.parentId=u.id||"kbn"+LB++:RB.push(l),nl.push(l)},"addNode"),Yi={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},gJe=o((t,e)=>{switch(Y.debug("In get type",t,e),t){case"[":return Yi.RECT;case"(":return e===")"?Yi.ROUNDED_RECT:Yi.CLOUD;case"((":return Yi.CIRCLE;case")":return Yi.CLOUD;case"))":return Yi.BANG;case"{{":return Yi.HEXAGON;default:return Yi.DEFAULT}},"getType"),yJe=o((t,e)=>{NB[t]=e},"setElementForId"),vJe=o(t=>{if(!t)return;let e=me(),r=nl[nl.length-1];t.icon&&(r.icon=Tr(t.icon,e)),t.class&&(r.cssClasses=Tr(t.class,e))},"decorateNode"),xJe=o(t=>{switch(t){case Yi.DEFAULT:return"no-border";case Yi.RECT:return"rect";case Yi.ROUNDED_RECT:return"rounded-rect";case Yi.CIRCLE:return"circle";case Yi.CLOUD:return"cloud";case Yi.BANG:return"bang";case Yi.HEXAGON:return"hexgon";default:return"no-border"}},"type2Str"),bJe=o(()=>Y,"getLogger"),wJe=o(t=>NB[t],"getElementById"),TJe={clear:fJe,addNode:mJe,getSections:i1e,getData:pJe,nodeType:Yi,getType:gJe,setElementForId:yJe,decorateNode:vJe,type2Str:xJe,getLogger:bJe,getElementById:wJe},a1e=TJe});var kJe,o1e,l1e=N(()=>{"use strict";zt();vt();Vc();Ei();Ya();Hw();eT();kJe=o(async(t,e,r,n)=>{Y.debug(`Rendering kanban diagram
+`+t);let a=n.db.getData(),s=me();s.htmlLabels=!1;let l=sa(e),u=l.append("g");u.attr("class","sections");let h=l.append("g");h.attr("class","items");let f=a.nodes.filter(v=>v.isGroup),d=0,p=10,m=[],g=25;for(let v of f){let x=s?.kanban?.sectionWidth||200;d=d+1,v.x=x*d+(d-1)*p/2,v.width=x,v.y=0,v.height=x*3,v.rx=5,v.ry=5,v.cssClasses=v.cssClasses+" section-"+d;let b=await ym(u,v);g=Math.max(g,b?.labelBBox?.height),m.push(b)}let y=0;for(let v of f){let x=m[y];y=y+1;let b=s?.kanban?.sectionWidth||200,w=-b*3/2+g,C=w,T=a.nodes.filter(S=>S.parentId===v.id);for(let S of T){if(S.isGroup)throw new Error("Groups within groups are not allowed in Kanban diagrams");S.x=v.x,S.width=b-1.5*p;let I=(await vm(h,S,{config:s})).node().getBBox();S.y=C+I.height/2,await k2(S),C=S.y+I.height/2+p/2}let E=x.cluster.select("rect"),A=Math.max(C-w+3*p,50)+(g-25);E.attr("height",A)}Ao(void 0,l,s.mindmap?.padding??or.kanban.padding,s.mindmap?.useMaxWidth??or.kanban.useMaxWidth)},"draw"),o1e={draw:kJe}});var EJe,SJe,c1e,u1e=N(()=>{"use strict";Ys();EJe=o(t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],ca(t["lineColor"+n])?t["lineColor"+n]=Dt(t["lineColor"+n],20):t["lineColor"+n]=Ot(t["lineColor"+n],20);let r=o((n,i)=>t.darkMode?Ot(n,i):Dt(n,i),"adjuster");for(let n=0;n<t.THEME_COLOR_LIMIT;n++){let i=""+(17-3*n);e+=`
+ .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} polygon, .section-${n-1} path {
+ fill: ${r(t["cScale"+n],10)};
+ stroke: ${r(t["cScale"+n],10)};
+
+ }
+ .section-${n-1} text {
+ fill: ${t["cScaleLabel"+n]};
+ }
+ .node-icon-${n-1} {
+ font-size: 40px;
+ color: ${t["cScaleLabel"+n]};
+ }
+ .section-edge-${n-1}{
+ stroke: ${t["cScale"+n]};
+ }
+ .edge-depth-${n-1}{
+ stroke-width: ${i};
+ }
+ .section-${n-1} line {
+ stroke: ${t["cScaleInv"+n]} ;
+ stroke-width: 3;
+ }
+
+ .disabled, .disabled circle, .disabled text {
+ fill: lightgray;
+ }
+ .disabled text {
+ fill: #efefef;
+ }
+
+ .node rect,
+ .node circle,
+ .node ellipse,
+ .node polygon,
+ .node path {
+ fill: ${t.background};
+ stroke: ${t.nodeBorder};
+ stroke-width: 1px;
+ }
+
+ .kanban-ticket-link {
+ fill: ${t.background};
+ stroke: ${t.nodeBorder};
+ text-decoration: underline;
+ }
+ `}return e},"genSections"),SJe=o(t=>`
+ .edge {
+ stroke-width: 3;
+ }
+ ${EJe(t)}
+ .section-root rect, .section-root path, .section-root circle, .section-root polygon {
+ fill: ${t.git0};
+ }
+ .section-root text {
+ fill: ${t.gitBranchLabel0};
+ }
+ .icon-container {
+ height:100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ .edge {
+ fill: none;
+ }
+ .cluster-label, .label {
+ color: ${t.textColor};
+ fill: ${t.textColor};
+ }
+ .kanban-label {
+ dy: 1em;
+ alignment-baseline: middle;
+ text-anchor: middle;
+ dominant-baseline: middle;
+ text-align: center;
+ }
+`,"getStyles"),c1e=SJe});var h1e={};hr(h1e,{diagram:()=>CJe});var CJe,f1e=N(()=>{"use strict";n1e();s1e();l1e();u1e();CJe={db:a1e,renderer:o1e,parser:r1e,styles:c1e}});var MB,d4,m1e=N(()=>{"use strict";MB=function(){var t=o(function(l,u,h,f){for(h=h||{},f=l.length;f--;h[l[f]]=u);return h},"o"),e=[1,9],r=[1,10],n=[1,5,10,12],i={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:o(function(u,h,f,d,p,m,g){var y=m.length-1;switch(p){case 7:let v=d.findOrCreateNode(m[y-4].trim().replaceAll('""','"')),x=d.findOrCreateNode(m[y-2].trim().replaceAll('""','"')),b=parseFloat(m[y].trim());d.addLink(v,x,b);break;case 8:case 9:case 11:this.$=m[y];break;case 10:this.$=m[y-1];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:e,20:r},{1:[2,6],7:11,10:[1,12]},t(r,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(n,[2,8]),t(n,[2,9]),{19:[1,16]},t(n,[2,11]),{1:[2,1]},{1:[2,5]},t(r,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:e,20:r},{15:18,16:7,17:8,18:e,20:r},{18:[1,19]},t(r,[2,3]),{12:[1,20]},t(n,[2,10]),{15:21,16:7,17:8,18:e,20:r},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:o(function(u,h){if(h.recoverable)this.trace(u);else{var f=new Error(u);throw f.hash=h,f}},"parseError"),parse:o(function(u){var h=this,f=[0],d=[],p=[null],m=[],g=this.table,y="",v=0,x=0,b=0,w=2,C=1,T=m.slice.call(arguments,1),E=Object.create(this.lexer),A={yy:{}};for(var S in this.yy)Object.prototype.hasOwnProperty.call(this.yy,S)&&(A.yy[S]=this.yy[S]);E.setInput(u,A.yy),A.yy.lexer=E,A.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var _=E.yylloc;m.push(_);var I=E.options&&E.options.ranges;typeof A.yy.parseError=="function"?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function D(ie){f.length=f.length-2*ie,p.length=p.length-ie,m.length=m.length-ie}o(D,"popStack");function k(){var ie;return ie=d.pop()||E.lex()||C,typeof ie!="number"&&(ie instanceof Array&&(d=ie,ie=d.pop()),ie=h.symbols_[ie]||ie),ie}o(k,"lex");for(var L,R,O,M,B,F,P={},z,$,H,Q;;){if(O=f[f.length-1],this.defaultActions[O]?M=this.defaultActions[O]:((L===null||typeof L>"u")&&(L=k()),M=g[O]&&g[O][L]),typeof M>"u"||!M.length||!M[0]){var j="";Q=[];for(z in g[O])this.terminals_[z]&&z>w&&Q.push("'"+this.terminals_[z]+"'");E.showPosition?j="Parse error on line "+(v+1)+`:
+`+E.showPosition()+`
+Expecting `+Q.join(", ")+", got '"+(this.terminals_[L]||L)+"'":j="Parse error on line "+(v+1)+": Unexpected "+(L==C?"end of input":"'"+(this.terminals_[L]||L)+"'"),this.parseError(j,{text:E.match,token:this.terminals_[L]||L,line:E.yylineno,loc:_,expected:Q})}if(M[0]instanceof Array&&M.length>1)throw new Error("Parse Error: multiple actions possible at state: "+O+", token: "+L);switch(M[0]){case 1:f.push(L),p.push(E.yytext),m.push(E.yylloc),f.push(M[1]),L=null,R?(L=R,R=null):(x=E.yyleng,y=E.yytext,v=E.yylineno,_=E.yylloc,b>0&&b--);break;case 2:if($=this.productions_[M[1]][1],P.$=p[p.length-$],P._$={first_line:m[m.length-($||1)].first_line,last_line:m[m.length-1].last_line,first_column:m[m.length-($||1)].first_column,last_column:m[m.length-1].last_column},I&&(P._$.range=[m[m.length-($||1)].range[0],m[m.length-1].range[1]]),F=this.performAction.apply(P,[y,x,v,A.yy,M[1],p,m].concat(T)),typeof F<"u")return F;$&&(f=f.slice(0,-1*$*2),p=p.slice(0,-1*$),m=m.slice(0,-1*$)),f.push(this.productions_[M[1]][0]),p.push(P.$),m.push(P._$),H=g[f[f.length-2]][f[f.length-1]],f.push(H);break;case 3:return!0}}return!0},"parse")},a=function(){var l={EOF:1,parseError:o(function(h,f){if(this.yy.parser)this.yy.parser.parseError(h,f);else throw new Error(h)},"parseError"),setInput:o(function(u,h){return this.yy=h||this.yy||{},this._input=u,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var u=this._input[0];this.yytext+=u,this.yyleng++,this.offset++,this.match+=u,this.matched+=u;var h=u.match(/(?:\r\n?|\n).*/g);return h?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),u},"input"),unput:o(function(u){var h=u.length,f=u.split(/(?:\r\n?|\n)/g);this._input=u+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-h),this.offset-=h;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),f.length-1&&(this.yylineno-=f.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:f?(f.length===d.length?this.yylloc.first_column:0)+d[d.length-f.length].length-f[0].length:this.yylloc.first_column-h},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-h]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(u){this.unput(this.match.slice(u))},"less"),pastInput:o(function(){var u=this.matched.substr(0,this.matched.length-this.match.length);return(u.length>20?"...":"")+u.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var u=this.match;return u.length<20&&(u+=this._input.substr(0,20-u.length)),(u.substr(0,20)+(u.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var u=this.pastInput(),h=new Array(u.length+1).join("-");return u+this.upcomingInput()+`
+`+h+"^"},"showPosition"),test_match:o(function(u,h){var f,d,p;if(this.options.backtrack_lexer&&(p={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(p.yylloc.range=this.yylloc.range.slice(0))),d=u[0].match(/(?:\r\n?|\n).*/g),d&&(this.yylineno+=d.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:d?d[d.length-1].length-d[d.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+u[0].length},this.yytext+=u[0],this.match+=u[0],this.matches=u,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(u[0].length),this.matched+=u[0],f=this.performAction.call(this,this.yy,this,h,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),f)return f;if(this._backtrack){for(var m in p)this[m]=p[m];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var u,h,f,d;this._more||(this.yytext="",this.match="");for(var p=this._currentRules(),m=0;m<p.length;m++)if(f=this._input.match(this.rules[p[m]]),f&&(!h||f[0].length>h[0].length)){if(h=f,d=m,this.options.backtrack_lexer){if(u=this.test_match(f,p[m]),u!==!1)return u;if(this._backtrack){h=!1;continue}else return!1}else if(!this.options.flex)break}return h?(u=this.test_match(h,p[d]),u!==!1?u:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var h=this.next();return h||this.lex()},"lex"),begin:o(function(h){this.conditionStack.push(h)},"begin"),popState:o(function(){var h=this.conditionStack.length-1;return h>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(h){return h=this.conditionStack.length-1-Math.abs(h||0),h>=0?this.conditionStack[h]:"INITIAL"},"topState"),pushState:o(function(h){this.begin(h)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{"case-insensitive":!0},performAction:o(function(h,f,d,p){var m=p;switch(d){case 0:return this.pushState("csv"),4;break;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;break;case 5:return 20;case 6:return this.popState("escaped_text"),18;break;case 7:return 19}},"anonymous"),rules:[/^(?:sankey-beta\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};return l}();i.lexer=a;function s(){this.yy={}}return o(s,"Parser"),s.prototype=i,i.Parser=s,new s}();MB.parser=MB;d4=MB});var XS,jS,YS,LJe,IB,RJe,OB,NJe,MJe,IJe,OJe,g1e,y1e=N(()=>{"use strict";zt();gr();mi();XS=[],jS=[],YS=new Map,LJe=o(()=>{XS=[],jS=[],YS=new Map,Ar()},"clear"),IB=class{constructor(e,r,n=0){this.source=e;this.target=r;this.value=n}static{o(this,"SankeyLink")}},RJe=o((t,e,r)=>{XS.push(new IB(t,e,r))},"addLink"),OB=class{constructor(e){this.ID=e}static{o(this,"SankeyNode")}},NJe=o(t=>{t=Ze.sanitizeText(t,me());let e=YS.get(t);return e===void 0&&(e=new OB(t),YS.set(t,e),jS.push(e)),e},"findOrCreateNode"),MJe=o(()=>jS,"getNodes"),IJe=o(()=>XS,"getLinks"),OJe=o(()=>({nodes:jS.map(t=>({id:t.ID})),links:XS.map(t=>({source:t.source.ID,target:t.target.ID,value:t.value}))}),"getGraph"),g1e={nodesMap:YS,getConfig:o(()=>me().sankey,"getConfig"),getNodes:MJe,getLinks:IJe,getGraph:OJe,addLink:RJe,findOrCreateNode:NJe,getAccTitle:Rr,setAccTitle:Lr,getAccDescription:Mr,setAccDescription:Nr,getDiagramTitle:Ir,setDiagramTitle:$r,clear:LJe}});function p4(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r<n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r<i||r===void 0&&i>=i)&&(r=i)}return r}var v1e=N(()=>{"use strict";o(p4,"max")});function cy(t,e){let r;if(e===void 0)for(let n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}var x1e=N(()=>{"use strict";o(cy,"min")});function uy(t,e){let r=0;if(e===void 0)for(let n of t)(n=+n)&&(r+=n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&(r+=i)}return r}var b1e=N(()=>{"use strict";o(uy,"sum")});var PB=N(()=>{"use strict";v1e();x1e();b1e()});function PJe(t){return t.target.depth}function BB(t){return t.depth}function FB(t,e){return e-1-t.height}function m4(t,e){return t.sourceLinks.length?t.depth:e-1}function $B(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?cy(t.sourceLinks,PJe)-1:0}var zB=N(()=>{"use strict";PB();o(PJe,"targetDepth");o(BB,"left");o(FB,"right");o(m4,"justify");o($B,"center")});function hy(t){return function(){return t}}var w1e=N(()=>{"use strict";o(hy,"constant")});function T1e(t,e){return KS(t.source,e.source)||t.index-e.index}function k1e(t,e){return KS(t.target,e.target)||t.index-e.index}function KS(t,e){return t.y0-e.y0}function GB(t){return t.value}function BJe(t){return t.index}function FJe(t){return t.nodes}function $Je(t){return t.links}function E1e(t,e){let r=t.get(e);if(!r)throw new Error("missing: "+e);return r}function S1e({nodes:t}){for(let e of t){let r=e.y0,n=r;for(let i of e.sourceLinks)i.y0=r+i.width/2,r+=i.width;for(let i of e.targetLinks)i.y1=n+i.width/2,n+=i.width}}function QS(){let t=0,e=0,r=1,n=1,i=24,a=8,s,l=BJe,u=m4,h,f,d=FJe,p=$Je,m=6;function g(){let O={nodes:d.apply(null,arguments),links:p.apply(null,arguments)};return y(O),v(O),x(O),b(O),T(O),S1e(O),O}o(g,"sankey"),g.update=function(O){return S1e(O),O},g.nodeId=function(O){return arguments.length?(l=typeof O=="function"?O:hy(O),g):l},g.nodeAlign=function(O){return arguments.length?(u=typeof O=="function"?O:hy(O),g):u},g.nodeSort=function(O){return arguments.length?(h=O,g):h},g.nodeWidth=function(O){return arguments.length?(i=+O,g):i},g.nodePadding=function(O){return arguments.length?(a=s=+O,g):a},g.nodes=function(O){return arguments.length?(d=typeof O=="function"?O:hy(O),g):d},g.links=function(O){return arguments.length?(p=typeof O=="function"?O:hy(O),g):p},g.linkSort=function(O){return arguments.length?(f=O,g):f},g.size=function(O){return arguments.length?(t=e=0,r=+O[0],n=+O[1],g):[r-t,n-e]},g.extent=function(O){return arguments.length?(t=+O[0][0],r=+O[1][0],e=+O[0][1],n=+O[1][1],g):[[t,e],[r,n]]},g.iterations=function(O){return arguments.length?(m=+O,g):m};function y({nodes:O,links:M}){for(let[F,P]of O.entries())P.index=F,P.sourceLinks=[],P.targetLinks=[];let B=new Map(O.map((F,P)=>[l(F,P,O),F]));for(let[F,P]of M.entries()){P.index=F;let{source:z,target:$}=P;typeof z!="object"&&(z=P.source=E1e(B,z)),typeof $!="object"&&($=P.target=E1e(B,$)),z.sourceLinks.push(P),$.targetLinks.push(P)}if(f!=null)for(let{sourceLinks:F,targetLinks:P}of O)F.sort(f),P.sort(f)}o(y,"computeNodeLinks");function v({nodes:O}){for(let M of O)M.value=M.fixedValue===void 0?Math.max(uy(M.sourceLinks,GB),uy(M.targetLinks,GB)):M.fixedValue}o(v,"computeNodeValues");function x({nodes:O}){let M=O.length,B=new Set(O),F=new Set,P=0;for(;B.size;){for(let z of B){z.depth=P;for(let{target:$}of z.sourceLinks)F.add($)}if(++P>M)throw new Error("circular link");B=F,F=new Set}}o(x,"computeNodeDepths");function b({nodes:O}){let M=O.length,B=new Set(O),F=new Set,P=0;for(;B.size;){for(let z of B){z.height=P;for(let{source:$}of z.targetLinks)F.add($)}if(++P>M)throw new Error("circular link");B=F,F=new Set}}o(b,"computeNodeHeights");function w({nodes:O}){let M=p4(O,P=>P.depth)+1,B=(r-t-i)/(M-1),F=new Array(M);for(let P of O){let z=Math.max(0,Math.min(M-1,Math.floor(u.call(null,P,M))));P.layer=z,P.x0=t+z*B,P.x1=P.x0+i,F[z]?F[z].push(P):F[z]=[P]}if(h)for(let P of F)P.sort(h);return F}o(w,"computeNodeLayers");function C(O){let M=cy(O,B=>(n-e-(B.length-1)*s)/uy(B,GB));for(let B of O){let F=e;for(let P of B){P.y0=F,P.y1=F+P.value*M,F=P.y1+s;for(let z of P.sourceLinks)z.width=z.value*M}F=(n-F+s)/(B.length+1);for(let P=0;P<B.length;++P){let z=B[P];z.y0+=F*(P+1),z.y1+=F*(P+1)}k(B)}}o(C,"initializeNodeBreadths");function T(O){let M=w(O);s=Math.min(a,(n-e)/(p4(M,B=>B.length)-1)),C(M);for(let B=0;B<m;++B){let F=Math.pow(.99,B),P=Math.max(1-F,(B+1)/m);A(M,F,P),E(M,F,P)}}o(T,"computeNodeBreadths");function E(O,M,B){for(let F=1,P=O.length;F<P;++F){let z=O[F];for(let $ of z){let H=0,Q=0;for(let{source:ie,value:ne}of $.targetLinks){let le=ne*($.layer-ie.layer);H+=L(ie,$)*le,Q+=le}if(!(Q>0))continue;let j=(H/Q-$.y0)*M;$.y0+=j,$.y1+=j,D($)}h===void 0&&z.sort(KS),S(z,B)}}o(E,"relaxLeftToRight");function A(O,M,B){for(let F=O.length,P=F-2;P>=0;--P){let z=O[P];for(let $ of z){let H=0,Q=0;for(let{target:ie,value:ne}of $.sourceLinks){let le=ne*(ie.layer-$.layer);H+=R($,ie)*le,Q+=le}if(!(Q>0))continue;let j=(H/Q-$.y0)*M;$.y0+=j,$.y1+=j,D($)}h===void 0&&z.sort(KS),S(z,B)}}o(A,"relaxRightToLeft");function S(O,M){let B=O.length>>1,F=O[B];I(O,F.y0-s,B-1,M),_(O,F.y1+s,B+1,M),I(O,n,O.length-1,M),_(O,e,0,M)}o(S,"resolveCollisions");function _(O,M,B,F){for(;B<O.length;++B){let P=O[B],z=(M-P.y0)*F;z>1e-6&&(P.y0+=z,P.y1+=z),M=P.y1+s}}o(_,"resolveCollisionsTopToBottom");function I(O,M,B,F){for(;B>=0;--B){let P=O[B],z=(P.y1-M)*F;z>1e-6&&(P.y0-=z,P.y1-=z),M=P.y0-s}}o(I,"resolveCollisionsBottomToTop");function D({sourceLinks:O,targetLinks:M}){if(f===void 0){for(let{source:{sourceLinks:B}}of M)B.sort(k1e);for(let{target:{targetLinks:B}}of O)B.sort(T1e)}}o(D,"reorderNodeLinks");function k(O){if(f===void 0)for(let{sourceLinks:M,targetLinks:B}of O)M.sort(k1e),B.sort(T1e)}o(k,"reorderLinks");function L(O,M){let B=O.y0-(O.sourceLinks.length-1)*s/2;for(let{target:F,width:P}of O.sourceLinks){if(F===M)break;B+=P+s}for(let{source:F,width:P}of M.targetLinks){if(F===O)break;B-=P}return B}o(L,"targetTop");function R(O,M){let B=M.y0-(M.targetLinks.length-1)*s/2;for(let{source:F,width:P}of M.targetLinks){if(F===O)break;B+=P+s}for(let{target:F,width:P}of O.sourceLinks){if(F===M)break;B-=P}return B}return o(R,"sourceTop"),g}var C1e=N(()=>{"use strict";PB();zB();w1e();o(T1e,"ascendingSourceBreadth");o(k1e,"ascendingTargetBreadth");o(KS,"ascendingBreadth");o(GB,"value");o(BJe,"defaultId");o(FJe,"defaultNodes");o($Je,"defaultLinks");o(E1e,"find");o(S1e,"computeLinkBreadths");o(QS,"Sankey")});function HB(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function A1e(){return new HB}var VB,UB,Xp,zJe,WB,_1e=N(()=>{"use strict";VB=Math.PI,UB=2*VB,Xp=1e-6,zJe=UB-Xp;o(HB,"Path");o(A1e,"path");HB.prototype=A1e.prototype={constructor:HB,moveTo:o(function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},"moveTo"),closePath:o(function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},"closePath"),lineTo:o(function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},"lineTo"),quadraticCurveTo:o(function(t,e,r,n){this._+="Q"+ +t+","+ +e+","+(this._x1=+r)+","+(this._y1=+n)},"quadraticCurveTo"),bezierCurveTo:o(function(t,e,r,n,i,a){this._+="C"+ +t+","+ +e+","+ +r+","+ +n+","+(this._x1=+i)+","+(this._y1=+a)},"bezierCurveTo"),arcTo:o(function(t,e,r,n,i){t=+t,e=+e,r=+r,n=+n,i=+i;var a=this._x1,s=this._y1,l=r-t,u=n-e,h=a-t,f=s-e,d=h*h+f*f;if(i<0)throw new Error("negative radius: "+i);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(d>Xp)if(!(Math.abs(f*l-u*h)>Xp)||!i)this._+="L"+(this._x1=t)+","+(this._y1=e);else{var p=r-a,m=n-s,g=l*l+u*u,y=p*p+m*m,v=Math.sqrt(g),x=Math.sqrt(d),b=i*Math.tan((VB-Math.acos((g+d-y)/(2*v*x)))/2),w=b/x,C=b/v;Math.abs(w-1)>Xp&&(this._+="L"+(t+w*h)+","+(e+w*f)),this._+="A"+i+","+i+",0,0,"+ +(f*p>h*m)+","+(this._x1=t+C*l)+","+(this._y1=e+C*u)}},"arcTo"),arc:o(function(t,e,r,n,i,a){t=+t,e=+e,r=+r,a=!!a;var s=r*Math.cos(n),l=r*Math.sin(n),u=t+s,h=e+l,f=1^a,d=a?n-i:i-n;if(r<0)throw new Error("negative radius: "+r);this._x1===null?this._+="M"+u+","+h:(Math.abs(this._x1-u)>Xp||Math.abs(this._y1-h)>Xp)&&(this._+="L"+u+","+h),r&&(d<0&&(d=d%UB+UB),d>zJe?this._+="A"+r+","+r+",0,1,"+f+","+(t-s)+","+(e-l)+"A"+r+","+r+",0,1,"+f+","+(this._x1=u)+","+(this._y1=h):d>Xp&&(this._+="A"+r+","+r+",0,"+ +(d>=VB)+","+f+","+(this._x1=t+r*Math.cos(i))+","+(this._y1=e+r*Math.sin(i))))},"arc"),rect:o(function(t,e,r,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +r+"v"+ +n+"h"+-r+"Z"},"rect"),toString:o(function(){return this._},"toString")};WB=A1e});var D1e=N(()=>{"use strict";_1e()});function ZS(t){return o(function(){return t},"constant")}var L1e=N(()=>{"use strict";o(ZS,"default")});function R1e(t){return t[0]}function N1e(t){return t[1]}var M1e=N(()=>{"use strict";o(R1e,"x");o(N1e,"y")});var I1e,O1e=N(()=>{"use strict";I1e=Array.prototype.slice});function GJe(t){return t.source}function VJe(t){return t.target}function UJe(t){var e=GJe,r=VJe,n=R1e,i=N1e,a=null;function s(){var l,u=I1e.call(arguments),h=e.apply(this,u),f=r.apply(this,u);if(a||(a=l=WB()),t(a,+n.apply(this,(u[0]=h,u)),+i.apply(this,u),+n.apply(this,(u[0]=f,u)),+i.apply(this,u)),l)return a=null,l+""||null}return o(s,"link"),s.source=function(l){return arguments.length?(e=l,s):e},s.target=function(l){return arguments.length?(r=l,s):r},s.x=function(l){return arguments.length?(n=typeof l=="function"?l:ZS(+l),s):n},s.y=function(l){return arguments.length?(i=typeof l=="function"?l:ZS(+l),s):i},s.context=function(l){return arguments.length?(a=l??null,s):a},s}function HJe(t,e,r,n,i){t.moveTo(e,r),t.bezierCurveTo(e=(e+n)/2,r,e,i,n,i)}function qB(){return UJe(HJe)}var P1e=N(()=>{"use strict";D1e();O1e();L1e();M1e();o(GJe,"linkSource");o(VJe,"linkTarget");o(UJe,"link");o(HJe,"curveHorizontal");o(qB,"linkHorizontal")});var B1e=N(()=>{"use strict";P1e()});function WJe(t){return[t.source.x1,t.y0]}function qJe(t){return[t.target.x0,t.y1]}function JS(){return qB().source(WJe).target(qJe)}var F1e=N(()=>{"use strict";B1e();o(WJe,"horizontalSource");o(qJe,"horizontalTarget");o(JS,"default")});var $1e=N(()=>{"use strict";C1e();zB();F1e()});var g4,z1e=N(()=>{"use strict";g4=class t{static{o(this,"Uid")}static{this.count=0}static next(e){return new t(e+ ++t.count)}constructor(e){this.id=e,this.href=`#${e}`}toString(){return"url("+this.href+")"}}});var YJe,XJe,G1e,V1e=N(()=>{"use strict";zt();dr();$1e();Ei();z1e();YJe={left:BB,right:FB,center:$B,justify:m4},XJe=o(function(t,e,r,n){let{securityLevel:i,sankey:a}=me(),s=A3.sankey,l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body"),h=i==="sandbox"?u.select(`[id="${e}"]`):Ge(`[id="${e}"]`),f=a?.width??s.width,d=a?.height??s.width,p=a?.useMaxWidth??s.useMaxWidth,m=a?.nodeAlignment??s.nodeAlignment,g=a?.prefix??s.prefix,y=a?.suffix??s.suffix,v=a?.showValues??s.showValues,x=n.db.getGraph(),b=YJe[m];QS().nodeId(I=>I.id).nodeWidth(10).nodePadding(10+(v?15:0)).nodeAlign(b).extent([[0,0],[f,d]])(x);let T=gu(e9);h.append("g").attr("class","nodes").selectAll(".node").data(x.nodes).join("g").attr("class","node").attr("id",I=>(I.uid=g4.next("node-")).id).attr("transform",function(I){return"translate("+I.x0+","+I.y0+")"}).attr("x",I=>I.x0).attr("y",I=>I.y0).append("rect").attr("height",I=>I.y1-I.y0).attr("width",I=>I.x1-I.x0).attr("fill",I=>T(I.id));let E=o(({id:I,value:D})=>v?`${I}
+${g}${Math.round(D*100)/100}${y}`:I,"getText");h.append("g").attr("class","node-labels").attr("font-size",14).selectAll("text").data(x.nodes).join("text").attr("x",I=>I.x0<f/2?I.x1+6:I.x0-6).attr("y",I=>(I.y1+I.y0)/2).attr("dy",`${v?"0":"0.35"}em`).attr("text-anchor",I=>I.x0<f/2?"start":"end").text(E);let A=h.append("g").attr("class","links").attr("fill","none").attr("stroke-opacity",.5).selectAll(".link").data(x.links).join("g").attr("class","link").style("mix-blend-mode","multiply"),S=a?.linkColor??"gradient";if(S==="gradient"){let I=A.append("linearGradient").attr("id",D=>(D.uid=g4.next("linearGradient-")).id).attr("gradientUnits","userSpaceOnUse").attr("x1",D=>D.source.x1).attr("x2",D=>D.target.x0);I.append("stop").attr("offset","0%").attr("stop-color",D=>T(D.source.id)),I.append("stop").attr("offset","100%").attr("stop-color",D=>T(D.target.id))}let _;switch(S){case"gradient":_=o(I=>I.uid,"coloring");break;case"source":_=o(I=>T(I.source.id),"coloring");break;case"target":_=o(I=>T(I.target.id),"coloring");break;default:_=S}A.append("path").attr("d",JS()).attr("stroke",_).attr("stroke-width",I=>Math.max(1,I.width)),Ao(void 0,h,0,p)},"draw"),G1e={draw:XJe}});var U1e,H1e=N(()=>{"use strict";U1e=o(t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,`
+`).trim(),"prepareTextForParsing")});var jJe,W1e,q1e=N(()=>{"use strict";jJe=o(t=>`.label {
+ font-family: ${t.fontFamily};
+ }`,"getStyles"),W1e=jJe});var Y1e={};hr(Y1e,{diagram:()=>QJe});var KJe,QJe,X1e=N(()=>{"use strict";m1e();y1e();V1e();H1e();q1e();KJe=d4.parse.bind(d4);d4.parse=t=>KJe(U1e(t));QJe={styles:W1e,parser:d4,db:g1e,renderer:G1e}});var Q1e,YB,tet,ret,net,iet,aet,Bf,XB=N(()=>{"use strict";ji();Ya();ir();mi();Q1e={packet:[]},YB=structuredClone(Q1e),tet=or.packet,ret=o(()=>{let t=Fi({...tet,...cr().packet});return t.showBits&&(t.paddingY+=10),t},"getConfig"),net=o(()=>YB.packet,"getPacket"),iet=o(t=>{t.length>0&&YB.packet.push(t)},"pushWord"),aet=o(()=>{Ar(),YB=structuredClone(Q1e)},"clear"),Bf={pushWord:iet,getPacket:net,getConfig:ret,clear:aet,setAccTitle:Lr,getAccTitle:Rr,setDiagramTitle:$r,getDiagramTitle:Ir,getAccDescription:Mr,setAccDescription:Nr}});var set,oet,cet,Z1e,J1e=N(()=>{"use strict";kp();vt();T1();XB();set=1e4,oet=o(t=>{$c(t,Bf);let e=-1,r=[],n=1,{bitsPerRow:i}=Bf.getConfig();for(let{start:a,end:s,label:l}of t.blocks){if(s&&s<a)throw new Error(`Packet block ${a} - ${s} is invalid. End must be greater than start.`);if(a!==e+1)throw new Error(`Packet block ${a} - ${s??a} is not contiguous. It should start from ${e+1}.`);for(e=s??a,Y.debug(`Packet block ${a} - ${e} with label ${l}`);r.length<=i+1&&Bf.getPacket().length<set;){let[u,h]=cet({start:a,end:s,label:l},n,i);if(r.push(u),u.end+1===n*i&&(Bf.pushWord(r),r=[],n++),!h)break;({start:a,end:s,label:l}=h)}}Bf.pushWord(r)},"populate"),cet=o((t,e,r)=>{if(t.end===void 0&&(t.end=t.start),t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);return t.end+1<=e*r?[t,void 0]:[{start:t.start,end:e*r-1,label:t.label},{start:e*r,end:t.end,label:t.label}]},"getNextFittingBlock"),Z1e={parse:o(async t=>{let e=await uo("packet",t);Y.debug(e),oet(e)},"parse")}});var uet,het,eye,tye=N(()=>{"use strict";Vc();Ei();uet=o((t,e,r,n)=>{let i=n.db,a=i.getConfig(),{rowHeight:s,paddingY:l,bitWidth:u,bitsPerRow:h}=a,f=i.getPacket(),d=i.getDiagramTitle(),p=s+l,m=p*(f.length+1)-(d?0:s),g=u*h+2,y=sa(e);y.attr("viewbox",`0 0 ${g} ${m}`),vn(y,m,g,a.useMaxWidth);for(let[v,x]of f.entries())het(y,x,v,a);y.append("text").text(d).attr("x",g/2).attr("y",m-p/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),het=o((t,e,r,{rowHeight:n,paddingX:i,paddingY:a,bitWidth:s,bitsPerRow:l,showBits:u})=>{let h=t.append("g"),f=r*(n+a)+a;for(let d of e){let p=d.start%l*s+1,m=(d.end-d.start+1)*s-i;if(h.append("rect").attr("x",p).attr("y",f).attr("width",m).attr("height",n).attr("class","packetBlock"),h.append("text").attr("x",p+m/2).attr("y",f+n/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(d.label),!u)continue;let g=d.end===d.start,y=f-2;h.append("text").attr("x",p+(g?m/2:0)).attr("y",y).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",g?"middle":"start").text(d.start),g||h.append("text").attr("x",p+m).attr("y",y).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(d.end)}},"drawWord"),eye={draw:uet}});var fet,rye,nye=N(()=>{"use strict";ir();fet={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},rye=o(({packet:t}={})=>{let e=Fi(fet,t);return`
+ .packetByte {
+ font-size: ${e.byteFontSize};
+ }
+ .packetByte.start {
+ fill: ${e.startByteColor};
+ }
+ .packetByte.end {
+ fill: ${e.endByteColor};
+ }
+ .packetLabel {
+ fill: ${e.labelColor};
+ font-size: ${e.labelFontSize};
+ }
+ .packetTitle {
+ fill: ${e.titleColor};
+ font-size: ${e.titleFontSize};
+ }
+ .packetBlock {
+ stroke: ${e.blockStrokeColor};
+ stroke-width: ${e.blockStrokeWidth};
+ fill: ${e.blockFillColor};
+ }
+ `},"styles")});var iye={};hr(iye,{diagram:()=>det});var det,aye=N(()=>{"use strict";XB();J1e();tye();nye();det={parser:Z1e,db:Bf,renderer:eye,styles:rye}});var fy,lye,jp,get,yet,cye,vet,xet,bet,wet,Tet,ket,Eet,Kp,jB=N(()=>{"use strict";ji();Ya();ir();mi();fy={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},lye={axes:[],curves:[],options:fy},jp=structuredClone(lye),get=or.radar,yet=o(()=>Fi({...get,...cr().radar}),"getConfig"),cye=o(()=>jp.axes,"getAxes"),vet=o(()=>jp.curves,"getCurves"),xet=o(()=>jp.options,"getOptions"),bet=o(t=>{jp.axes=t.map(e=>({name:e.name,label:e.label??e.name}))},"setAxes"),wet=o(t=>{jp.curves=t.map(e=>({name:e.name,label:e.label??e.name,entries:Tet(e.entries)}))},"setCurves"),Tet=o(t=>{if(t[0].axis==null)return t.map(r=>r.value);let e=cye();if(e.length===0)throw new Error("Axes must be populated before curves for reference entries");return e.map(r=>{let n=t.find(i=>i.axis?.$refText===r.name);if(n===void 0)throw new Error("Missing entry for axis "+r.label);return n.value})},"computeCurveEntries"),ket=o(t=>{let e=t.reduce((r,n)=>(r[n.name]=n,r),{});jp.options={showLegend:e.showLegend?.value??fy.showLegend,ticks:e.ticks?.value??fy.ticks,max:e.max?.value??fy.max,min:e.min?.value??fy.min,graticule:e.graticule?.value??fy.graticule}},"setOptions"),Eet=o(()=>{Ar(),jp=structuredClone(lye)},"clear"),Kp={getAxes:cye,getCurves:vet,getOptions:xet,setAxes:bet,setCurves:wet,setOptions:ket,getConfig:yet,clear:Eet,setAccTitle:Lr,getAccTitle:Rr,setDiagramTitle:$r,getDiagramTitle:Ir,getAccDescription:Mr,setAccDescription:Nr}});var Cet,uye,hye=N(()=>{"use strict";kp();vt();T1();jB();Cet=o(t=>{$c(t,Kp);let{axes:e,curves:r,options:n}=t;Kp.setAxes(e),Kp.setCurves(r),Kp.setOptions(n)},"populate"),uye={parse:o(async t=>{let e=await uo("radar",t);Y.debug(e),Cet(e)},"parse")}});function Ret(t,e,r,n,i,a,s){let l=e.length,u=Math.min(s.width,s.height)/2;r.forEach((h,f)=>{if(h.entries.length!==l)return;let d=h.entries.map((p,m)=>{let g=2*Math.PI*m/l-Math.PI/2,y=Net(p,n,i,u),v=y*Math.cos(g),x=y*Math.sin(g);return{x:v,y:x}});a==="circle"?t.append("path").attr("d",Met(d,s.curveTension)).attr("class",`radarCurve-${f}`):a==="polygon"&&t.append("polygon").attr("points",d.map(p=>`${p.x},${p.y}`).join(" ")).attr("class",`radarCurve-${f}`)})}function Net(t,e,r,n){let i=Math.min(Math.max(t,e),r);return n*(i-e)/(r-e)}function Met(t,e){let r=t.length,n=`M${t[0].x},${t[0].y}`;for(let i=0;i<r;i++){let a=t[(i-1+r)%r],s=t[i],l=t[(i+1)%r],u=t[(i+2)%r],h={x:s.x+(l.x-a.x)*e,y:s.y+(l.y-a.y)*e},f={x:l.x-(u.x-s.x)*e,y:l.y-(u.y-s.y)*e};n+=` C${h.x},${h.y} ${f.x},${f.y} ${l.x},${l.y}`}return`${n} Z`}function Iet(t,e,r,n){if(!r)return;let i=(n.width/2+n.marginRight)*3/4,a=-(n.height/2+n.marginTop)*3/4,s=20;e.forEach((l,u)=>{let h=t.append("g").attr("transform",`translate(${i}, ${a+u*s})`);h.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${u}`),h.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(l.label)})}var Aet,_et,Det,Let,fye,dye=N(()=>{"use strict";Vc();Aet=o((t,e,r,n)=>{let i=n.db,a=i.getAxes(),s=i.getCurves(),l=i.getOptions(),u=i.getConfig(),h=i.getDiagramTitle(),f=sa(e),d=_et(f,u),p=l.max??Math.max(...s.map(y=>Math.max(...y.entries))),m=l.min,g=Math.min(u.width,u.height)/2;Det(d,a,g,l.ticks,l.graticule),Let(d,a,g,u),Ret(d,a,s,m,p,l.graticule,u),Iet(d,s,l.showLegend,u),d.append("text").attr("class","radarTitle").text(h).attr("x",0).attr("y",-u.height/2-u.marginTop)},"draw"),_et=o((t,e)=>{let r=e.width+e.marginLeft+e.marginRight,n=e.height+e.marginTop+e.marginBottom,i={x:e.marginLeft+e.width/2,y:e.marginTop+e.height/2};return t.attr("viewbox",`0 0 ${r} ${n}`).attr("width",r).attr("height",n),t.append("g").attr("transform",`translate(${i.x}, ${i.y})`)},"drawFrame"),Det=o((t,e,r,n,i)=>{if(i==="circle")for(let a=0;a<n;a++){let s=r*(a+1)/n;t.append("circle").attr("r",s).attr("class","radarGraticule")}else if(i==="polygon"){let a=e.length;for(let s=0;s<n;s++){let l=r*(s+1)/n,u=e.map((h,f)=>{let d=2*f*Math.PI/a-Math.PI/2,p=l*Math.cos(d),m=l*Math.sin(d);return`${p},${m}`}).join(" ");t.append("polygon").attr("points",u).attr("class","radarGraticule")}}},"drawGraticule"),Let=o((t,e,r,n)=>{let i=e.length;for(let a=0;a<i;a++){let s=e[a].label,l=2*a*Math.PI/i-Math.PI/2;t.append("line").attr("x1",0).attr("y1",0).attr("x2",r*n.axisScaleFactor*Math.cos(l)).attr("y2",r*n.axisScaleFactor*Math.sin(l)).attr("class","radarAxisLine"),t.append("text").text(s).attr("x",r*n.axisLabelFactor*Math.cos(l)).attr("y",r*n.axisLabelFactor*Math.sin(l)).attr("class","radarAxisLabel")}},"drawAxes");o(Ret,"drawCurves");o(Net,"relativeRadius");o(Met,"closedRoundCurve");o(Iet,"drawLegend");fye={draw:Aet}});var Oet,Pet,pye,mye=N(()=>{"use strict";ir();_y();ji();Oet=o((t,e)=>{let r="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++){let i=t[`cScale${n}`];r+=`
+ .radarCurve-${n} {
+ color: ${i};
+ fill: ${i};
+ fill-opacity: ${e.curveOpacity};
+ stroke: ${i};
+ stroke-width: ${e.curveStrokeWidth};
+ }
+ .radarLegendBox-${n} {
+ fill: ${i};
+ fill-opacity: ${e.curveOpacity};
+ stroke: ${i};
+ }
+ `}return r},"genIndexStyles"),Pet=o(t=>{let e=oh(),r=cr(),n=Fi(e,r.themeVariables),i=Fi(n.radar,t);return{themeVariables:n,radarOptions:i}},"buildRadarStyleOptions"),pye=o(({radar:t}={})=>{let{themeVariables:e,radarOptions:r}=Pet(t);return`
+ .radarTitle {
+ font-size: ${e.fontSize};
+ color: ${e.titleColor};
+ dominant-baseline: hanging;
+ text-anchor: middle;
+ }
+ .radarAxisLine {
+ stroke: ${r.axisColor};
+ stroke-width: ${r.axisStrokeWidth};
+ }
+ .radarAxisLabel {
+ dominant-baseline: middle;
+ text-anchor: middle;
+ font-size: ${r.axisLabelFontSize}px;
+ color: ${r.axisColor};
+ }
+ .radarGraticule {
+ fill: ${r.graticuleColor};
+ fill-opacity: ${r.graticuleOpacity};
+ stroke: ${r.graticuleColor};
+ stroke-width: ${r.graticuleStrokeWidth};
+ }
+ .radarLegendText {
+ text-anchor: start;
+ font-size: ${r.legendFontSize}px;
+ dominant-baseline: hanging;
+ }
+ ${Oet(e,r)}
+ `},"styles")});var gye={};hr(gye,{diagram:()=>Bet});var Bet,yye=N(()=>{"use strict";jB();hye();dye();mye();Bet={parser:uye,db:Kp,renderer:fye,styles:pye}});var KB,bye,wye=N(()=>{"use strict";KB=function(){var t=o(function(w,C,T,E){for(T=T||{},E=w.length;E--;T[w[E]]=C);return T},"o"),e=[1,7],r=[1,13],n=[1,14],i=[1,15],a=[1,19],s=[1,16],l=[1,17],u=[1,18],h=[8,30],f=[8,21,28,29,30,31,32,40,44,47],d=[1,23],p=[1,24],m=[8,15,16,21,28,29,30,31,32,40,44,47],g=[8,15,16,21,27,28,29,30,31,32,40,44,47],y=[1,49],v={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:o(function(C,T,E,A,S,_,I){var D=_.length-1;switch(S){case 4:A.getLogger().debug("Rule: separator (NL) ");break;case 5:A.getLogger().debug("Rule: separator (Space) ");break;case 6:A.getLogger().debug("Rule: separator (EOF) ");break;case 7:A.getLogger().debug("Rule: hierarchy: ",_[D-1]),A.setHierarchy(_[D-1]);break;case 8:A.getLogger().debug("Stop NL ");break;case 9:A.getLogger().debug("Stop EOF ");break;case 10:A.getLogger().debug("Stop NL2 ");break;case 11:A.getLogger().debug("Stop EOF2 ");break;case 12:A.getLogger().debug("Rule: statement: ",_[D]),typeof _[D].length=="number"?this.$=_[D]:this.$=[_[D]];break;case 13:A.getLogger().debug("Rule: statement #2: ",_[D-1]),this.$=[_[D-1]].concat(_[D]);break;case 14:A.getLogger().debug("Rule: link: ",_[D],C),this.$={edgeTypeStr:_[D],label:""};break;case 15:A.getLogger().debug("Rule: LABEL link: ",_[D-3],_[D-1],_[D]),this.$={edgeTypeStr:_[D],label:_[D-1]};break;case 18:let k=parseInt(_[D]),L=A.generateId();this.$={id:L,type:"space",label:"",width:k,children:[]};break;case 23:A.getLogger().debug("Rule: (nodeStatement link node) ",_[D-2],_[D-1],_[D]," typestr: ",_[D-1].edgeTypeStr);let R=A.edgeStrToEdgeData(_[D-1].edgeTypeStr);this.$=[{id:_[D-2].id,label:_[D-2].label,type:_[D-2].type,directions:_[D-2].directions},{id:_[D-2].id+"-"+_[D].id,start:_[D-2].id,end:_[D].id,label:_[D-1].label,type:"edge",directions:_[D].directions,arrowTypeEnd:R,arrowTypeStart:"arrow_open"},{id:_[D].id,label:_[D].label,type:A.typeStr2Type(_[D].typeStr),directions:_[D].directions}];break;case 24:A.getLogger().debug("Rule: nodeStatement (abc88 node size) ",_[D-1],_[D]),this.$={id:_[D-1].id,label:_[D-1].label,type:A.typeStr2Type(_[D-1].typeStr),directions:_[D-1].directions,widthInColumns:parseInt(_[D],10)};break;case 25:A.getLogger().debug("Rule: nodeStatement (node) ",_[D]),this.$={id:_[D].id,label:_[D].label,type:A.typeStr2Type(_[D].typeStr),directions:_[D].directions,widthInColumns:1};break;case 26:A.getLogger().debug("APA123",this?this:"na"),A.getLogger().debug("COLUMNS: ",_[D]),this.$={type:"column-setting",columns:_[D]==="auto"?-1:parseInt(_[D])};break;case 27:A.getLogger().debug("Rule: id-block statement : ",_[D-2],_[D-1]);let O=A.generateId();this.$={..._[D-2],type:"composite",children:_[D-1]};break;case 28:A.getLogger().debug("Rule: blockStatement : ",_[D-2],_[D-1],_[D]);let M=A.generateId();this.$={id:M,type:"composite",label:"",children:_[D-1]};break;case 29:A.getLogger().debug("Rule: node (NODE_ID separator): ",_[D]),this.$={id:_[D]};break;case 30:A.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",_[D-1],_[D]),this.$={id:_[D-1],label:_[D].label,typeStr:_[D].typeStr,directions:_[D].directions};break;case 31:A.getLogger().debug("Rule: dirList: ",_[D]),this.$=[_[D]];break;case 32:A.getLogger().debug("Rule: dirList: ",_[D-1],_[D]),this.$=[_[D-1]].concat(_[D]);break;case 33:A.getLogger().debug("Rule: nodeShapeNLabel: ",_[D-2],_[D-1],_[D]),this.$={typeStr:_[D-2]+_[D],label:_[D-1]};break;case 34:A.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",_[D-3],_[D-2]," #3:",_[D-1],_[D]),this.$={typeStr:_[D-3]+_[D],label:_[D-2],directions:_[D-1]};break;case 35:case 36:this.$={type:"classDef",id:_[D-1].trim(),css:_[D].trim()};break;case 37:this.$={type:"applyClass",id:_[D-1].trim(),styleClass:_[D].trim()};break;case 38:this.$={type:"applyStyles",id:_[D-1].trim(),stylesStr:_[D].trim()};break}},"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{8:[1,20]},t(h,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:e,28:r,29:n,31:i,32:a,40:s,44:l,47:u}),t(f,[2,16],{14:22,15:d,16:p}),t(f,[2,17]),t(f,[2,18]),t(f,[2,19]),t(f,[2,20]),t(f,[2,21]),t(f,[2,22]),t(m,[2,25],{27:[1,25]}),t(f,[2,26]),{19:26,26:12,32:a},{11:27,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},t(g,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},t(h,[2,13]),{26:35,32:a},{32:[2,14]},{17:[1,36]},t(m,[2,24]),{11:37,13:4,14:22,15:d,16:p,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:n,31:i,32:a,40:s,44:l,47:u},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},t(g,[2,30]),{18:[1,43]},{18:[1,44]},t(m,[2,23]),{18:[1,45]},{30:[1,46]},t(f,[2,28]),t(f,[2,35]),t(f,[2,36]),t(f,[2,37]),t(f,[2,38]),{37:[1,47]},{34:48,35:y},{15:[1,50]},t(f,[2,27]),t(g,[2,33]),{39:[1,51]},{34:52,35:y,39:[2,31]},{32:[2,15]},t(g,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:o(function(C,T){if(T.recoverable)this.trace(C);else{var E=new Error(C);throw E.hash=T,E}},"parseError"),parse:o(function(C){var T=this,E=[0],A=[],S=[null],_=[],I=this.table,D="",k=0,L=0,R=0,O=2,M=1,B=_.slice.call(arguments,1),F=Object.create(this.lexer),P={yy:{}};for(var z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,z)&&(P.yy[z]=this.yy[z]);F.setInput(C,P.yy),P.yy.lexer=F,P.yy.parser=this,typeof F.yylloc>"u"&&(F.yylloc={});var $=F.yylloc;_.push($);var H=F.options&&F.options.ranges;typeof P.yy.parseError=="function"?this.parseError=P.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Q(ce){E.length=E.length-2*ce,S.length=S.length-ce,_.length=_.length-ce}o(Q,"popStack");function j(){var ce;return ce=A.pop()||F.lex()||M,typeof ce!="number"&&(ce instanceof Array&&(A=ce,ce=A.pop()),ce=T.symbols_[ce]||ce),ce}o(j,"lex");for(var ie,ne,le,he,K,X,te={},J,se,ue,Z;;){if(le=E[E.length-1],this.defaultActions[le]?he=this.defaultActions[le]:((ie===null||typeof ie>"u")&&(ie=j()),he=I[le]&&I[le][ie]),typeof he>"u"||!he.length||!he[0]){var Se="";Z=[];for(J in I[le])this.terminals_[J]&&J>O&&Z.push("'"+this.terminals_[J]+"'");F.showPosition?Se="Parse error on line "+(k+1)+`:
+`+F.showPosition()+`
+Expecting `+Z.join(", ")+", got '"+(this.terminals_[ie]||ie)+"'":Se="Parse error on line "+(k+1)+": Unexpected "+(ie==M?"end of input":"'"+(this.terminals_[ie]||ie)+"'"),this.parseError(Se,{text:F.match,token:this.terminals_[ie]||ie,line:F.yylineno,loc:$,expected:Z})}if(he[0]instanceof Array&&he.length>1)throw new Error("Parse Error: multiple actions possible at state: "+le+", token: "+ie);switch(he[0]){case 1:E.push(ie),S.push(F.yytext),_.push(F.yylloc),E.push(he[1]),ie=null,ne?(ie=ne,ne=null):(L=F.yyleng,D=F.yytext,k=F.yylineno,$=F.yylloc,R>0&&R--);break;case 2:if(se=this.productions_[he[1]][1],te.$=S[S.length-se],te._$={first_line:_[_.length-(se||1)].first_line,last_line:_[_.length-1].last_line,first_column:_[_.length-(se||1)].first_column,last_column:_[_.length-1].last_column},H&&(te._$.range=[_[_.length-(se||1)].range[0],_[_.length-1].range[1]]),X=this.performAction.apply(te,[D,L,k,P.yy,he[1],S,_].concat(B)),typeof X<"u")return X;se&&(E=E.slice(0,-1*se*2),S=S.slice(0,-1*se),_=_.slice(0,-1*se)),E.push(this.productions_[he[1]][0]),S.push(te.$),_.push(te._$),ue=I[E[E.length-2]][E[E.length-1]],E.push(ue);break;case 3:return!0}}return!0},"parse")},x=function(){var w={EOF:1,parseError:o(function(T,E){if(this.yy.parser)this.yy.parser.parseError(T,E);else throw new Error(T)},"parseError"),setInput:o(function(C,T){return this.yy=T||this.yy||{},this._input=C,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var C=this._input[0];this.yytext+=C,this.yyleng++,this.offset++,this.match+=C,this.matched+=C;var T=C.match(/(?:\r\n?|\n).*/g);return T?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),C},"input"),unput:o(function(C){var T=C.length,E=C.split(/(?:\r\n?|\n)/g);this._input=C+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-T),this.offset-=T;var A=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),E.length-1&&(this.yylineno-=E.length-1);var S=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:E?(E.length===A.length?this.yylloc.first_column:0)+A[A.length-E.length].length-E[0].length:this.yylloc.first_column-T},this.options.ranges&&(this.yylloc.range=[S[0],S[0]+this.yyleng-T]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
+`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(C){this.unput(this.match.slice(C))},"less"),pastInput:o(function(){var C=this.matched.substr(0,this.matched.length-this.match.length);return(C.length>20?"...":"")+C.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var C=this.match;return C.length<20&&(C+=this._input.substr(0,20-C.length)),(C.substr(0,20)+(C.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var C=this.pastInput(),T=new Array(C.length+1).join("-");return C+this.upcomingInput()+`
+`+T+"^"},"showPosition"),test_match:o(function(C,T){var E,A,S;if(this.options.backtrack_lexer&&(S={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(S.yylloc.range=this.yylloc.range.slice(0))),A=C[0].match(/(?:\r\n?|\n).*/g),A&&(this.yylineno+=A.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:A?A[A.length-1].length-A[A.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+C[0].length},this.yytext+=C[0],this.match+=C[0],this.matches=C,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(C[0].length),this.matched+=C[0],E=this.performAction.call(this,this.yy,this,T,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),E)return E;if(this._backtrack){for(var _ in S)this[_]=S[_];return!1}return!1},"test_match"),next:o(function(){if(this.done)return this.EOF;this._input||(this.done=!0);var C,T,E,A;this._more||(this.yytext="",this.match="");for(var S=this._currentRules(),_=0;_<S.length;_++)if(E=this._input.match(this.rules[S[_]]),E&&(!T||E[0].length>T[0].length)){if(T=E,A=_,this.options.backtrack_lexer){if(C=this.test_match(E,S[_]),C!==!1)return C;if(this._backtrack){T=!1;continue}else return!1}else if(!this.options.flex)break}return T?(C=this.test_match(T,S[A]),C!==!1?C:!1):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text.
+`+this.showPosition(),{text:"",token:null,line:this.yylineno})},"next"),lex:o(function(){var T=this.next();return T||this.lex()},"lex"),begin:o(function(T){this.conditionStack.push(T)},"begin"),popState:o(function(){var T=this.conditionStack.length-1;return T>0?this.conditionStack.pop():this.conditionStack[0]},"popState"),_currentRules:o(function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},"_currentRules"),topState:o(function(T){return T=this.conditionStack.length-1-Math.abs(T||0),T>=0?this.conditionStack[T]:"INITIAL"},"topState"),pushState:o(function(T){this.begin(T)},"pushState"),stateStackSize:o(function(){return this.conditionStack.length},"stateStackSize"),options:{},performAction:o(function(T,E,A,S){var _=S;switch(A){case 0:return 10;case 1:return T.getLogger().debug("Found space-block"),31;break;case 2:return T.getLogger().debug("Found nl-block"),31;break;case 3:return T.getLogger().debug("Found space-block"),29;break;case 4:T.getLogger().debug(".",E.yytext);break;case 5:T.getLogger().debug("_",E.yytext);break;case 6:return 5;case 7:return E.yytext=-1,28;break;case 8:return E.yytext=E.yytext.replace(/columns\s+/,""),T.getLogger().debug("COLUMNS (LEX)",E.yytext),28;break;case 9:this.pushState("md_string");break;case 10:return"MD_STR";case 11:this.popState();break;case 12:this.pushState("string");break;case 13:T.getLogger().debug("LEX: POPPING STR:",E.yytext),this.popState();break;case 14:return T.getLogger().debug("LEX: STR end:",E.yytext),"STR";break;case 15:return E.yytext=E.yytext.replace(/space\:/,""),T.getLogger().debug("SPACE NUM (LEX)",E.yytext),21;break;case 16:return E.yytext="1",T.getLogger().debug("COLUMNS (LEX)",E.yytext),21;break;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;break;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";break;case 22:return this.popState(),this.pushState("CLASSDEFID"),41;break;case 23:return this.popState(),42;break;case 24:return this.pushState("CLASS"),44;break;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;break;case 26:return this.popState(),46;break;case 27:return this.pushState("STYLE_STMNT"),47;break;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;break;case 29:return this.popState(),49;break;case 30:return this.pushState("acc_title"),"acc_title";break;case 31:return this.popState(),"acc_title_value";break;case 32:return this.pushState("acc_descr"),"acc_descr";break;case 33:return this.popState(),"acc_descr_value";break;case 34:this.pushState("acc_descr_multiline");break;case 35:this.popState();break;case 36:return"acc_descr_multiline_value";case 37:return 30;case 38:return this.popState(),T.getLogger().debug("Lex: (("),"NODE_DEND";break;case 39:return this.popState(),T.getLogger().debug("Lex: (("),"NODE_DEND";break;case 40:return this.popState(),T.getLogger().debug("Lex: ))"),"NODE_DEND";break;case 41:return this.popState(),T.getLogger().debug("Lex: (("),"NODE_DEND";break;case 42:return this.popState(),T.getLogger().debug("Lex: (("),"NODE_DEND";break;case 43:return this.popState(),T.getLogger().debug("Lex: (-"),"NODE_DEND";break;case 44:return this.popState(),T.getLogger().debug("Lex: -)"),"NODE_DEND";break;case 45:return this.popState(),T.getLogger().debug("Lex: (("),"NODE_DEND";break;case 46:return this.popState(),T.getLogger().debug("Lex: ]]"),"NODE_DEND";break;case 47:return this.popState(),T.getLogger().debug("Lex: ("),"NODE_DEND";break;case 48:return this.popState(),T.getLogger().debug("Lex: ])"),"NODE_DEND";break;case 49:return this.popState(),T.getLogger().debug("Lex: /]"),"NODE_DEND";break;case 50:return this.popState(),T.getLogger().debug("Lex: /]"),"NODE_DEND";break;case 51:return this.popState(),T.getLogger().debug("Lex: )]"),"NODE_DEND";break;case 52:return this.popState(),T.getLogger().debug("Lex: )"),"NODE_DEND";break;case 53:return this.popState(),T.getLogger().debug("Lex: ]>"),"NODE_DEND";break;case 54:return this.popState(),T.getLogger().debug("Lex: ]"),"NODE_DEND";break;case 55:return T.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;break;case 56:return T.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;break;case 57:return T.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;break;case 58:return T.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 59:return T.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;break;case 60:return T.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 61:return T.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 62:return T.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 63:return T.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;break;case 64:return T.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;break;case 65:return T.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;break;case 66:return this.pushState("NODE"),36;break;case 67:return this.pushState("NODE"),36;break;case 68:return this.pushState("NODE"),36;break;case 69:return this.pushState("NODE"),36;break;case 70:return this.pushState("NODE"),36;break;case 71:return this.pushState("NODE"),36;break;case 72:return this.pushState("NODE"),36;break;case 73:return T.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;break;case 74:return this.pushState("BLOCK_ARROW"),T.getLogger().debug("LEX ARR START"),38;break;case 75:return T.getLogger().debug("Lex: NODE_ID",E.yytext),32;break;case 76:return T.getLogger().debug("Lex: EOF",E.yytext),8;break;case 77:this.pushState("md_string");break;case 78:this.pushState("md_string");break;case 79:return"NODE_DESCR";case 80:this.popState();break;case 81:T.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:T.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return T.getLogger().debug("LEX: NODE_DESCR:",E.yytext),"NODE_DESCR";break;case 84:T.getLogger().debug("LEX POPPING"),this.popState();break;case 85:T.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return E.yytext=E.yytext.replace(/^,\s*/,""),T.getLogger().debug("Lex (right): dir:",E.yytext),"DIR";break;case 87:return E.yytext=E.yytext.replace(/^,\s*/,""),T.getLogger().debug("Lex (left):",E.yytext),"DIR";break;case 88:return E.yytext=E.yytext.replace(/^,\s*/,""),T.getLogger().debug("Lex (x):",E.yytext),"DIR";break;case 89:return E.yytext=E.yytext.replace(/^,\s*/,""),T.getLogger().debug("Lex (y):",E.yytext),"DIR";break;case 90:return E.yytext=E.yytext.replace(/^,\s*/,""),T.getLogger().debug("Lex (up):",E.yytext),"DIR";break;case 91:return E.yytext=E.yytext.replace(/^,\s*/,""),T.getLogger().debug("Lex (down):",E.yytext),"DIR";break;case 92:return E.yytext="]>",T.getLogger().debug("Lex (ARROW_DIR end):",E.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";break;case 93:return T.getLogger().debug("Lex: LINK","#"+E.yytext+"#"),15;break;case 94:return T.getLogger().debug("Lex: LINK",E.yytext),15;break;case 95:return T.getLogger().debug("Lex: LINK",E.yytext),15;break;case 96:return T.getLogger().debug("Lex: LINK",E.yytext),15;break;case 97:return T.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 98:return T.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 99:return T.getLogger().debug("Lex: START_LINK",E.yytext),this.pushState("LLABEL"),16;break;case 100:this.pushState("md_string");break;case 101:return T.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";break;case 102:return this.popState(),T.getLogger().debug("Lex: LINK","#"+E.yytext+"#"),15;break;case 103:return this.popState(),T.getLogger().debug("Lex: LINK",E.yytext),15;break;case 104:return this.popState(),T.getLogger().debug("Lex: LINK",E.yytext),15;break;case 105:return T.getLogger().debug("Lex: COLON",E.yytext),E.yytext=E.yytext.slice(1),27;break}},"anonymous"),rules:[/^(?:block-beta\b)/,/^(?:block\s+)/,/^(?:block\n+)/,/^(?:block:)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[29],inclusive:!1},STYLE_STMNT:{rules:[28],inclusive:!1},CLASSDEFID:{rules:[23],inclusive:!1},CLASSDEF:{rules:[21,22],inclusive:!1},CLASS_STYLE:{rules:[26],inclusive:!1},CLASS:{rules:[25],inclusive:!1},LLABEL:{rules:[100,101,102,103,104],inclusive:!1},ARROW_DIR:{rules:[86,87,88,89,90,91,92],inclusive:!1},BLOCK_ARROW:{rules:[77,82,85],inclusive:!1},NODE:{rules:[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,78,81],inclusive:!1},md_string:{rules:[10,11,79,80],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[13,14,83,84],inclusive:!1},acc_descr_multiline:{rules:[35,36],inclusive:!1},acc_descr:{rules:[33],inclusive:!1},acc_title:{rules:[31],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,12,15,16,17,18,19,20,24,27,30,32,34,37,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,93,94,95,96,97,98,99,105],inclusive:!0}}};return w}();v.lexer=x;function b(){this.yy={}}return o(b,"Parser"),b.prototype=v,v.Parser=b,new b}();KB.parser=KB;bye=KB});function Yet(t){switch(Y.debug("typeStr2Type",t),t){case"[]":return"square";case"()":return Y.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}}function Xet(t){switch(Y.debug("typeStr2Type",t),t){case"==":return"thick";default:return"normal"}}function jet(t){switch(t.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}}var Ul,ZB,QB,Tye,kye,zet,Sye,Get,eC,Vet,Uet,Het,Wet,Cye,JB,y4,qet,Eye,Ket,Qet,Zet,Jet,ett,ttt,rtt,ntt,itt,att,stt,Aye,_ye=N(()=>{"use strict";gL();ji();zt();vt();gr();mi();Ul=new Map,ZB=[],QB=new Map,Tye="color",kye="fill",zet="bgFill",Sye=",",Get=me(),eC=new Map,Vet=o(t=>Ze.sanitizeText(t,Get),"sanitizeText"),Uet=o(function(t,e=""){let r=eC.get(t);r||(r={id:t,styles:[],textStyles:[]},eC.set(t,r)),e?.split(Sye).forEach(n=>{let i=n.replace(/([^;]*);/,"$1").trim();if(RegExp(Tye).exec(n)){let s=i.replace(kye,zet).replace(Tye,kye);r.textStyles.push(s)}r.styles.push(i)})},"addStyleClass"),Het=o(function(t,e=""){let r=Ul.get(t);e!=null&&(r.styles=e.split(Sye))},"addStyle2Node"),Wet=o(function(t,e){t.split(",").forEach(function(r){let n=Ul.get(r);if(n===void 0){let i=r.trim();n={id:i,type:"na",children:[]},Ul.set(i,n)}n.classes||(n.classes=[]),n.classes.push(e)})},"setCssClass"),Cye=o((t,e)=>{let r=t.flat(),n=[];for(let i of r){if(i.label&&(i.label=Vet(i.label)),i.type==="classDef"){Uet(i.id,i.css);continue}if(i.type==="applyClass"){Wet(i.id,i?.styleClass??"");continue}if(i.type==="applyStyles"){i?.stylesStr&&Het(i.id,i?.stylesStr);continue}if(i.type==="column-setting")e.columns=i.columns??-1;else if(i.type==="edge"){let a=(QB.get(i.id)??0)+1;QB.set(i.id,a),i.id=a+"-"+i.id,ZB.push(i)}else{i.label||(i.type==="composite"?i.label="":i.label=i.id);let a=Ul.get(i.id);if(a===void 0?Ul.set(i.id,i):(i.type!=="na"&&(a.type=i.type),i.label!==i.id&&(a.label=i.label)),i.children&&Cye(i.children,i),i.type==="space"){let s=i.width??1;for(let l=0;l<s;l++){let u=an(i);u.id=u.id+"-"+l,Ul.set(u.id,u),n.push(u)}}else a===void 0&&n.push(i)}}e.children=n},"populateBlockDatabase"),JB=[],y4={id:"root",type:"composite",children:[],columns:-1},qet=o(()=>{Y.debug("Clear called"),Ar(),y4={id:"root",type:"composite",children:[],columns:-1},Ul=new Map([["root",y4]]),JB=[],eC=new Map,ZB=[],QB=new Map},"clear");o(Yet,"typeStr2Type");o(Xet,"edgeTypeStr2Type");o(jet,"edgeStrToEdgeData");Eye=0,Ket=o(()=>(Eye++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Eye),"generateId"),Qet=o(t=>{y4.children=t,Cye(t,y4),JB=y4.children},"setHierarchy"),Zet=o(t=>{let e=Ul.get(t);return e?e.columns?e.columns:e.children?e.children.length:-1:-1},"getColumns"),Jet=o(()=>[...Ul.values()],"getBlocksFlat"),ett=o(()=>JB||[],"getBlocks"),ttt=o(()=>ZB,"getEdges"),rtt=o(t=>Ul.get(t),"getBlock"),ntt=o(t=>{Ul.set(t.id,t)},"setBlock"),itt=o(()=>console,"getLogger"),att=o(function(){return eC},"getClasses"),stt={getConfig:o(()=>cr().block,"getConfig"),typeStr2Type:Yet,edgeTypeStr2Type:Xet,edgeStrToEdgeData:jet,getLogger:itt,getBlocksFlat:Jet,getBlocks:ett,getEdges:ttt,setHierarchy:Qet,getBlock:rtt,setBlock:ntt,getColumns:Zet,getClasses:att,clear:qet,generateId:Ket},Aye=stt});var tC,ott,Dye,Lye=N(()=>{"use strict";Ys();tC=o((t,e)=>{let r=Kf,n=r(t,"r"),i=r(t,"g"),a=r(t,"b");return qa(n,i,a,e)},"fade"),ott=o(t=>`.label {
+ font-family: ${t.fontFamily};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+ .cluster-label text {
+ fill: ${t.titleColor};
+ }
+ .cluster-label span,p {
+ color: ${t.titleColor};
+ }
+
+
+
+ .label text,span,p {
+ fill: ${t.nodeTextColor||t.textColor};
+ color: ${t.nodeTextColor||t.textColor};
+ }
+
+ .node rect,
+ .node circle,
+ .node ellipse,
+ .node polygon,
+ .node path {
+ fill: ${t.mainBkg};
+ stroke: ${t.nodeBorder};
+ stroke-width: 1px;
+ }
+ .flowchart-label text {
+ text-anchor: middle;
+ }
+ // .flowchart-label .text-outer-tspan {
+ // text-anchor: middle;
+ // }
+ // .flowchart-label .text-inner-tspan {
+ // text-anchor: start;
+ // }
+
+ .node .label {
+ text-align: center;
+ }
+ .node.clickable {
+ cursor: pointer;
+ }
+
+ .arrowheadPath {
+ fill: ${t.arrowheadColor};
+ }
+
+ .edgePath .path {
+ stroke: ${t.lineColor};
+ stroke-width: 2.0px;
+ }
+
+ .flowchart-link {
+ stroke: ${t.lineColor};
+ fill: none;
+ }
+
+ .edgeLabel {
+ background-color: ${t.edgeLabelBackground};
+ rect {
+ opacity: 0.5;
+ background-color: ${t.edgeLabelBackground};
+ fill: ${t.edgeLabelBackground};
+ }
+ text-align: center;
+ }
+
+ /* For html labels only */
+ .labelBkg {
+ background-color: ${tC(t.edgeLabelBackground,.5)};
+ // background-color:
+ }
+
+ .node .cluster {
+ // fill: ${tC(t.mainBkg,.5)};
+ fill: ${tC(t.clusterBkg,.5)};
+ stroke: ${tC(t.clusterBorder,.2)};
+ box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
+ stroke-width: 1px;
+ }
+
+ .cluster text {
+ fill: ${t.titleColor};
+ }
+
+ .cluster span,p {
+ color: ${t.titleColor};
+ }
+ /* .cluster div {
+ color: ${t.titleColor};
+ } */
+
+ div.mermaidTooltip {
+ position: absolute;
+ text-align: center;
+ max-width: 200px;
+ padding: 2px;
+ font-family: ${t.fontFamily};
+ font-size: 12px;
+ background: ${t.tertiaryColor};
+ border: 1px solid ${t.border2};
+ border-radius: 2px;
+ pointer-events: none;
+ z-index: 100;
+ }
+
+ .flowchartTitleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: ${t.textColor};
+ }
+`,"getStyles"),Dye=ott});var ltt,ctt,utt,htt,ftt,dtt,ptt,mtt,gtt,ytt,vtt,Rye,Nye=N(()=>{"use strict";vt();ltt=o((t,e,r,n)=>{e.forEach(i=>{vtt[i](t,r,n)})},"insertMarkers"),ctt=o((t,e,r)=>{Y.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},"extension"),utt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"composition"),htt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},"aggregation"),ftt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},"dependency"),dtt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},"lollipop"),ptt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"point"),mtt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},"circle"),gtt=o((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},"cross"),ytt=o((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"barb"),vtt={extension:ctt,composition:utt,aggregation:htt,dependency:ftt,lollipop:dtt,point:ptt,circle:mtt,cross:gtt,barb:ytt},Rye=ltt});function xtt(t,e){if(t===0||!Number.isInteger(t))throw new Error("Columns must be an integer !== 0.");if(e<0||!Number.isInteger(e))throw new Error("Position must be a non-negative integer."+e);if(t<0)return{px:e,py:0};if(t===1)return{px:0,py:e};let r=e%t,n=Math.floor(e/t);return{px:r,py:n}}function eF(t,e,r=0,n=0){Y.debug("setBlockSizes abc95 (start)",t.id,t?.size?.x,"block width =",t?.size,"sieblingWidth",r),t?.size?.width||(t.size={width:r,height:n,x:0,y:0});let i=0,a=0;if(t.children?.length>0){for(let m of t.children)eF(m,e);let s=btt(t);i=s.width,a=s.height,Y.debug("setBlockSizes abc95 maxWidth of",t.id,":s children is ",i,a);for(let m of t.children)m.size&&(Y.debug(`abc95 Setting size of children of ${t.id} id=${m.id} ${i} ${a} ${JSON.stringify(m.size)}`),m.size.width=i*(m.widthInColumns??1)+bi*((m.widthInColumns??1)-1),m.size.height=a,m.size.x=0,m.size.y=0,Y.debug(`abc95 updating size of ${t.id} children child:${m.id} maxWidth:${i} maxHeight:${a}`));for(let m of t.children)eF(m,e,i,a);let l=t.columns??-1,u=0;for(let m of t.children)u+=m.widthInColumns??1;let h=t.children.length;l>0&&l<u&&(h=l);let f=Math.ceil(u/h),d=h*(i+bi)+bi,p=f*(a+bi)+bi;if(d<r){Y.debug(`Detected to small siebling: abc95 ${t.id} sieblingWidth ${r} sieblingHeight ${n} width ${d}`),d=r,p=n;let m=(r-h*bi-bi)/h,g=(n-f*bi-bi)/f;Y.debug("Size indata abc88",t.id,"childWidth",m,"maxWidth",i),Y.debug("Size indata abc88",t.id,"childHeight",g,"maxHeight",a),Y.debug("Size indata abc88 xSize",h,"padding",bi);for(let y of t.children)y.size&&(y.size.width=m,y.size.height=g,y.size.x=0,y.size.y=0)}if(Y.debug(`abc95 (finale calc) ${t.id} xSize ${h} ySize ${f} columns ${l}${t.children.length} width=${Math.max(d,t.size?.width||0)}`),d<(t?.size?.width||0)){d=t?.size?.width||0;let m=l>0?Math.min(t.children.length,l):t.children.length;if(m>0){let g=(d-m*bi-bi)/m;Y.debug("abc95 (growing to fit) width",t.id,d,t.size?.width,g);for(let y of t.children)y.size&&(y.size.width=g)}}t.size={width:d,height:p,x:0,y:0}}Y.debug("setBlockSizes abc94 (done)",t.id,t?.size?.x,t?.size?.width,t?.size?.y,t?.size?.height)}function Mye(t,e){Y.debug(`abc85 layout blocks (=>layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`);let r=t.columns??-1;if(Y.debug("layoutBlocks columns abc95",t.id,"=>",r,t),t.children&&t.children.length>0){let n=t?.children[0]?.size?.width??0,i=t.children.length*n+(t.children.length-1)*bi;Y.debug("widthOfChildren 88",i,"posX");let a=0;Y.debug("abc91 block?.size?.x",t.id,t?.size?.x);let s=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-bi,l=0;for(let u of t.children){let h=t;if(!u.size)continue;let{width:f,height:d}=u.size,{px:p,py:m}=xtt(r,a);if(m!=l&&(l=m,s=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-bi,Y.debug("New row in layout for block",t.id," and child ",u.id,l)),Y.debug(`abc89 layout blocks (child) id: ${u.id} Pos: ${a} (px, py) ${p},${m} (${h?.size?.x},${h?.size?.y}) parent: ${h.id} width: ${f}${bi}`),h.size){let g=f/2;u.size.x=s+bi+g,Y.debug(`abc91 layout blocks (calc) px, pyid:${u.id} startingPos=X${s} new startingPosX${u.size.x} ${g} padding=${bi} width=${f} halfWidth=${g} => x:${u.size.x} y:${u.size.y} ${u.widthInColumns} (width * (child?.w || 1)) / 2 ${f*(u?.widthInColumns??1)/2}`),s=u.size.x+g,u.size.y=h.size.y-h.size.height/2+m*(d+bi)+d/2+bi,Y.debug(`abc88 layout blocks (calc) px, pyid:${u.id}startingPosX${s}${bi}${g}=>x:${u.size.x}y:${u.size.y}${u.widthInColumns}(width * (child?.w || 1)) / 2${f*(u?.widthInColumns??1)/2}`)}u.children&&Mye(u,e),a+=u?.widthInColumns??1,Y.debug("abc88 columnsPos",u,a)}}Y.debug(`layout blocks (<==layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`)}function Iye(t,{minX:e,minY:r,maxX:n,maxY:i}={minX:0,minY:0,maxX:0,maxY:0}){if(t.size&&t.id!=="root"){let{x:a,y:s,width:l,height:u}=t.size;a-l/2<e&&(e=a-l/2),s-u/2<r&&(r=s-u/2),a+l/2>n&&(n=a+l/2),s+u/2>i&&(i=s+u/2)}if(t.children)for(let a of t.children)({minX:e,minY:r,maxX:n,maxY:i}=Iye(a,{minX:e,minY:r,maxX:n,maxY:i}));return{minX:e,minY:r,maxX:n,maxY:i}}function Oye(t){let e=t.getBlock("root");if(!e)return;eF(e,t,0,0),Mye(e,t),Y.debug("getBlocks",JSON.stringify(e,null,2));let{minX:r,minY:n,maxX:i,maxY:a}=Iye(e),s=a-n,l=i-r;return{x:r,y:n,width:l,height:s}}var bi,btt,Pye=N(()=>{"use strict";vt();zt();bi=me()?.block?.padding??8;o(xtt,"calculateBlockPosition");btt=o(t=>{let e=0,r=0;for(let n of t.children){let{width:i,height:a,x:s,y:l}=n.size??{width:0,height:0,x:0,y:0};Y.debug("getMaxChildSize abc95 child:",n.id,"width:",i,"height:",a,"x:",s,"y:",l,n.type),n.type!=="space"&&(i>e&&(e=i/(t.widthInColumns??1)),a>r&&(r=a))}return{width:e,height:r}},"getMaxChildSize");o(eF,"setBlockSizes");o(Mye,"layoutBlocks");o(Iye,"findBounds");o(Oye,"layout")});function Bye(t,e){e&&t.attr("style",e)}function wtt(t){let e=Ge(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),n=t.label,i=t.isNode?"nodeLabel":"edgeLabel",a=r.append("span");return a.html(n),Bye(a,t.labelStyle),a.attr("class",i),Bye(r,t.labelStyle),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}var Ttt,vs,rC=N(()=>{"use strict";dr();vt();zt();gr();ir();to();o(Bye,"applyStyle");o(wtt,"addHtmlLabel");Ttt=o((t,e,r,n)=>{let i=t||"";if(typeof i=="object"&&(i=i[0]),fr(me().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"<br />"),Y.debug("vertexText"+i);let a={isNode:n,label:DD(na(i)),labelStyle:e.replace("fill:","color:")};return wtt(a)}else{let a=document.createElementNS("http://www.w3.org/2000/svg","text");a.setAttribute("style",e.replace("color:","fill:"));let s=[];typeof i=="string"?s=i.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(i)?s=i:s=[];for(let l of s){let u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),r?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=l.trim(),a.appendChild(u)}return a}},"createLabel"),vs=Ttt});var $ye,ktt,Fye,zye=N(()=>{"use strict";vt();$ye=o((t,e,r,n,i)=>{e.arrowTypeStart&&Fye(t,"start",e.arrowTypeStart,r,n,i),e.arrowTypeEnd&&Fye(t,"end",e.arrowTypeEnd,r,n,i)},"addEdgeMarkers"),ktt={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},Fye=o((t,e,r,n,i,a)=>{let s=ktt[r];if(!s){Y.warn(`Unknown arrow type: ${r}`);return}let l=e==="start"?"Start":"End";t.attr(`marker-${e}`,`url(${n}#${i}_${a}-${s}${l})`)},"addEdgeMarker")});function nC(t,e){me().flowchart.htmlLabels&&t&&(t.style.width=e.length*9+"px",t.style.height="12px")}var tF,Ua,Vye,Uye,Ett,Stt,Gye,Hye,Wye=N(()=>{"use strict";vt();rC();to();dr();zt();ir();gr();JD();w2();zye();tF={},Ua={},Vye=o((t,e)=>{let r=me(),n=fr(r.flowchart.htmlLabels),i=e.labelType==="markdown"?Hn(t,e.label,{style:e.labelStyle,useHtmlLabels:n,addSvgBackground:!0},r):vs(e.label,e.labelStyle),a=t.insert("g").attr("class","edgeLabel"),s=a.insert("g").attr("class","label");s.node().appendChild(i);let l=i.getBBox();if(n){let h=i.children[0],f=Ge(i);l=h.getBoundingClientRect(),f.attr("width",l.width),f.attr("height",l.height)}s.attr("transform","translate("+-l.width/2+", "+-l.height/2+")"),tF[e.id]=a,e.width=l.width,e.height=l.height;let u;if(e.startLabelLeft){let h=vs(e.startLabelLeft,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),Ua[e.id]||(Ua[e.id]={}),Ua[e.id].startLeft=f,nC(u,e.startLabelLeft)}if(e.startLabelRight){let h=vs(e.startLabelRight,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=f.node().appendChild(h),d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),Ua[e.id]||(Ua[e.id]={}),Ua[e.id].startRight=f,nC(u,e.startLabelRight)}if(e.endLabelLeft){let h=vs(e.endLabelLeft,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),f.node().appendChild(h),Ua[e.id]||(Ua[e.id]={}),Ua[e.id].endLeft=f,nC(u,e.endLabelLeft)}if(e.endLabelRight){let h=vs(e.endLabelRight,e.labelStyle),f=t.insert("g").attr("class","edgeTerminals"),d=f.insert("g").attr("class","inner");u=d.node().appendChild(h);let p=h.getBBox();d.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),f.node().appendChild(h),Ua[e.id]||(Ua[e.id]={}),Ua[e.id].endRight=f,nC(u,e.endLabelRight)}return i},"insertEdgeLabel");o(nC,"setTerminalWidth");Uye=o((t,e)=>{Y.debug("Moving label abc88 ",t.id,t.label,tF[t.id],e);let r=e.updatedPath?e.updatedPath:e.originalPath,n=me(),{subGraphTitleTotalMargin:i}=Ru(n);if(t.label){let a=tF[t.id],s=t.x,l=t.y;if(r){let u=Gt.calcLabelPosition(r);Y.debug("Moving label "+t.label+" from (",s,",",l,") to (",u.x,",",u.y,") abc88"),e.updatedPath&&(s=u.x,l=u.y)}a.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){let a=Ua[t.id].startLeft,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.startLabelRight){let a=Ua[t.id].startRight,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelLeft){let a=Ua[t.id].endLeft,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}if(t.endLabelRight){let a=Ua[t.id].endRight,s=t.x,l=t.y;if(r){let u=Gt.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=u.x,l=u.y}a.attr("transform",`translate(${s}, ${l})`)}},"positionEdgeLabel"),Ett=o((t,e)=>{let r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),s=t.width/2,l=t.height/2;return i>=s||a>=l},"outsideNode"),Stt=o((t,e,r)=>{Y.debug(`intersection calc abc89:
+ outsidePoint: ${JSON.stringify(e)}
+ insidePoint : ${JSON.stringify(r)}
+ node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);let n=t.x,i=t.y,a=Math.abs(n-r.x),s=t.width/2,l=r.x<e.x?s-a:s+a,u=t.height/2,h=Math.abs(e.y-r.y),f=Math.abs(e.x-r.x);if(Math.abs(i-e.y)*s>Math.abs(n-e.x)*u){let d=r.y<e.y?e.y-u-i:i-u-e.y;l=f*d/h;let p={x:r.x<e.x?r.x+l:r.x-f+l,y:r.y<e.y?r.y+h-d:r.y-h+d};return l===0&&(p.x=e.x,p.y=e.y),f===0&&(p.x=e.x),h===0&&(p.y=e.y),Y.debug(`abc89 topp/bott calc, Q ${h}, q ${d}, R ${f}, r ${l}`,p),p}else{r.x<e.x?l=e.x-s-n:l=n-s-e.x;let d=h*l/f,p=r.x<e.x?r.x+f-l:r.x-f+l,m=r.y<e.y?r.y+d:r.y-d;return Y.debug(`sides calc abc89, Q ${h}, q ${d}, R ${f}, r ${l}`,{_x:p,_y:m}),l===0&&(p=e.x,m=e.y),f===0&&(p=e.x),h===0&&(m=e.y),{x:p,y:m}}},"intersection"),Gye=o((t,e)=>{Y.debug("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach(a=>{if(!Ett(e,a)&&!i){let s=Stt(e,n,a),l=!1;r.forEach(u=>{l=l||u.x===s.x&&u.y===s.y}),r.some(u=>u.x===s.x&&u.y===s.y)||r.push(s),i=!0}else n=a,i||r.push(a)}),r},"cutPathAtIntersect"),Hye=o(function(t,e,r,n,i,a,s){let l=r.points;Y.debug("abc88 InsertEdge: edge=",r,"e=",e);let u=!1,h=a.node(e.v);var f=a.node(e.w);f?.intersect&&h?.intersect&&(l=l.slice(1,r.points.length-1),l.unshift(h.intersect(l[0])),l.push(f.intersect(l[l.length-1]))),r.toCluster&&(Y.debug("to cluster abc88",n[r.toCluster]),l=Gye(r.points,n[r.toCluster].node),u=!0),r.fromCluster&&(Y.debug("from cluster abc88",n[r.fromCluster]),l=Gye(l.reverse(),n[r.fromCluster].node).reverse(),u=!0);let d=l.filter(C=>!Number.isNaN(C.y)),p=Do;r.curve&&(i==="graph"||i==="flowchart")&&(p=r.curve);let{x:m,y:g}=qw(r),y=wl().x(m).y(g).curve(p),v;switch(r.thickness){case"normal":v="edge-thickness-normal";break;case"thick":v="edge-thickness-thick";break;case"invisible":v="edge-thickness-thick";break;default:v=""}switch(r.pattern){case"solid":v+=" edge-pattern-solid";break;case"dotted":v+=" edge-pattern-dotted";break;case"dashed":v+=" edge-pattern-dashed";break}let x=t.append("path").attr("d",y(d)).attr("id",r.id).attr("class"," "+v+(r.classes?" "+r.classes:"")).attr("style",r.style),b="";(me().flowchart.arrowMarkerAbsolute||me().state.arrowMarkerAbsolute)&&(b=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,b=b.replace(/\(/g,"\\("),b=b.replace(/\)/g,"\\)")),$ye(x,r,b,s,i);let w={};return u&&(w.updatedPath=l),w.originalPath=r.points,w},"insertEdge")});var Ctt,qye,Yye=N(()=>{"use strict";Ctt=o(t=>{let e=new Set;for(let r of t)switch(r){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(r);break}return e},"expandAndDeduplicateDirections"),qye=o((t,e,r)=>{let n=Ctt(t),i=2,a=e.height+2*r.padding,s=a/i,l=e.width+2*s+r.padding,u=r.padding/2;return n.has("right")&&n.has("left")&&n.has("up")&&n.has("down")?[{x:0,y:0},{x:s,y:0},{x:l/2,y:2*u},{x:l-s,y:0},{x:l,y:0},{x:l,y:-a/3},{x:l+2*u,y:-a/2},{x:l,y:-2*a/3},{x:l,y:-a},{x:l-s,y:-a},{x:l/2,y:-a-2*u},{x:s,y:-a},{x:0,y:-a},{x:0,y:-2*a/3},{x:-2*u,y:-a/2},{x:0,y:-a/3}]:n.has("right")&&n.has("left")&&n.has("up")?[{x:s,y:0},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}]:n.has("right")&&n.has("left")&&n.has("down")?[{x:0,y:0},{x:s,y:-a},{x:l-s,y:-a},{x:l,y:0}]:n.has("right")&&n.has("up")&&n.has("down")?[{x:0,y:0},{x:l,y:-s},{x:l,y:-a+s},{x:0,y:-a}]:n.has("left")&&n.has("up")&&n.has("down")?[{x:l,y:0},{x:0,y:-s},{x:0,y:-a+s},{x:l,y:-a}]:n.has("right")&&n.has("left")?[{x:s,y:0},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a},{x:0,y:-a/2}]:n.has("up")&&n.has("down")?[{x:l/2,y:0},{x:0,y:-u},{x:s,y:-u},{x:s,y:-a+u},{x:0,y:-a+u},{x:l/2,y:-a},{x:l,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u},{x:l,y:-u}]:n.has("right")&&n.has("up")?[{x:0,y:0},{x:l,y:-s},{x:0,y:-a}]:n.has("right")&&n.has("down")?[{x:0,y:0},{x:l,y:0},{x:0,y:-a}]:n.has("left")&&n.has("up")?[{x:l,y:0},{x:0,y:-s},{x:l,y:-a}]:n.has("left")&&n.has("down")?[{x:l,y:0},{x:0,y:0},{x:l,y:-a}]:n.has("right")?[{x:s,y:-u},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a+u}]:n.has("left")?[{x:s,y:0},{x:s,y:-u},{x:l-s,y:-u},{x:l-s,y:-a+u},{x:s,y:-a+u},{x:s,y:-a},{x:0,y:-a/2}]:n.has("up")?[{x:s,y:-u},{x:s,y:-a+u},{x:0,y:-a+u},{x:l/2,y:-a},{x:l,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u}]:n.has("down")?[{x:l/2,y:0},{x:0,y:-u},{x:s,y:-u},{x:s,y:-a+u},{x:l-s,y:-a+u},{x:l-s,y:-u},{x:l,y:-u}]:[{x:0,y:0}]},"getArrowPoints")});function Att(t,e){return t.intersect(e)}var Xye,jye=N(()=>{"use strict";o(Att,"intersectNode");Xye=Att});function _tt(t,e,r,n){var i=t.x,a=t.y,s=i-n.x,l=a-n.y,u=Math.sqrt(e*e*l*l+r*r*s*s),h=Math.abs(e*r*s/u);n.x<i&&(h=-h);var f=Math.abs(e*r*l/u);return n.y<a&&(f=-f),{x:i+h,y:a+f}}var iC,rF=N(()=>{"use strict";o(_tt,"intersectEllipse");iC=_tt});function Dtt(t,e,r){return iC(t,e,e,r)}var Kye,Qye=N(()=>{"use strict";rF();o(Dtt,"intersectCircle");Kye=Dtt});function Ltt(t,e,r,n){var i,a,s,l,u,h,f,d,p,m,g,y,v,x,b;if(i=e.y-t.y,s=t.x-e.x,u=e.x*t.y-t.x*e.y,p=i*r.x+s*r.y+u,m=i*n.x+s*n.y+u,!(p!==0&&m!==0&&Zye(p,m))&&(a=n.y-r.y,l=r.x-n.x,h=n.x*r.y-r.x*n.y,f=a*t.x+l*t.y+h,d=a*e.x+l*e.y+h,!(f!==0&&d!==0&&Zye(f,d))&&(g=i*l-a*s,g!==0)))return y=Math.abs(g/2),v=s*h-l*u,x=v<0?(v-y)/g:(v+y)/g,v=a*u-i*h,b=v<0?(v-y)/g:(v+y)/g,{x,y:b}}function Zye(t,e){return t*e>0}var Jye,eve=N(()=>{"use strict";o(Ltt,"intersectLine");o(Zye,"sameSign");Jye=Ltt});function Rtt(t,e,r){var n=t.x,i=t.y,a=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;typeof e.forEach=="function"?e.forEach(function(g){s=Math.min(s,g.x),l=Math.min(l,g.y)}):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var u=n-t.width/2-s,h=i-t.height/2-l,f=0;f<e.length;f++){var d=e[f],p=e[f<e.length-1?f+1:0],m=Jye(t,r,{x:u+d.x,y:h+d.y},{x:u+p.x,y:h+p.y});m&&a.push(m)}return a.length?(a.length>1&&a.sort(function(g,y){var v=g.x-r.x,x=g.y-r.y,b=Math.sqrt(v*v+x*x),w=y.x-r.x,C=y.y-r.y,T=Math.sqrt(w*w+C*C);return b<T?-1:b===T?0:1}),a[0]):t}var tve,rve=N(()=>{"use strict";eve();tve=Rtt;o(Rtt,"intersectPolygon")});var Ntt,nve,ive=N(()=>{"use strict";Ntt=o((t,e)=>{var r=t.x,n=t.y,i=e.x-r,a=e.y-n,s=t.width/2,l=t.height/2,u,h;return Math.abs(a)*s>Math.abs(i)*l?(a<0&&(l=-l),u=a===0?0:l*i/a,h=l):(i<0&&(s=-s),u=s,h=i===0?0:s*a/i),{x:r+u,y:n+h}},"intersectRect"),nve=Ntt});var In,nF=N(()=>{"use strict";jye();Qye();rF();rve();ive();In={node:Xye,circle:Kye,ellipse:iC,polygon:tve,rect:nve}});function Hl(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map(function(i){return i.x+","+i.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}var Di,Qn,iF=N(()=>{"use strict";rC();to();zt();dr();gr();ir();Di=o(async(t,e,r,n)=>{let i=me(),a,s=e.useHtmlLabels||fr(i.flowchart.htmlLabels);r?a=r:a="node default";let l=t.insert("g").attr("class",a).attr("id",e.domId||e.id),u=l.insert("g").attr("class","label").attr("style",e.labelStyle),h;e.labelText===void 0?h="":h=typeof e.labelText=="string"?e.labelText:e.labelText[0];let f=u.node(),d;e.labelType==="markdown"?d=Hn(u,Tr(na(h),i),{useHtmlLabels:s,width:e.width||i.flowchart.wrappingWidth,classes:"markdown-node-label"},i):d=f.appendChild(vs(Tr(na(h),i),e.labelStyle,!1,n));let p=d.getBBox(),m=e.padding/2;if(fr(i.flowchart.htmlLabels)){let g=d.children[0],y=Ge(d),v=g.getElementsByTagName("img");if(v){let x=h.replace(/<img[^>]*>/g,"").trim()==="";await Promise.all([...v].map(b=>new Promise(w=>{function C(){if(b.style.display="flex",b.style.flexDirection="column",x){let T=i.fontSize?i.fontSize:window.getComputedStyle(document.body).fontSize,A=parseInt(T,10)*5+"px";b.style.minWidth=A,b.style.maxWidth=A}else b.style.width="100%";w(b)}o(C,"setupImage"),setTimeout(()=>{b.complete&&C()}),b.addEventListener("error",C),b.addEventListener("load",C)})))}p=g.getBoundingClientRect(),y.attr("width",p.width),y.attr("height",p.height)}return s?u.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"):u.attr("transform","translate(0, "+-p.height/2+")"),e.centerLabel&&u.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),u.insert("rect",":first-child"),{shapeSvg:l,bbox:p,halfPadding:m,label:u}},"labelHelper"),Qn=o((t,e)=>{let r=e.node().getBBox();t.width=r.width,t.height=r.height},"updateNodeBounds");o(Hl,"insertPolygonShape")});var Mtt,ave,sve=N(()=>{"use strict";iF();vt();zt();nF();Mtt=o(async(t,e)=>{e.useHtmlLabels||me().flowchart.htmlLabels||(e.centerLabel=!0);let{shapeSvg:n,bbox:i,halfPadding:a}=await Di(t,e,"node "+e.classes,!0);Y.info("Classes = ",e.classes);let s=n.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-a).attr("y",-i.height/2-a).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Qn(e,s),e.intersect=function(l){return In.rect(e,l)},n},"note"),ave=Mtt});function aF(t,e,r,n){let i=[],a=o(l=>{i.push(l,0)},"addBorder"),s=o(l=>{i.push(0,l)},"skipBorder");e.includes("t")?(Y.debug("add top border"),a(r)):s(r),e.includes("r")?(Y.debug("add right border"),a(n)):s(n),e.includes("b")?(Y.debug("add bottom border"),a(r)):s(r),e.includes("l")?(Y.debug("add left border"),a(n)):s(n),t.attr("stroke-dasharray",i.join(" "))}var ove,yo,lve,Itt,Ott,Ptt,Btt,Ftt,$tt,ztt,Gtt,Vtt,Utt,Htt,Wtt,qtt,Ytt,Xtt,jtt,Ktt,Qtt,Ztt,cve,Jtt,ert,uve,aC,sF,hve,fve=N(()=>{"use strict";dr();zt();gr();vt();Yye();rC();nF();sve();iF();ove=o(t=>t?" "+t:"","formatClass"),yo=o((t,e)=>`${e||"node default"}${ove(t.classes)} ${ove(t.class)}`,"getClassesFromNode"),lve=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=i+a,l=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];Y.info("Question main (Circle)");let u=Hl(r,s,s,l);return u.attr("style",e.style),Qn(e,u),e.intersect=function(h){return Y.warn("Intersect called"),In.polygon(e,l,h)},r},"question"),Itt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=28,i=[{x:0,y:n/2},{x:n/2,y:0},{x:0,y:-n/2},{x:-n/2,y:0}];return r.insert("polygon",":first-child").attr("points",i.map(function(s){return s.x+","+s.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(s){return In.circle(e,14,s)},r},"choice"),Ott=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=4,a=n.height+e.padding,s=a/i,l=n.width+2*s+e.padding,u=[{x:s,y:0},{x:l-s,y:0},{x:l,y:-a/2},{x:l-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}],h=Hl(r,l,a,u);return h.attr("style",e.style),Qn(e,h),e.intersect=function(f){return In.polygon(e,u,f)},r},"hexagon"),Ptt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,void 0,!0),i=2,a=n.height+2*e.padding,s=a/i,l=n.width+2*s+e.padding,u=qye(e.directions,n,e),h=Hl(r,l,a,u);return h.attr("style",e.style),Qn(e,h),e.intersect=function(f){return In.polygon(e,u,f)},r},"block_arrow"),Btt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-a/2,y:0},{x:i,y:0},{x:i,y:-a},{x:-a/2,y:-a},{x:0,y:-a/2}];return Hl(r,i,a,s).attr("style",e.style),e.width=i+a,e.height=a,e.intersect=function(u){return In.polygon(e,s,u)},r},"rect_left_inv_arrow"),Ftt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-2*a/6,y:0},{x:i-a/6,y:0},{x:i+2*a/6,y:-a},{x:a/6,y:-a}],l=Hl(r,i,a,s);return l.attr("style",e.style),Qn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"lean_right"),$tt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:2*a/6,y:0},{x:i+a/6,y:0},{x:i-2*a/6,y:-a},{x:-a/6,y:-a}],l=Hl(r,i,a,s);return l.attr("style",e.style),Qn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"lean_left"),ztt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:-2*a/6,y:0},{x:i+2*a/6,y:0},{x:i-a/6,y:-a},{x:a/6,y:-a}],l=Hl(r,i,a,s);return l.attr("style",e.style),Qn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"trapezoid"),Gtt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:a/6,y:0},{x:i-a/6,y:0},{x:i+2*a/6,y:-a},{x:-2*a/6,y:-a}],l=Hl(r,i,a,s);return l.attr("style",e.style),Qn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"inv_trapezoid"),Vtt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:0,y:0},{x:i+a/2,y:0},{x:i,y:-a/2},{x:i+a/2,y:-a},{x:0,y:-a}],l=Hl(r,i,a,s);return l.attr("style",e.style),Qn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"rect_right_inv_arrow"),Utt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=i/2,s=a/(2.5+i/50),l=n.height+s+e.padding,u="M 0,"+s+" a "+a+","+s+" 0,0,0 "+i+" 0 a "+a+","+s+" 0,0,0 "+-i+" 0 l 0,"+l+" a "+a+","+s+" 0,0,0 "+i+" 0 l 0,"+-l,h=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",u).attr("transform","translate("+-i/2+","+-(l/2+s)+")");return Qn(e,h),e.intersect=function(f){let d=In.rect(e,f),p=d.x-e.x;if(a!=0&&(Math.abs(p)<e.width/2||Math.abs(p)==e.width/2&&Math.abs(d.y-e.y)>e.height/2-s)){let m=s*s*(1-p*p/(a*a));m!=0&&(m=Math.sqrt(m)),m=s-m,f.y-e.y>0&&(m=-m),d.y+=m}return d},r},"cylinder"),Htt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Di(t,e,"node "+e.classes+" "+e.class,!0),a=r.insert("rect",":first-child"),s=e.positioned?e.width:n.width+e.padding,l=e.positioned?e.height:n.height+e.padding,u=e.positioned?-s/2:-n.width/2-i,h=e.positioned?-l/2:-n.height/2-i;if(a.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",u).attr("y",h).attr("width",s).attr("height",l),e.props){let f=new Set(Object.keys(e.props));e.props.borders&&(aF(a,e.props.borders,s,l),f.delete("borders")),f.forEach(d=>{Y.warn(`Unknown node property ${d}`)})}return Qn(e,a),e.intersect=function(f){return In.rect(e,f)},r},"rect"),Wtt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Di(t,e,"node "+e.classes,!0),a=r.insert("rect",":first-child"),s=e.positioned?e.width:n.width+e.padding,l=e.positioned?e.height:n.height+e.padding,u=e.positioned?-s/2:-n.width/2-i,h=e.positioned?-l/2:-n.height/2-i;if(a.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",u).attr("y",h).attr("width",s).attr("height",l),e.props){let f=new Set(Object.keys(e.props));e.props.borders&&(aF(a,e.props.borders,s,l),f.delete("borders")),f.forEach(d=>{Y.warn(`Unknown node property ${d}`)})}return Qn(e,a),e.intersect=function(f){return In.rect(e,f)},r},"composite"),qtt=o(async(t,e)=>{let{shapeSvg:r}=await Di(t,e,"label",!0);Y.trace("Classes = ",e.class);let n=r.insert("rect",":first-child"),i=0,a=0;if(n.attr("width",i).attr("height",a),r.attr("class","label edgeLabel"),e.props){let s=new Set(Object.keys(e.props));e.props.borders&&(aF(n,e.props.borders,i,a),s.delete("borders")),s.forEach(l=>{Y.warn(`Unknown node property ${l}`)})}return Qn(e,n),e.intersect=function(s){return In.rect(e,s)},r},"labelRect");o(aF,"applyNodePropertyBorders");Ytt=o((t,e)=>{let r;e.classes?r="node "+e.classes:r="node default";let n=t.insert("g").attr("class",r).attr("id",e.domId||e.id),i=n.insert("rect",":first-child"),a=n.insert("line"),s=n.insert("g").attr("class","label"),l=e.labelText.flat?e.labelText.flat():e.labelText,u="";typeof l=="object"?u=l[0]:u=l,Y.info("Label text abc79",u,l,typeof l=="object");let h=s.node().appendChild(vs(u,e.labelStyle,!0,!0)),f={width:0,height:0};if(fr(me().flowchart.htmlLabels)){let y=h.children[0],v=Ge(h);f=y.getBoundingClientRect(),v.attr("width",f.width),v.attr("height",f.height)}Y.info("Text 2",l);let d=l.slice(1,l.length),p=h.getBBox(),m=s.node().appendChild(vs(d.join?d.join("<br/>"):d,e.labelStyle,!0,!0));if(fr(me().flowchart.htmlLabels)){let y=m.children[0],v=Ge(m);f=y.getBoundingClientRect(),v.attr("width",f.width),v.attr("height",f.height)}let g=e.padding/2;return Ge(m).attr("transform","translate( "+(f.width>p.width?0:(p.width-f.width)/2)+", "+(p.height+g+5)+")"),Ge(h).attr("transform","translate( "+(f.width<p.width?0:-(p.width-f.width)/2)+", 0)"),f=s.node().getBBox(),s.attr("transform","translate("+-f.width/2+", "+(-f.height/2-g+3)+")"),i.attr("class","outer title-state").attr("x",-f.width/2-g).attr("y",-f.height/2-g).attr("width",f.width+e.padding).attr("height",f.height+e.padding),a.attr("class","divider").attr("x1",-f.width/2-g).attr("x2",f.width/2+g).attr("y1",-f.height/2-g+p.height+g).attr("y2",-f.height/2-g+p.height+g),Qn(e,i),e.intersect=function(y){return In.rect(e,y)},n},"rectWithTitle"),Xtt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.height+e.padding,a=n.width+i/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",i/2).attr("ry",i/2).attr("x",-a/2).attr("y",-i/2).attr("width",a).attr("height",i);return Qn(e,s),e.intersect=function(l){return In.rect(e,l)},r},"stadium"),jtt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Di(t,e,yo(e,void 0),!0),a=r.insert("circle",":first-child");return a.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),Y.info("Circle main"),Qn(e,a),e.intersect=function(s){return Y.info("Circle intersect",e,n.width/2+i,s),In.circle(e,n.width/2+i,s)},r},"circle"),Ktt=o(async(t,e)=>{let{shapeSvg:r,bbox:n,halfPadding:i}=await Di(t,e,yo(e,void 0),!0),a=5,s=r.insert("g",":first-child"),l=s.insert("circle"),u=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+a).attr("width",n.width+e.padding+a*2).attr("height",n.height+e.padding+a*2),u.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),Y.info("DoubleCircle main"),Qn(e,l),e.intersect=function(h){return Y.info("DoubleCircle intersect",e,n.width/2+i+a,h),In.circle(e,n.width/2+i+a,h)},r},"doublecircle"),Qtt=o(async(t,e)=>{let{shapeSvg:r,bbox:n}=await Di(t,e,yo(e,void 0),!0),i=n.width+e.padding,a=n.height+e.padding,s=[{x:0,y:0},{x:i,y:0},{x:i,y:-a},{x:0,y:-a},{x:0,y:0},{x:-8,y:0},{x:i+8,y:0},{x:i+8,y:-a},{x:-8,y:-a},{x:-8,y:0}],l=Hl(r,i,a,s);return l.attr("style",e.style),Qn(e,l),e.intersect=function(u){return In.polygon(e,s,u)},r},"subroutine"),Ztt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),Qn(e,n),e.intersect=function(i){return In.circle(e,7,i)},r},"start"),cve=o((t,e,r)=>{let n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=70,a=10;r==="LR"&&(i=10,a=70);let s=n.append("rect").attr("x",-1*i/2).attr("y",-1*a/2).attr("width",i).attr("height",a).attr("class","fork-join");return Qn(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(l){return In.rect(e,l)},n},"forkJoin"),Jtt=o((t,e)=>{let r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),n=r.insert("circle",":first-child"),i=r.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),n.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),Qn(e,i),e.intersect=function(a){return In.circle(e,7,a)},r},"end"),ert=o((t,e)=>{let r=e.padding/2,n=4,i=8,a;e.classes?a="node "+e.classes:a="node default";let s=t.insert("g").attr("class",a).attr("id",e.domId||e.id),l=s.insert("rect",":first-child"),u=s.insert("line"),h=s.insert("line"),f=0,d=n,p=s.insert("g").attr("class","label"),m=0,g=e.classData.annotations?.[0],y=e.classData.annotations[0]?"\xAB"+e.classData.annotations[0]+"\xBB":"",v=p.node().appendChild(vs(y,e.labelStyle,!0,!0)),x=v.getBBox();if(fr(me().flowchart.htmlLabels)){let S=v.children[0],_=Ge(v);x=S.getBoundingClientRect(),_.attr("width",x.width),_.attr("height",x.height)}e.classData.annotations[0]&&(d+=x.height+n,f+=x.width);let b=e.classData.label;e.classData.type!==void 0&&e.classData.type!==""&&(me().flowchart.htmlLabels?b+="&lt;"+e.classData.type+"&gt;":b+="<"+e.classData.type+">");let w=p.node().appendChild(vs(b,e.labelStyle,!0,!0));Ge(w).attr("class","classTitle");let C=w.getBBox();if(fr(me().flowchart.htmlLabels)){let S=w.children[0],_=Ge(w);C=S.getBoundingClientRect(),_.attr("width",C.width),_.attr("height",C.height)}d+=C.height+n,C.width>f&&(f=C.width);let T=[];e.classData.members.forEach(S=>{let _=S.getDisplayDetails(),I=_.displayText;me().flowchart.htmlLabels&&(I=I.replace(/</g,"&lt;").replace(/>/g,"&gt;"));let D=p.node().appendChild(vs(I,_.cssStyle?_.cssStyle:e.labelStyle,!0,!0)),k=D.getBBox();if(fr(me().flowchart.htmlLabels)){let L=D.children[0],R=Ge(D);k=L.getBoundingClientRect(),R.attr("width",k.width),R.attr("height",k.height)}k.width>f&&(f=k.width),d+=k.height+n,T.push(D)}),d+=i;let E=[];if(e.classData.methods.forEach(S=>{let _=S.getDisplayDetails(),I=_.displayText;me().flowchart.htmlLabels&&(I=I.replace(/</g,"&lt;").replace(/>/g,"&gt;"));let D=p.node().appendChild(vs(I,_.cssStyle?_.cssStyle:e.labelStyle,!0,!0)),k=D.getBBox();if(fr(me().flowchart.htmlLabels)){let L=D.children[0],R=Ge(D);k=L.getBoundingClientRect(),R.attr("width",k.width),R.attr("height",k.height)}k.width>f&&(f=k.width),d+=k.height+n,E.push(D)}),d+=i,g){let S=(f-x.width)/2;Ge(v).attr("transform","translate( "+(-1*f/2+S)+", "+-1*d/2+")"),m=x.height+n}let A=(f-C.width)/2;return Ge(w).attr("transform","translate( "+(-1*f/2+A)+", "+(-1*d/2+m)+")"),m+=C.height+n,u.attr("class","divider").attr("x1",-f/2-r).attr("x2",f/2+r).attr("y1",-d/2-r+i+m).attr("y2",-d/2-r+i+m),m+=i,T.forEach(S=>{Ge(S).attr("transform","translate( "+-f/2+", "+(-1*d/2+m+i/2)+")");let _=S?.getBBox();m+=(_?.height??0)+n}),m+=i,h.attr("class","divider").attr("x1",-f/2-r).attr("x2",f/2+r).attr("y1",-d/2-r+i+m).attr("y2",-d/2-r+i+m),m+=i,E.forEach(S=>{Ge(S).attr("transform","translate( "+-f/2+", "+(-1*d/2+m)+")");let _=S?.getBBox();m+=(_?.height??0)+n}),l.attr("style",e.style).attr("class","outer title-state").attr("x",-f/2-r).attr("y",-(d/2)-r).attr("width",f+e.padding).attr("height",d+e.padding),Qn(e,l),e.intersect=function(S){return In.rect(e,S)},s},"class_box"),uve={rhombus:lve,composite:Wtt,question:lve,rect:Htt,labelRect:qtt,rectWithTitle:Ytt,choice:Itt,circle:jtt,doublecircle:Ktt,stadium:Xtt,hexagon:Ott,block_arrow:Ptt,rect_left_inv_arrow:Btt,lean_right:Ftt,lean_left:$tt,trapezoid:ztt,inv_trapezoid:Gtt,rect_right_inv_arrow:Vtt,cylinder:Utt,start:Ztt,end:Jtt,note:ave,subroutine:Qtt,fork:cve,join:cve,class_box:ert},aC={},sF=o(async(t,e,r)=>{let n,i;if(e.link){let a;me().securityLevel==="sandbox"?a="_top":e.linkTarget&&(a=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",a),i=await uve[e.shape](n,e,r)}else i=await uve[e.shape](t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),aC[e.id]=n,e.haveCallback&&aC[e.id].attr("class",aC[e.id].attr("class")+" clickable"),n},"insertNode"),hve=o(t=>{let e=aC[t.id];Y.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");let r=8,n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-r)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},"positionNode")});function dve(t,e,r=!1){let n=t,i="default";(n?.classes?.length||0)>0&&(i=(n?.classes??[]).join(" ")),i=i+" flowchart-label";let a=0,s="",l;switch(n.type){case"round":a=5,s="rect";break;case"composite":a=0,s="composite",l=0;break;case"square":s="rect";break;case"diamond":s="question";break;case"hexagon":s="hexagon";break;case"block_arrow":s="block_arrow";break;case"odd":s="rect_left_inv_arrow";break;case"lean_right":s="lean_right";break;case"lean_left":s="lean_left";break;case"trapezoid":s="trapezoid";break;case"inv_trapezoid":s="inv_trapezoid";break;case"rect_left_inv_arrow":s="rect_left_inv_arrow";break;case"circle":s="circle";break;case"ellipse":s="ellipse";break;case"stadium":s="stadium";break;case"subroutine":s="subroutine";break;case"cylinder":s="cylinder";break;case"group":s="rect";break;case"doublecircle":s="doublecircle";break;default:s="rect"}let u=Y9(n?.styles??[]),h=n.label,f=n.size??{width:0,height:0,x:0,y:0};return{labelStyle:u.labelStyle,shape:s,labelText:h,rx:a,ry:a,class:i,style:u.style,id:n.id,directions:n.directions,width:f.width,height:f.height,x:f.x,y:f.y,positioned:r,intersect:void 0,type:n.type,padding:l??cr()?.block?.padding??0}}async function trt(t,e,r){let n=dve(e,r,!1);if(n.type==="group")return;let i=cr(),a=await sF(t,n,{config:i}),s=a.node().getBBox(),l=r.getBlock(n.id);l.size={width:s.width,height:s.height,x:0,y:0,node:a},r.setBlock(l),a.remove()}async function rrt(t,e,r){let n=dve(e,r,!0);if(r.getBlock(n.id).type!=="space"){let a=cr();await sF(t,n,{config:a}),e.intersect=n?.intersect,hve(n)}}async function oF(t,e,r,n){for(let i of e)await n(t,i,r),i.children&&await oF(t,i.children,r,n)}async function pve(t,e,r){await oF(t,e,r,trt)}async function mve(t,e,r){await oF(t,e,r,rrt)}async function gve(t,e,r,n,i){let a=new sn({multigraph:!0,compound:!0});a.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(let s of r)s.size&&a.setNode(s.id,{width:s.size.width,height:s.size.height,intersect:s.intersect});for(let s of e)if(s.start&&s.end){let l=n.getBlock(s.start),u=n.getBlock(s.end);if(l?.size&&u?.size){let h=l.size,f=u.size,d=[{x:h.x,y:h.y},{x:h.x+(f.x-h.x)/2,y:h.y+(f.y-h.y)/2},{x:f.x,y:f.y}];Hye(t,{v:s.start,w:s.end,name:s.id},{...s,arrowTypeEnd:s.arrowTypeEnd,arrowTypeStart:s.arrowTypeStart,points:d,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",a,i),s.label&&(await Vye(t,{...s,label:s.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:s.arrowTypeEnd,arrowTypeStart:s.arrowTypeStart,points:d,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),Uye({...s,x:d[1].x,y:d[1].y},{originalPath:d}))}}}var yve=N(()=>{"use strict";Vo();ji();Wye();fve();ir();o(dve,"getNodeFromBlock");o(trt,"calculateBlockSize");o(rrt,"insertBlockPositioned");o(oF,"performOperations");o(pve,"calculateBlockSizes");o(mve,"insertBlocks");o(gve,"insertEdges")});var nrt,irt,vve,xve=N(()=>{"use strict";dr();ji();Nye();vt();Ei();Pye();yve();nrt=o(function(t,e){return e.db.getClasses()},"getClasses"),irt=o(async function(t,e,r,n){let{securityLevel:i,block:a}=cr(),s=n.db,l;i==="sandbox"&&(l=Ge("#i"+e));let u=i==="sandbox"?Ge(l.nodes()[0].contentDocument.body):Ge("body"),h=i==="sandbox"?u.select(`[id="${e}"]`):Ge(`[id="${e}"]`);Rye(h,["point","circle","cross"],n.type,e);let d=s.getBlocks(),p=s.getBlocksFlat(),m=s.getEdges(),g=h.insert("g").attr("class","block");await pve(g,d,s);let y=Oye(s);if(await mve(g,d,s),await gve(g,m,p,s,e),y){let v=y,x=Math.max(1,Math.round(.125*(v.width/v.height))),b=v.height+x+10,w=v.width+10,{useMaxWidth:C}=a;vn(h,b,w,!!C),Y.debug("Here Bounds",y,v),h.attr("viewBox",`${v.x-5} ${v.y-5} ${v.width+10} ${v.height+10}`)}},"draw"),vve={draw:irt,getClasses:nrt}});var bve={};hr(bve,{diagram:()=>art});var art,wve=N(()=>{"use strict";wye();_ye();Lye();xve();art={parser:bye,db:Aye,renderer:vve,styles:Dye}});var lF,cF,v4,Eve,uF,Ha,Zc,x4,Sve,crt,b4,Cve,Ave,_ve,Dve,Lve,sC,Ff,oC=N(()=>{"use strict";lF={L:"left",R:"right",T:"top",B:"bottom"},cF={L:o(t=>`${t},${t/2} 0,${t} 0,0`,"L"),R:o(t=>`0,${t/2} ${t},0 ${t},${t}`,"R"),T:o(t=>`0,0 ${t},0 ${t/2},${t}`,"T"),B:o(t=>`${t/2},0 ${t},${t} 0,${t}`,"B")},v4={L:o((t,e)=>t-e+2,"L"),R:o((t,e)=>t-2,"R"),T:o((t,e)=>t-e+2,"T"),B:o((t,e)=>t-2,"B")},Eve=o(function(t){return Ha(t)?t==="L"?"R":"L":t==="T"?"B":"T"},"getOppositeArchitectureDirection"),uF=o(function(t){let e=t;return e==="L"||e==="R"||e==="T"||e==="B"},"isArchitectureDirection"),Ha=o(function(t){let e=t;return e==="L"||e==="R"},"isArchitectureDirectionX"),Zc=o(function(t){let e=t;return e==="T"||e==="B"},"isArchitectureDirectionY"),x4=o(function(t,e){let r=Ha(t)&&Zc(e),n=Zc(t)&&Ha(e);return r||n},"isArchitectureDirectionXY"),Sve=o(function(t){let e=t[0],r=t[1],n=Ha(e)&&Zc(r),i=Zc(e)&&Ha(r);return n||i},"isArchitecturePairXY"),crt=o(function(t){return t!=="LL"&&t!=="RR"&&t!=="TT"&&t!=="BB"},"isValidArchitectureDirectionPair"),b4=o(function(t,e){let r=`${t}${e}`;return crt(r)?r:void 0},"getArchitectureDirectionPair"),Cve=o(function([t,e],r){let n=r[0],i=r[1];return Ha(n)?Zc(i)?[t+(n==="L"?-1:1),e+(i==="T"?1:-1)]:[t+(n==="L"?-1:1),e]:Ha(i)?[t+(i==="L"?1:-1),e+(n==="T"?1:-1)]:[t,e+(n==="T"?1:-1)]},"shiftPositionByArchitectureDirectionPair"),Ave=o(function(t){return t==="LT"||t==="TL"?[1,1]:t==="BL"||t==="LB"?[1,-1]:t==="BR"||t==="RB"?[-1,-1]:[-1,1]},"getArchitectureDirectionXYFactors"),_ve=o(function(t,e){return x4(t,e)?"bend":Ha(t)?"horizontal":"vertical"},"getArchitectureDirectionAlignment"),Dve=o(function(t){return t.type==="service"},"isArchitectureService"),Lve=o(function(t){return t.type==="junction"},"isArchitectureJunction"),sC=o(t=>t.data(),"edgeData"),Ff=o(t=>t.data(),"nodeData")});function Li(t){let e=me().architecture;return e?.[t]?e[t]:Rve[t]}var Rve,vr,urt,hrt,frt,drt,prt,mrt,hF,grt,yrt,vrt,xrt,brt,wrt,Trt,Qp,w4=N(()=>{"use strict";Ya();zt();s6();mi();oC();Rve=or.architecture,vr=new pf(()=>({nodes:{},groups:{},edges:[],registeredIds:{},config:Rve,dataStructures:void 0,elements:{}})),urt=o(()=>{vr.reset(),Ar()},"clear"),hrt=o(function({id:t,icon:e,in:r,title:n,iconText:i}){if(vr.records.registeredIds[t]!==void 0)throw new Error(`The service id [${t}] is already in use by another ${vr.records.registeredIds[t]}`);if(r!==void 0){if(t===r)throw new Error(`The service [${t}] cannot be placed within itself`);if(vr.records.registeredIds[r]===void 0)throw new Error(`The service [${t}]'s parent does not exist. Please make sure the parent is created before this service`);if(vr.records.registeredIds[r]==="node")throw new Error(`The service [${t}]'s parent is not a group`)}vr.records.registeredIds[t]="node",vr.records.nodes[t]={id:t,type:"service",icon:e,iconText:i,title:n,edges:[],in:r}},"addService"),frt=o(()=>Object.values(vr.records.nodes).filter(Dve),"getServices"),drt=o(function({id:t,in:e}){vr.records.registeredIds[t]="node",vr.records.nodes[t]={id:t,type:"junction",edges:[],in:e}},"addJunction"),prt=o(()=>Object.values(vr.records.nodes).filter(Lve),"getJunctions"),mrt=o(()=>Object.values(vr.records.nodes),"getNodes"),hF=o(t=>vr.records.nodes[t],"getNode"),grt=o(function({id:t,icon:e,in:r,title:n}){if(vr.records.registeredIds[t]!==void 0)throw new Error(`The group id [${t}] is already in use by another ${vr.records.registeredIds[t]}`);if(r!==void 0){if(t===r)throw new Error(`The group [${t}] cannot be placed within itself`);if(vr.records.registeredIds[r]===void 0)throw new Error(`The group [${t}]'s parent does not exist. Please make sure the parent is created before this group`);if(vr.records.registeredIds[r]==="node")throw new Error(`The group [${t}]'s parent is not a group`)}vr.records.registeredIds[t]="group",vr.records.groups[t]={id:t,icon:e,title:n,in:r}},"addGroup"),yrt=o(()=>Object.values(vr.records.groups),"getGroups"),vrt=o(function({lhsId:t,rhsId:e,lhsDir:r,rhsDir:n,lhsInto:i,rhsInto:a,lhsGroup:s,rhsGroup:l,title:u}){if(!uF(r))throw new Error(`Invalid direction given for left hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${r}`);if(!uF(n))throw new Error(`Invalid direction given for right hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${n}`);if(vr.records.nodes[t]===void 0&&vr.records.groups[t]===void 0)throw new Error(`The left-hand id [${t}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(vr.records.nodes[e]===void 0&&vr.records.groups[t]===void 0)throw new Error(`The right-hand id [${e}] does not yet exist. Please create the service/group before declaring an edge to it.`);let h=vr.records.nodes[t].in,f=vr.records.nodes[e].in;if(s&&h&&f&&h==f)throw new Error(`The left-hand id [${t}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(l&&h&&f&&h==f)throw new Error(`The right-hand id [${e}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);let d={lhsId:t,lhsDir:r,lhsInto:i,lhsGroup:s,rhsId:e,rhsDir:n,rhsInto:a,rhsGroup:l,title:u};vr.records.edges.push(d),vr.records.nodes[t]&&vr.records.nodes[e]&&(vr.records.nodes[t].edges.push(vr.records.edges[vr.records.edges.length-1]),vr.records.nodes[e].edges.push(vr.records.edges[vr.records.edges.length-1]))},"addEdge"),xrt=o(()=>vr.records.edges,"getEdges"),brt=o(()=>{if(vr.records.dataStructures===void 0){let t={},e=Object.entries(vr.records.nodes).reduce((l,[u,h])=>(l[u]=h.edges.reduce((f,d)=>{let p=hF(d.lhsId)?.in,m=hF(d.rhsId)?.in;if(p&&m&&p!==m){let g=_ve(d.lhsDir,d.rhsDir);g!=="bend"&&(t[p]??={},t[p][m]=g,t[m]??={},t[m][p]=g)}if(d.lhsId===u){let g=b4(d.lhsDir,d.rhsDir);g&&(f[g]=d.rhsId)}else{let g=b4(d.rhsDir,d.lhsDir);g&&(f[g]=d.lhsId)}return f},{}),l),{}),r=Object.keys(e)[0],n={[r]:1},i=Object.keys(e).reduce((l,u)=>u===r?l:{...l,[u]:1},{}),a=o(l=>{let u={[l]:[0,0]},h=[l];for(;h.length>0;){let f=h.shift();if(f){n[f]=1,delete i[f];let d=e[f],[p,m]=u[f];Object.entries(d).forEach(([g,y])=>{n[y]||(u[y]=Cve([p,m],g),h.push(y))})}}return u},"BFS"),s=[a(r)];for(;Object.keys(i).length>0;)s.push(a(Object.keys(i)[0]));vr.records.dataStructures={adjList:e,spatialMaps:s,groupAlignments:t}}return vr.records.dataStructures},"getDataStructures"),wrt=o((t,e)=>{vr.records.elements[t]=e},"setElementForId"),Trt=o(t=>vr.records.elements[t],"getElementById"),Qp={clear:urt,setDiagramTitle:$r,getDiagramTitle:Ir,setAccTitle:Lr,getAccTitle:Rr,setAccDescription:Nr,getAccDescription:Mr,addService:hrt,getServices:frt,addJunction:drt,getJunctions:prt,getNodes:mrt,getNode:hF,addGroup:grt,getGroups:yrt,addEdge:vrt,getEdges:xrt,setElementForId:wrt,getElementById:Trt,getDataStructures:brt};o(Li,"getConfigField")});var krt,Nve,Mve=N(()=>{"use strict";kp();vt();T1();w4();krt=o((t,e)=>{$c(t,e),t.groups.map(e.addGroup),t.services.map(r=>e.addService({...r,type:"service"})),t.junctions.map(r=>e.addJunction({...r,type:"junction"})),t.edges.map(e.addEdge)},"populateDb"),Nve={parse:o(async t=>{let e=await uo("architecture",t);Y.debug(e),krt(e,Qp)},"parse")}});var Ert,Ive,Ove=N(()=>{"use strict";Ert=o(t=>`
+ .edge {
+ stroke-width: ${t.archEdgeWidth};
+ stroke: ${t.archEdgeColor};
+ fill: none;
+ }
+
+ .arrow {
+ fill: ${t.archEdgeArrowColor};
+ }
+
+ .node-bkg {
+ fill: none;
+ stroke: ${t.archGroupBorderColor};
+ stroke-width: ${t.archGroupBorderWidth};
+ stroke-dasharray: 8;
+ }
+ .node-icon-text {
+ display: flex;
+ align-items: center;
+ }
+
+ .node-icon-text > div {
+ color: #fff;
+ margin: 1px;
+ height: fit-content;
+ text-align: center;
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ }
+`,"getStyles"),Ive=Ert});var dF=Mi((T4,fF)=>{"use strict";o(function(e,r){typeof T4=="object"&&typeof fF=="object"?fF.exports=r():typeof define=="function"&&define.amd?define([],r):typeof T4=="object"?T4.layoutBase=r():e.layoutBase=r()},"webpackUniversalModuleDefinition")(T4,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return o(r,"__webpack_require__"),r.m=t,r.c=e,r.i=function(n){return n},r.d=function(n,i,a){r.o(n,i)||Object.defineProperty(n,i,{configurable:!1,enumerable:!0,get:a})},r.n=function(n){var i=n&&n.__esModule?o(function(){return n.default},"getDefault"):o(function(){return n},"getModuleExports");return r.d(i,"a",i),i},r.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},r.p="",r(r.s=28)}([function(t,e,r){"use strict";function n(){}o(n,"LayoutConstants"),n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(8),a=r(9);function s(u,h,f){n.call(this,f),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=f,this.bendpoints=[],this.source=u,this.target=h}o(s,"LEdge"),s.prototype=Object.create(n.prototype);for(var l in n)s[l]=n[l];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(u){if(this.source===u)return this.target;if(this.target===u)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(u,h){for(var f=this.getOtherEnd(u),d=h.getGraphManager().getRoot();;){if(f.getOwner()==h)return f;if(f.getOwner()==d)break;f=f.getOwner().getParent()}return null},s.prototype.updateLength=function(){var u=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),u),this.isOverlapingSourceAndTarget||(this.lengthX=u[0]-u[2],this.lengthY=u[1]-u[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,r){"use strict";function n(i){this.vGraphObject=i}o(n,"LGraphObject"),t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(13),s=r(0),l=r(16),u=r(5);function h(d,p,m,g){m==null&&g==null&&(g=p),n.call(this,g),d.graphManager!=null&&(d=d.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=g,this.edges=[],this.graphManager=d,m!=null&&p!=null?this.rect=new a(p.x,p.y,m.width,m.height):this.rect=new a}o(h,"LNode"),h.prototype=Object.create(n.prototype);for(var f in n)h[f]=n[f];h.prototype.getEdges=function(){return this.edges},h.prototype.getChild=function(){return this.child},h.prototype.getOwner=function(){return this.owner},h.prototype.getWidth=function(){return this.rect.width},h.prototype.setWidth=function(d){this.rect.width=d},h.prototype.getHeight=function(){return this.rect.height},h.prototype.setHeight=function(d){this.rect.height=d},h.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},h.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},h.prototype.getCenter=function(){return new u(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},h.prototype.getLocation=function(){return new u(this.rect.x,this.rect.y)},h.prototype.getRect=function(){return this.rect},h.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},h.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},h.prototype.setRect=function(d,p){this.rect.x=d.x,this.rect.y=d.y,this.rect.width=p.width,this.rect.height=p.height},h.prototype.setCenter=function(d,p){this.rect.x=d-this.rect.width/2,this.rect.y=p-this.rect.height/2},h.prototype.setLocation=function(d,p){this.rect.x=d,this.rect.y=p},h.prototype.moveBy=function(d,p){this.rect.x+=d,this.rect.y+=p},h.prototype.getEdgeListToNode=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(y.target==d){if(y.source!=g)throw"Incorrect edge source!";p.push(y)}}),p},h.prototype.getEdgesBetween=function(d){var p=[],m,g=this;return g.edges.forEach(function(y){if(!(y.source==g||y.target==g))throw"Incorrect edge source and/or target";(y.target==d||y.source==d)&&p.push(y)}),p},h.prototype.getNeighborsList=function(){var d=new Set,p=this;return p.edges.forEach(function(m){if(m.source==p)d.add(m.target);else{if(m.target!=p)throw"Incorrect incidency!";d.add(m.source)}}),d},h.prototype.withChildren=function(){var d=new Set,p,m;if(d.add(this),this.child!=null)for(var g=this.child.getNodes(),y=0;y<g.length;y++)p=g[y],m=p.withChildren(),m.forEach(function(v){d.add(v)});return d},h.prototype.getNoOfChildren=function(){var d=0,p;if(this.child==null)d=1;else for(var m=this.child.getNodes(),g=0;g<m.length;g++)p=m[g],d+=p.getNoOfChildren();return d==0&&(d=1),d},h.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},h.prototype.calcEstimatedSize=function(){return this.child==null?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},h.prototype.scatter=function(){var d,p,m=-s.INITIAL_WORLD_BOUNDARY,g=s.INITIAL_WORLD_BOUNDARY;d=s.WORLD_CENTER_X+l.nextDouble()*(g-m)+m;var y=-s.INITIAL_WORLD_BOUNDARY,v=s.INITIAL_WORLD_BOUNDARY;p=s.WORLD_CENTER_Y+l.nextDouble()*(v-y)+y,this.rect.x=d,this.rect.y=p},h.prototype.updateBounds=function(){if(this.getChild()==null)throw"assert failed";if(this.getChild().getNodes().length!=0){var d=this.getChild();if(d.updateBounds(!0),this.rect.x=d.getLeft(),this.rect.y=d.getTop(),this.setWidth(d.getRight()-d.getLeft()),this.setHeight(d.getBottom()-d.getTop()),s.NODE_DIMENSIONS_INCLUDE_LABELS){var p=d.getRight()-d.getLeft(),m=d.getBottom()-d.getTop();this.labelWidth&&(this.labelPosHorizontal=="left"?(this.rect.x-=this.labelWidth,this.setWidth(p+this.labelWidth)):this.labelPosHorizontal=="center"&&this.labelWidth>p?(this.rect.x-=(this.labelWidth-p)/2,this.setWidth(this.labelWidth)):this.labelPosHorizontal=="right"&&this.setWidth(p+this.labelWidth)),this.labelHeight&&(this.labelPosVertical=="top"?(this.rect.y-=this.labelHeight,this.setHeight(m+this.labelHeight)):this.labelPosVertical=="center"&&this.labelHeight>m?(this.rect.y-=(this.labelHeight-m)/2,this.setHeight(this.labelHeight)):this.labelPosVertical=="bottom"&&this.setHeight(m+this.labelHeight))}}},h.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},h.prototype.transform=function(d){var p=this.rect.x;p>s.WORLD_BOUNDARY?p=s.WORLD_BOUNDARY:p<-s.WORLD_BOUNDARY&&(p=-s.WORLD_BOUNDARY);var m=this.rect.y;m>s.WORLD_BOUNDARY?m=s.WORLD_BOUNDARY:m<-s.WORLD_BOUNDARY&&(m=-s.WORLD_BOUNDARY);var g=new u(p,m),y=d.inverseTransformPoint(g);this.setLocation(y.x,y.y)},h.prototype.getLeft=function(){return this.rect.x},h.prototype.getRight=function(){return this.rect.x+this.rect.width},h.prototype.getTop=function(){return this.rect.y},h.prototype.getBottom=function(){return this.rect.y+this.rect.height},h.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},t.exports=h},function(t,e,r){"use strict";var n=r(0);function i(){}o(i,"FDLayoutConstants");for(var a in n)i[a]=n[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=i.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=i},function(t,e,r){"use strict";function n(i,a){i==null&&a==null?(this.x=0,this.y=0):(this.x=i,this.y=a)}o(n,"PointD"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(i){this.x=i},n.prototype.setY=function(i){this.y=i},n.prototype.getDifference=function(i){return new DimensionD(this.x-i.x,this.y-i.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(i){return this.x+=i.width,this.y+=i.height,this},t.exports=n},function(t,e,r){"use strict";var n=r(2),i=r(10),a=r(0),s=r(7),l=r(3),u=r(1),h=r(13),f=r(12),d=r(11);function p(g,y,v){n.call(this,v),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=g,y!=null&&y instanceof s?this.graphManager=y:y!=null&&y instanceof Layout&&(this.graphManager=y.graphManager)}o(p,"LGraph"),p.prototype=Object.create(n.prototype);for(var m in n)p[m]=n[m];p.prototype.getNodes=function(){return this.nodes},p.prototype.getEdges=function(){return this.edges},p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getParent=function(){return this.parent},p.prototype.getLeft=function(){return this.left},p.prototype.getRight=function(){return this.right},p.prototype.getTop=function(){return this.top},p.prototype.getBottom=function(){return this.bottom},p.prototype.isConnected=function(){return this.isConnected},p.prototype.add=function(g,y,v){if(y==null&&v==null){var x=g;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(x)>-1)throw"Node already in graph!";return x.owner=this,this.getNodes().push(x),x}else{var b=g;if(!(this.getNodes().indexOf(y)>-1&&this.getNodes().indexOf(v)>-1))throw"Source or target not in graph!";if(!(y.owner==v.owner&&y.owner==this))throw"Both owners must be this graph!";return y.owner!=v.owner?null:(b.source=y,b.target=v,b.isInterGraph=!1,this.getEdges().push(b),y.edges.push(b),v!=y&&v.edges.push(b),b)}},p.prototype.remove=function(g){var y=g;if(g instanceof l){if(y==null)throw"Node is null!";if(!(y.owner!=null&&y.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var v=y.edges.slice(),x,b=v.length,w=0;w<b;w++)x=v[w],x.isInterGraph?this.graphManager.remove(x):x.source.owner.remove(x);var C=this.nodes.indexOf(y);if(C==-1)throw"Node not in owner node list!";this.nodes.splice(C,1)}else if(g instanceof u){var x=g;if(x==null)throw"Edge is null!";if(!(x.source!=null&&x.target!=null))throw"Source and/or target is null!";if(!(x.source.owner!=null&&x.target.owner!=null&&x.source.owner==this&&x.target.owner==this))throw"Source and/or target owner is invalid!";var T=x.source.edges.indexOf(x),E=x.target.edges.indexOf(x);if(!(T>-1&&E>-1))throw"Source and/or target doesn't know this edge!";x.source.edges.splice(T,1),x.target!=x.source&&x.target.edges.splice(E,1);var C=x.source.owner.getEdges().indexOf(x);if(C==-1)throw"Not in owner's edge list!";x.source.owner.getEdges().splice(C,1)}},p.prototype.updateLeftTop=function(){for(var g=i.MAX_VALUE,y=i.MAX_VALUE,v,x,b,w=this.getNodes(),C=w.length,T=0;T<C;T++){var E=w[T];v=E.getTop(),x=E.getLeft(),g>v&&(g=v),y>x&&(y=x)}return g==i.MAX_VALUE?null:(w[0].getParent().paddingLeft!=null?b=w[0].getParent().paddingLeft:b=this.margin,this.left=y-b,this.top=g-b,new f(this.left,this.top))},p.prototype.updateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,w,C,T,E,A,S=this.nodes,_=S.length,I=0;I<_;I++){var D=S[I];g&&D.child!=null&&D.updateBounds(),w=D.getLeft(),C=D.getRight(),T=D.getTop(),E=D.getBottom(),y>w&&(y=w),v<C&&(v=C),x>T&&(x=T),b<E&&(b=E)}var k=new h(y,x,v-y,b-x);y==i.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),S[0].getParent().paddingLeft!=null?A=S[0].getParent().paddingLeft:A=this.margin,this.left=k.x-A,this.right=k.x+k.width+A,this.top=k.y-A,this.bottom=k.y+k.height+A},p.calculateBounds=function(g){for(var y=i.MAX_VALUE,v=-i.MAX_VALUE,x=i.MAX_VALUE,b=-i.MAX_VALUE,w,C,T,E,A=g.length,S=0;S<A;S++){var _=g[S];w=_.getLeft(),C=_.getRight(),T=_.getTop(),E=_.getBottom(),y>w&&(y=w),v<C&&(v=C),x>T&&(x=T),b<E&&(b=E)}var I=new h(y,x,v-y,b-x);return I},p.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},p.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},p.prototype.calcEstimatedSize=function(){for(var g=0,y=this.nodes,v=y.length,x=0;x<v;x++){var b=y[x];g+=b.calcEstimatedSize()}return g==0?this.estimatedSize=a.EMPTY_COMPOUND_NODE_SIZE:this.estimatedSize=g/Math.sqrt(this.nodes.length),this.estimatedSize},p.prototype.updateConnected=function(){var g=this;if(this.nodes.length==0){this.isConnected=!0;return}var y=new d,v=new Set,x=this.nodes[0],b,w,C=x.withChildren();for(C.forEach(function(I){y.push(I),v.add(I)});y.length!==0;){x=y.shift(),b=x.getEdges();for(var T=b.length,E=0;E<T;E++){var A=b[E];if(w=A.getOtherEndInGraph(x,this),w!=null&&!v.has(w)){var S=w.withChildren();S.forEach(function(I){y.push(I),v.add(I)})}}}if(this.isConnected=!1,v.size>=this.nodes.length){var _=0;v.forEach(function(I){I.owner==g&&_++}),_==this.nodes.length&&(this.isConnected=!0)}},t.exports=p},function(t,e,r){"use strict";var n,i=r(1);function a(s){n=r(6),this.layout=s,this.graphs=[],this.edges=[]}o(a,"LGraphManager"),a.prototype.addRoot=function(){var s=this.layout.newGraph(),l=this.layout.newNode(null),u=this.add(s,l);return this.setRootGraph(u),this.rootGraph},a.prototype.add=function(s,l,u,h,f){if(u==null&&h==null&&f==null){if(s==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(s)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(s),s.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return s.parent=l,l.child=s,s}else{f=u,h=l,u=s;var d=h.getOwner(),p=f.getOwner();if(!(d!=null&&d.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(p!=null&&p.getGraphManager()==this))throw"Target not in this graph mgr!";if(d==p)return u.isInterGraph=!1,d.add(u,h,f);if(u.isInterGraph=!0,u.source=h,u.target=f,this.edges.indexOf(u)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(u),!(u.source!=null&&u.target!=null))throw"Edge source and/or target is null!";if(!(u.source.edges.indexOf(u)==-1&&u.target.edges.indexOf(u)==-1))throw"Edge already in source and/or target incidency list!";return u.source.edges.push(u),u.target.edges.push(u),u}},a.prototype.remove=function(s){if(s instanceof n){var l=s;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var u=[];u=u.concat(l.getEdges());for(var h,f=u.length,d=0;d<f;d++)h=u[d],l.remove(h);var p=[];p=p.concat(l.getNodes());var m;f=p.length;for(var d=0;d<f;d++)m=p[d],l.remove(m);l==this.rootGraph&&this.setRootGraph(null);var g=this.graphs.indexOf(l);this.graphs.splice(g,1),l.parent=null}else if(s instanceof i){if(h=s,h==null)throw"Edge is null!";if(!h.isInterGraph)throw"Not an inter-graph edge!";if(!(h.source!=null&&h.target!=null))throw"Source and/or target is null!";if(!(h.source.edges.indexOf(h)!=-1&&h.target.edges.indexOf(h)!=-1))throw"Source and/or target doesn't know this edge!";var g=h.source.edges.indexOf(h);if(h.source.edges.splice(g,1),g=h.target.edges.indexOf(h),h.target.edges.splice(g,1),!(h.source.owner!=null&&h.source.owner.getGraphManager()!=null))throw"Edge owner graph or owner graph manager is null!";if(h.source.owner.getGraphManager().edges.indexOf(h)==-1)throw"Not in owner graph manager's edge list!";var g=h.source.owner.getGraphManager().edges.indexOf(h);h.source.owner.getGraphManager().edges.splice(g,1)}},a.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},a.prototype.getGraphs=function(){return this.graphs},a.prototype.getAllNodes=function(){if(this.allNodes==null){for(var s=[],l=this.getGraphs(),u=l.length,h=0;h<u;h++)s=s.concat(l[h].getNodes());this.allNodes=s}return this.allNodes},a.prototype.resetAllNodes=function(){this.allNodes=null},a.prototype.resetAllEdges=function(){this.allEdges=null},a.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},a.prototype.getAllEdges=function(){if(this.allEdges==null){for(var s=[],l=this.getGraphs(),u=l.length,h=0;h<l.length;h++)s=s.concat(l[h].getEdges());s=s.concat(this.edges),this.allEdges=s}return this.allEdges},a.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},a.prototype.setAllNodesToApplyGravitation=function(s){if(this.allNodesToApplyGravitation!=null)throw"assert failed";this.allNodesToApplyGravitation=s},a.prototype.getRoot=function(){return this.rootGraph},a.prototype.setRootGraph=function(s){if(s.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=s,s.parent==null&&(s.parent=this.layout.newNode("Root node"))},a.prototype.getLayout=function(){return this.layout},a.prototype.isOneAncestorOfOther=function(s,l){if(!(s!=null&&l!=null))throw"assert failed";if(s==l)return!0;var u=s.getOwner(),h;do{if(h=u.getParent(),h==null)break;if(h==l)return!0;if(u=h.getOwner(),u==null)break}while(!0);u=l.getOwner();do{if(h=u.getParent(),h==null)break;if(h==s)return!0;if(u=h.getOwner(),u==null)break}while(!0);return!1},a.prototype.calcLowestCommonAncestors=function(){for(var s,l,u,h,f,d=this.getAllEdges(),p=d.length,m=0;m<p;m++){if(s=d[m],l=s.source,u=s.target,s.lca=null,s.sourceInLca=l,s.targetInLca=u,l==u){s.lca=l.getOwner();continue}for(h=l.getOwner();s.lca==null;){for(s.targetInLca=u,f=u.getOwner();s.lca==null;){if(f==h){s.lca=f;break}if(f==this.rootGraph)break;if(s.lca!=null)throw"assert failed";s.targetInLca=f.getParent(),f=s.targetInLca.getOwner()}if(h==this.rootGraph)break;s.lca==null&&(s.sourceInLca=h.getParent(),h=s.sourceInLca.getOwner())}if(s.lca==null)throw"assert failed"}},a.prototype.calcLowestCommonAncestor=function(s,l){if(s==l)return s.getOwner();var u=s.getOwner();do{if(u==null)break;var h=l.getOwner();do{if(h==null)break;if(h==u)return h;h=h.getParent().getOwner()}while(!0);u=u.getParent().getOwner()}while(!0);return u},a.prototype.calcInclusionTreeDepths=function(s,l){s==null&&l==null&&(s=this.rootGraph,l=1);for(var u,h=s.getNodes(),f=h.length,d=0;d<f;d++)u=h[d],u.inclusionTreeDepth=l,u.child!=null&&this.calcInclusionTreeDepths(u.child,l+1)},a.prototype.includesInvalidEdge=function(){for(var s,l=[],u=this.edges.length,h=0;h<u;h++)s=this.edges[h],this.isOneAncestorOfOther(s.source,s.target)&&l.push(s);for(var h=0;h<l.length;h++)this.remove(l[h]);return!1},t.exports=a},function(t,e,r){"use strict";var n=r(12);function i(){}o(i,"IGeometry"),i.calcSeparationAmount=function(a,s,l,u){if(!a.intersects(s))throw"assert failed";var h=new Array(2);this.decideDirectionsForOverlappingNodes(a,s,h),l[0]=Math.min(a.getRight(),s.getRight())-Math.max(a.x,s.x),l[1]=Math.min(a.getBottom(),s.getBottom())-Math.max(a.y,s.y),a.getX()<=s.getX()&&a.getRight()>=s.getRight()?l[0]+=Math.min(s.getX()-a.getX(),a.getRight()-s.getRight()):s.getX()<=a.getX()&&s.getRight()>=a.getRight()&&(l[0]+=Math.min(a.getX()-s.getX(),s.getRight()-a.getRight())),a.getY()<=s.getY()&&a.getBottom()>=s.getBottom()?l[1]+=Math.min(s.getY()-a.getY(),a.getBottom()-s.getBottom()):s.getY()<=a.getY()&&s.getBottom()>=a.getBottom()&&(l[1]+=Math.min(a.getY()-s.getY(),s.getBottom()-a.getBottom()));var f=Math.abs((s.getCenterY()-a.getCenterY())/(s.getCenterX()-a.getCenterX()));s.getCenterY()===a.getCenterY()&&s.getCenterX()===a.getCenterX()&&(f=1);var d=f*l[0],p=l[1]/f;l[0]<p?p=l[0]:d=l[1],l[0]=-1*h[0]*(p/2+u),l[1]=-1*h[1]*(d/2+u)},i.decideDirectionsForOverlappingNodes=function(a,s,l){a.getCenterX()<s.getCenterX()?l[0]=-1:l[0]=1,a.getCenterY()<s.getCenterY()?l[1]=-1:l[1]=1},i.getIntersection2=function(a,s,l){var u=a.getCenterX(),h=a.getCenterY(),f=s.getCenterX(),d=s.getCenterY();if(a.intersects(s))return l[0]=u,l[1]=h,l[2]=f,l[3]=d,!0;var p=a.getX(),m=a.getY(),g=a.getRight(),y=a.getX(),v=a.getBottom(),x=a.getRight(),b=a.getWidthHalf(),w=a.getHeightHalf(),C=s.getX(),T=s.getY(),E=s.getRight(),A=s.getX(),S=s.getBottom(),_=s.getRight(),I=s.getWidthHalf(),D=s.getHeightHalf(),k=!1,L=!1;if(u===f){if(h>d)return l[0]=u,l[1]=m,l[2]=f,l[3]=S,!1;if(h<d)return l[0]=u,l[1]=v,l[2]=f,l[3]=T,!1}else if(h===d){if(u>f)return l[0]=p,l[1]=h,l[2]=E,l[3]=d,!1;if(u<f)return l[0]=g,l[1]=h,l[2]=C,l[3]=d,!1}else{var R=a.height/a.width,O=s.height/s.width,M=(d-h)/(f-u),B=void 0,F=void 0,P=void 0,z=void 0,$=void 0,H=void 0;if(-R===M?u>f?(l[0]=y,l[1]=v,k=!0):(l[0]=g,l[1]=m,k=!0):R===M&&(u>f?(l[0]=p,l[1]=m,k=!0):(l[0]=x,l[1]=v,k=!0)),-O===M?f>u?(l[2]=A,l[3]=S,L=!0):(l[2]=E,l[3]=T,L=!0):O===M&&(f>u?(l[2]=C,l[3]=T,L=!0):(l[2]=_,l[3]=S,L=!0)),k&&L)return!1;if(u>f?h>d?(B=this.getCardinalDirection(R,M,4),F=this.getCardinalDirection(O,M,2)):(B=this.getCardinalDirection(-R,M,3),F=this.getCardinalDirection(-O,M,1)):h>d?(B=this.getCardinalDirection(-R,M,1),F=this.getCardinalDirection(-O,M,3)):(B=this.getCardinalDirection(R,M,2),F=this.getCardinalDirection(O,M,4)),!k)switch(B){case 1:z=m,P=u+-w/M,l[0]=P,l[1]=z;break;case 2:P=x,z=h+b*M,l[0]=P,l[1]=z;break;case 3:z=v,P=u+w/M,l[0]=P,l[1]=z;break;case 4:P=y,z=h+-b*M,l[0]=P,l[1]=z;break}if(!L)switch(F){case 1:H=T,$=f+-D/M,l[2]=$,l[3]=H;break;case 2:$=_,H=d+I*M,l[2]=$,l[3]=H;break;case 3:H=S,$=f+D/M,l[2]=$,l[3]=H;break;case 4:$=A,H=d+-I*M,l[2]=$,l[3]=H;break}}return!1},i.getCardinalDirection=function(a,s,l){return a>s?l:1+l%4},i.getIntersection=function(a,s,l,u){if(u==null)return this.getIntersection2(a,s,l);var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=void 0,b=void 0,w=void 0,C=void 0,T=void 0,E=void 0,A=void 0,S=void 0,_=void 0;return w=p-f,T=h-d,A=d*f-h*p,C=v-g,E=m-y,S=y*g-m*v,_=w*E-C*T,_===0?null:(x=(T*S-E*A)/_,b=(C*A-w*S)/_,new n(x,b))},i.angleOfVector=function(a,s,l,u){var h=void 0;return a!==l?(h=Math.atan((u-s)/(l-a)),l<a?h+=Math.PI:u<s&&(h+=this.TWO_PI)):u<s?h=this.ONE_AND_HALF_PI:h=this.HALF_PI,h},i.doIntersect=function(a,s,l,u){var h=a.x,f=a.y,d=s.x,p=s.y,m=l.x,g=l.y,y=u.x,v=u.y,x=(d-h)*(v-g)-(y-m)*(p-f);if(x===0)return!1;var b=((v-g)*(y-h)+(m-y)*(v-f))/x,w=((f-p)*(y-h)+(d-h)*(v-f))/x;return 0<b&&b<1&&0<w&&w<1},i.findCircleLineIntersections=function(a,s,l,u,h,f,d){var p=(l-a)*(l-a)+(u-s)*(u-s),m=2*((a-h)*(l-a)+(s-f)*(u-s)),g=(a-h)*(a-h)+(s-f)*(s-f)-d*d,y=m*m-4*p*g;if(y>=0){var v=(-m+Math.sqrt(m*m-4*p*g))/(2*p),x=(-m-Math.sqrt(m*m-4*p*g))/(2*p),b=null;return v>=0&&v<=1?[v]:x>=0&&x<=1?[x]:b}else return null},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,t.exports=i},function(t,e,r){"use strict";function n(){}o(n,"IMath"),n.sign=function(i){return i>0?1:i<0?-1:0},n.floor=function(i){return i<0?Math.ceil(i):Math.floor(i)},n.ceil=function(i){return i<0?Math.floor(i):Math.ceil(i)},t.exports=n},function(t,e,r){"use strict";function n(){}o(n,"Integer"),n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,r){"use strict";var n=function(){function h(f,d){for(var p=0;p<d.length;p++){var m=d[p];m.enumerable=m.enumerable||!1,m.configurable=!0,"value"in m&&(m.writable=!0),Object.defineProperty(f,m.key,m)}}return o(h,"defineProperties"),function(f,d,p){return d&&h(f.prototype,d),p&&h(f,p),f}}();function i(h,f){if(!(h instanceof f))throw new TypeError("Cannot call a class as a function")}o(i,"_classCallCheck");var a=o(function(f){return{value:f,next:null,prev:null}},"nodeFrom"),s=o(function(f,d,p,m){return f!==null?f.next=d:m.head=d,p!==null?p.prev=d:m.tail=d,d.prev=f,d.next=p,m.length++,d},"add"),l=o(function(f,d){var p=f.prev,m=f.next;return p!==null?p.next=m:d.head=m,m!==null?m.prev=p:d.tail=p,f.prev=f.next=null,d.length--,f},"_remove"),u=function(){function h(f){var d=this;i(this,h),this.length=0,this.head=null,this.tail=null,f?.forEach(function(p){return d.push(p)})}return o(h,"LinkedList"),n(h,[{key:"size",value:o(function(){return this.length},"size")},{key:"insertBefore",value:o(function(d,p){return s(p.prev,a(d),p,this)},"insertBefore")},{key:"insertAfter",value:o(function(d,p){return s(p,a(d),p.next,this)},"insertAfter")},{key:"insertNodeBefore",value:o(function(d,p){return s(p.prev,d,p,this)},"insertNodeBefore")},{key:"insertNodeAfter",value:o(function(d,p){return s(p,d,p.next,this)},"insertNodeAfter")},{key:"push",value:o(function(d){return s(this.tail,a(d),null,this)},"push")},{key:"unshift",value:o(function(d){return s(null,a(d),this.head,this)},"unshift")},{key:"remove",value:o(function(d){return l(d,this)},"remove")},{key:"pop",value:o(function(){return l(this.tail,this).value},"pop")},{key:"popNode",value:o(function(){return l(this.tail,this)},"popNode")},{key:"shift",value:o(function(){return l(this.head,this).value},"shift")},{key:"shiftNode",value:o(function(){return l(this.head,this)},"shiftNode")},{key:"get_object_at",value:o(function(d){if(d<=this.length()){for(var p=1,m=this.head;p<d;)m=m.next,p++;return m.value}},"get_object_at")},{key:"set_object_at",value:o(function(d,p){if(d<=this.length()){for(var m=1,g=this.head;m<d;)g=g.next,m++;g.value=p}},"set_object_at")}]),h}();t.exports=u},function(t,e,r){"use strict";function n(i,a,s){this.x=null,this.y=null,i==null&&a==null&&s==null?(this.x=0,this.y=0):typeof i=="number"&&typeof a=="number"&&s==null?(this.x=i,this.y=a):i.constructor.name=="Point"&&a==null&&s==null&&(s=i,this.x=s.x,this.y=s.y)}o(n,"Point"),n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.getLocation=function(){return new n(this.x,this.y)},n.prototype.setLocation=function(i,a,s){i.constructor.name=="Point"&&a==null&&s==null?(s=i,this.setLocation(s.x,s.y)):typeof i=="number"&&typeof a=="number"&&s==null&&(parseInt(i)==i&&parseInt(a)==a?this.move(i,a):(this.x=Math.floor(i+.5),this.y=Math.floor(a+.5)))},n.prototype.move=function(i,a){this.x=i,this.y=a},n.prototype.translate=function(i,a){this.x+=i,this.y+=a},n.prototype.equals=function(i){if(i.constructor.name=="Point"){var a=i;return this.x==a.x&&this.y==a.y}return this==i},n.prototype.toString=function(){return new n().constructor.name+"[x="+this.x+",y="+this.y+"]"},t.exports=n},function(t,e,r){"use strict";function n(i,a,s,l){this.x=0,this.y=0,this.width=0,this.height=0,i!=null&&a!=null&&s!=null&&l!=null&&(this.x=i,this.y=a,this.width=s,this.height=l)}o(n,"RectangleD"),n.prototype.getX=function(){return this.x},n.prototype.setX=function(i){this.x=i},n.prototype.getY=function(){return this.y},n.prototype.setY=function(i){this.y=i},n.prototype.getWidth=function(){return this.width},n.prototype.setWidth=function(i){this.width=i},n.prototype.getHeight=function(){return this.height},n.prototype.setHeight=function(i){this.height=i},n.prototype.getRight=function(){return this.x+this.width},n.prototype.getBottom=function(){return this.y+this.height},n.prototype.intersects=function(i){return!(this.getRight()<i.x||this.getBottom()<i.y||i.getRight()<this.x||i.getBottom()<this.y)},n.prototype.getCenterX=function(){return this.x+this.width/2},n.prototype.getMinX=function(){return this.getX()},n.prototype.getMaxX=function(){return this.getX()+this.width},n.prototype.getCenterY=function(){return this.y+this.height/2},n.prototype.getMinY=function(){return this.getY()},n.prototype.getMaxY=function(){return this.getY()+this.height},n.prototype.getWidthHalf=function(){return this.width/2},n.prototype.getHeightHalf=function(){return this.height/2},t.exports=n},function(t,e,r){"use strict";var n=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};function i(){}o(i,"UniqueIDGeneretor"),i.lastID=0,i.createID=function(a){return i.isPrimitive(a)?a:(a.uniqueID!=null||(a.uniqueID=i.getString(),i.lastID++),a.uniqueID)},i.getString=function(a){return a==null&&(a=i.lastID),"Object#"+a},i.isPrimitive=function(a){var s=typeof a>"u"?"undefined":n(a);return a==null||s!="object"&&s!="function"},t.exports=i},function(t,e,r){"use strict";function n(m){if(Array.isArray(m)){for(var g=0,y=Array(m.length);g<m.length;g++)y[g]=m[g];return y}else return Array.from(m)}o(n,"_toConsumableArray");var i=r(0),a=r(7),s=r(3),l=r(1),u=r(6),h=r(5),f=r(17),d=r(29);function p(m){d.call(this),this.layoutQuality=i.QUALITY,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=i.DEFAULT_INCREMENTAL,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new a(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,m!=null&&(this.isRemoteUse=m)}o(p,"Layout"),p.RANDOM_SEED=1,p.prototype=Object.create(d.prototype),p.prototype.getGraphManager=function(){return this.graphManager},p.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},p.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},p.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},p.prototype.newGraphManager=function(){var m=new a(this);return this.graphManager=m,m},p.prototype.newGraph=function(m){return new u(null,this.graphManager,m)},p.prototype.newNode=function(m){return new s(this.graphManager,m)},p.prototype.newEdge=function(m){return new l(null,null,m)},p.prototype.checkLayoutSuccess=function(){return this.graphManager.getRoot()==null||this.graphManager.getRoot().getNodes().length==0||this.graphManager.includesInvalidEdge()},p.prototype.runLayout=function(){this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters();var m;return this.checkLayoutSuccess()?m=!1:m=this.layout(),i.ANIMATE==="during"?!1:(m&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,m)},p.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},p.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var m,g=this.graphManager.getAllEdges(),y=0;y<g.length;y++)m=g[y];for(var v,x=this.graphManager.getRoot().getNodes(),y=0;y<x.length;y++)v=x[y];this.update(this.graphManager.getRoot())}},p.prototype.update=function(m){if(m==null)this.update2();else if(m instanceof s){var g=m;if(g.getChild()!=null)for(var y=g.getChild().getNodes(),v=0;v<y.length;v++)update(y[v]);if(g.vGraphObject!=null){var x=g.vGraphObject;x.update(g)}}else if(m instanceof l){var b=m;if(b.vGraphObject!=null){var w=b.vGraphObject;w.update(b)}}else if(m instanceof u){var C=m;if(C.vGraphObject!=null){var T=C.vGraphObject;T.update(C)}}},p.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=i.QUALITY,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=i.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},p.prototype.transform=function(m){if(m==null)this.transform(new h(0,0));else{var g=new f,y=this.graphManager.getRoot().updateLeftTop();if(y!=null){g.setWorldOrgX(m.x),g.setWorldOrgY(m.y),g.setDeviceOrgX(y.x),g.setDeviceOrgY(y.y);for(var v=this.getAllNodes(),x,b=0;b<v.length;b++)x=v[b],x.transform(g)}}},p.prototype.positionNodesRandomly=function(m){if(m==null)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var g,y,v=m.getNodes(),x=0;x<v.length;x++)g=v[x],y=g.getChild(),y==null||y.getNodes().length==0?g.scatter():(this.positionNodesRandomly(y),g.updateBounds())},p.prototype.getFlatForest=function(){for(var m=[],g=!0,y=this.graphManager.getRoot().getNodes(),v=!0,x=0;x<y.length;x++)y[x].getChild()!=null&&(v=!1);if(!v)return m;var b=new Set,w=[],C=new Map,T=[];for(T=T.concat(y);T.length>0&&g;){for(w.push(T[0]);w.length>0&&g;){var E=w[0];w.splice(0,1),b.add(E);for(var A=E.getEdges(),x=0;x<A.length;x++){var S=A[x].getOtherEnd(E);if(C.get(E)!=S)if(!b.has(S))w.push(S),C.set(S,E);else{g=!1;break}}}if(!g)m=[];else{var _=[].concat(n(b));m.push(_);for(var x=0;x<_.length;x++){var I=_[x],D=T.indexOf(I);D>-1&&T.splice(D,1)}b=new Set,C=new Map}}return m},p.prototype.createDummyNodesForBendpoints=function(m){for(var g=[],y=m.source,v=this.graphManager.calcLowestCommonAncestor(m.source,m.target),x=0;x<m.bendpoints.length;x++){var b=this.newNode(null);b.setRect(new Point(0,0),new Dimension(1,1)),v.add(b);var w=this.newEdge(null);this.graphManager.add(w,y,b),g.add(b),y=b}var w=this.newEdge(null);return this.graphManager.add(w,y,m.target),this.edgeToDummyNodes.set(m,g),m.isInterGraph()?this.graphManager.remove(m):v.remove(m),g},p.prototype.createBendpointsFromDummyNodes=function(){var m=[];m=m.concat(this.graphManager.getAllEdges()),m=[].concat(n(this.edgeToDummyNodes.keys())).concat(m);for(var g=0;g<m.length;g++){var y=m[g];if(y.bendpoints.length>0){for(var v=this.edgeToDummyNodes.get(y),x=0;x<v.length;x++){var b=v[x],w=new h(b.getCenterX(),b.getCenterY()),C=y.bendpoints.get(x);C.x=w.x,C.y=w.y,b.getOwner().remove(b)}this.graphManager.add(y,y.source,y.target)}}},p.transform=function(m,g,y,v){if(y!=null&&v!=null){var x=g;if(m<=50){var b=g/y;x-=(g-b)/50*(50-m)}else{var w=g*v;x+=(w-g)/50*(m-50)}return x}else{var C,T;return m<=50?(C=9*g/500,T=g/10):(C=9*g/50,T=-8*g),C*m+T}},p.findCenterOfTree=function(m){var g=[];g=g.concat(m);var y=[],v=new Map,x=!1,b=null;(g.length==1||g.length==2)&&(x=!0,b=g[0]);for(var w=0;w<g.length;w++){var C=g[w],T=C.getNeighborsList().size;v.set(C,C.getNeighborsList().size),T==1&&y.push(C)}var E=[];for(E=E.concat(y);!x;){var A=[];A=A.concat(E),E=[];for(var w=0;w<g.length;w++){var C=g[w],S=g.indexOf(C);S>=0&&g.splice(S,1);var _=C.getNeighborsList();_.forEach(function(k){if(y.indexOf(k)<0){var L=v.get(k),R=L-1;R==1&&E.push(k),v.set(k,R)}})}y=y.concat(E),(g.length==1||g.length==2)&&(x=!0,b=g[0])}return b},p.prototype.setGraphManager=function(m){this.graphManager=m},t.exports=p},function(t,e,r){"use strict";function n(){}o(n,"RandomSeed"),n.seed=1,n.x=0,n.nextDouble=function(){return n.x=Math.sin(n.seed++)*1e4,n.x-Math.floor(n.x)},t.exports=n},function(t,e,r){"use strict";var n=r(5);function i(a,s){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}o(i,"Transform"),i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(a){this.lworldOrgX=a},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(a){this.lworldOrgY=a},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(a){this.lworldExtX=a},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(a){this.lworldExtY=a},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(a){this.ldeviceOrgX=a},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(a){this.ldeviceOrgY=a},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(a){this.ldeviceExtX=a},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(a){this.ldeviceExtY=a},i.prototype.transformX=function(a){var s=0,l=this.lworldExtX;return l!=0&&(s=this.ldeviceOrgX+(a-this.lworldOrgX)*this.ldeviceExtX/l),s},i.prototype.transformY=function(a){var s=0,l=this.lworldExtY;return l!=0&&(s=this.ldeviceOrgY+(a-this.lworldOrgY)*this.ldeviceExtY/l),s},i.prototype.inverseTransformX=function(a){var s=0,l=this.ldeviceExtX;return l!=0&&(s=this.lworldOrgX+(a-this.ldeviceOrgX)*this.lworldExtX/l),s},i.prototype.inverseTransformY=function(a){var s=0,l=this.ldeviceExtY;return l!=0&&(s=this.lworldOrgY+(a-this.ldeviceOrgY)*this.lworldExtY/l),s},i.prototype.inverseTransformPoint=function(a){var s=new n(this.inverseTransformX(a.x),this.inverseTransformY(a.y));return s},t.exports=i},function(t,e,r){"use strict";function n(d){if(Array.isArray(d)){for(var p=0,m=Array(d.length);p<d.length;p++)m[p]=d[p];return m}else return Array.from(d)}o(n,"_toConsumableArray");var i=r(15),a=r(4),s=r(0),l=r(8),u=r(9);function h(){i.call(this),this.useSmartIdealEdgeLengthCalculation=a.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=a.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=a.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=a.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*a.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=a.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=a.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=a.MAX_ITERATIONS}o(h,"FDLayout"),h.prototype=Object.create(i.prototype);for(var f in i)h[f]=i[f];h.prototype.initParameters=function(){i.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=a.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},h.prototype.calcIdealEdgeLengths=function(){for(var d,p,m,g,y,v,x,b=this.getGraphManager().getAllEdges(),w=0;w<b.length;w++)d=b[w],p=d.idealLength,d.isInterGraph&&(g=d.getSource(),y=d.getTarget(),v=d.getSourceInLca().getEstimatedSize(),x=d.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(d.idealLength+=v+x-2*s.SIMPLE_NODE_SIZE),m=d.getLca().getInclusionTreeDepth(),d.idealLength+=p*a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(g.getInclusionTreeDepth()+y.getInclusionTreeDepth()-2*m))},h.prototype.initSpringEmbedder=function(){var d=this.getAllNodes().length;this.incremental?(d>a.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*a.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-a.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT_INCREMENTAL):(d>a.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(a.COOLING_ADAPTATION_FACTOR,1-(d-a.ADAPTATION_LOWER_NODE_LIMIT)/(a.ADAPTATION_UPPER_NODE_LIMIT-a.ADAPTATION_LOWER_NODE_LIMIT)*(1-a.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=a.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.displacementThresholdPerNode=3*a.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var d=this.getAllEdges(),p,m=0;m<d.length;m++)p=d[m],this.calcSpringForce(p,p.idealLength)},h.prototype.calcRepulsionForces=function(){var d=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,p=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,m,g,y,v,x=this.getAllNodes(),b;if(this.useFRGridVariant)for(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&d&&this.updateGrid(),b=new Set,m=0;m<x.length;m++)y=x[m],this.calculateRepulsionForceOfANode(y,b,d,p),b.add(y);else for(m=0;m<x.length;m++)for(y=x[m],g=m+1;g<x.length;g++)v=x[g],y.getOwner()==v.getOwner()&&this.calcRepulsionForce(y,v)},h.prototype.calcGravitationalForces=function(){for(var d,p=this.getAllNodesToApplyGravitation(),m=0;m<p.length;m++)d=p[m],this.calcGravitationalForce(d)},h.prototype.moveNodes=function(){for(var d=this.getAllNodes(),p,m=0;m<d.length;m++)p=d[m],p.move()},h.prototype.calcSpringForce=function(d,p){var m=d.getSource(),g=d.getTarget(),y,v,x,b;if(this.uniformLeafNodeSizes&&m.getChild()==null&&g.getChild()==null)d.updateLengthSimple();else if(d.updateLength(),d.isOverlapingSourceAndTarget)return;y=d.getLength(),y!=0&&(v=d.edgeElasticity*(y-p),x=v*(d.lengthX/y),b=v*(d.lengthY/y),m.springForceX+=x,m.springForceY+=b,g.springForceX-=x,g.springForceY-=b)},h.prototype.calcRepulsionForce=function(d,p){var m=d.getRect(),g=p.getRect(),y=new Array(2),v=new Array(4),x,b,w,C,T,E,A;if(m.intersects(g)){l.calcSeparationAmount(m,g,y,a.DEFAULT_EDGE_LENGTH/2),E=2*y[0],A=2*y[1];var S=d.noOfChildren*p.noOfChildren/(d.noOfChildren+p.noOfChildren);d.repulsionForceX-=S*E,d.repulsionForceY-=S*A,p.repulsionForceX+=S*E,p.repulsionForceY+=S*A}else this.uniformLeafNodeSizes&&d.getChild()==null&&p.getChild()==null?(x=g.getCenterX()-m.getCenterX(),b=g.getCenterY()-m.getCenterY()):(l.getIntersection(m,g,v),x=v[2]-v[0],b=v[3]-v[1]),Math.abs(x)<a.MIN_REPULSION_DIST&&(x=u.sign(x)*a.MIN_REPULSION_DIST),Math.abs(b)<a.MIN_REPULSION_DIST&&(b=u.sign(b)*a.MIN_REPULSION_DIST),w=x*x+b*b,C=Math.sqrt(w),T=(d.nodeRepulsion/2+p.nodeRepulsion/2)*d.noOfChildren*p.noOfChildren/w,E=T*x/C,A=T*b/C,d.repulsionForceX-=E,d.repulsionForceY-=A,p.repulsionForceX+=E,p.repulsionForceY+=A},h.prototype.calcGravitationalForce=function(d){var p,m,g,y,v,x,b,w;p=d.getOwner(),m=(p.getRight()+p.getLeft())/2,g=(p.getTop()+p.getBottom())/2,y=d.getCenterX()-m,v=d.getCenterY()-g,x=Math.abs(y)+d.getWidth()/2,b=Math.abs(v)+d.getHeight()/2,d.getOwner()==this.graphManager.getRoot()?(w=p.getEstimatedSize()*this.gravityRangeFactor,(x>w||b>w)&&(d.gravitationForceX=-this.gravityConstant*y,d.gravitationForceY=-this.gravityConstant*v)):(w=p.getEstimatedSize()*this.compoundGravityRangeFactor,(x>w||b>w)&&(d.gravitationForceX=-this.gravityConstant*y*this.compoundGravityConstant,d.gravitationForceY=-this.gravityConstant*v*this.compoundGravityConstant))},h.prototype.isConverged=function(){var d,p=!1;return this.totalIterations>this.maxIterations/3&&(p=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),d=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,d||p},h.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},h.prototype.calcNoOfChildrenForAllNodes=function(){for(var d,p=this.graphManager.getAllNodes(),m=0;m<p.length;m++)d=p[m],d.noOfChildren=d.getNoOfChildren()},h.prototype.calcGrid=function(d){var p=0,m=0;p=parseInt(Math.ceil((d.getRight()-d.getLeft())/this.repulsionRange)),m=parseInt(Math.ceil((d.getBottom()-d.getTop())/this.repulsionRange));for(var g=new Array(p),y=0;y<p;y++)g[y]=new Array(m);for(var y=0;y<p;y++)for(var v=0;v<m;v++)g[y][v]=new Array;return g},h.prototype.addNodeToGrid=function(d,p,m){var g=0,y=0,v=0,x=0;g=parseInt(Math.floor((d.getRect().x-p)/this.repulsionRange)),y=parseInt(Math.floor((d.getRect().width+d.getRect().x-p)/this.repulsionRange)),v=parseInt(Math.floor((d.getRect().y-m)/this.repulsionRange)),x=parseInt(Math.floor((d.getRect().height+d.getRect().y-m)/this.repulsionRange));for(var b=g;b<=y;b++)for(var w=v;w<=x;w++)this.grid[b][w].push(d),d.setGridCoordinates(g,y,v,x)},h.prototype.updateGrid=function(){var d,p,m=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),d=0;d<m.length;d++)p=m[d],this.addNodeToGrid(p,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},h.prototype.calculateRepulsionForceOfANode=function(d,p,m,g){if(this.totalIterations%a.GRID_CALCULATION_CHECK_PERIOD==1&&m||g){var y=new Set;d.surrounding=new Array;for(var v,x=this.grid,b=d.startX-1;b<d.finishX+2;b++)for(var w=d.startY-1;w<d.finishY+2;w++)if(!(b<0||w<0||b>=x.length||w>=x[0].length)){for(var C=0;C<x[b][w].length;C++)if(v=x[b][w][C],!(d.getOwner()!=v.getOwner()||d==v)&&!p.has(v)&&!y.has(v)){var T=Math.abs(d.getCenterX()-v.getCenterX())-(d.getWidth()/2+v.getWidth()/2),E=Math.abs(d.getCenterY()-v.getCenterY())-(d.getHeight()/2+v.getHeight()/2);T<=this.repulsionRange&&E<=this.repulsionRange&&y.add(v)}}d.surrounding=[].concat(n(y))}for(b=0;b<d.surrounding.length;b++)this.calcRepulsionForce(d,d.surrounding[b])},h.prototype.calcRepulsionRange=function(){return 0},t.exports=h},function(t,e,r){"use strict";var n=r(1),i=r(4);function a(l,u,h){n.call(this,l,u,h),this.idealLength=i.DEFAULT_EDGE_LENGTH,this.edgeElasticity=i.DEFAULT_SPRING_STRENGTH}o(a,"FDLayoutEdge"),a.prototype=Object.create(n.prototype);for(var s in n)a[s]=n[s];t.exports=a},function(t,e,r){"use strict";var n=r(3),i=r(4);function a(l,u,h,f){n.call(this,l,u,h,f),this.nodeRepulsion=i.DEFAULT_REPULSION_STRENGTH,this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}o(a,"FDLayoutNode"),a.prototype=Object.create(n.prototype);for(var s in n)a[s]=n[s];a.prototype.setGridCoordinates=function(l,u,h,f){this.startX=l,this.finishX=u,this.startY=h,this.finishY=f},t.exports=a},function(t,e,r){"use strict";function n(i,a){this.width=0,this.height=0,i!==null&&a!==null&&(this.height=a,this.width=i)}o(n,"DimensionD"),n.prototype.getWidth=function(){return this.width},n.prototype.setWidth=function(i){this.width=i},n.prototype.getHeight=function(){return this.height},n.prototype.setHeight=function(i){this.height=i},t.exports=n},function(t,e,r){"use strict";var n=r(14);function i(){this.map={},this.keys=[]}o(i,"HashMap"),i.prototype.put=function(a,s){var l=n.createID(a);this.contains(l)||(this.map[l]=s,this.keys.push(a))},i.prototype.contains=function(a){var s=n.createID(a);return this.map[a]!=null},i.prototype.get=function(a){var s=n.createID(a);return this.map[s]},i.prototype.keySet=function(){return this.keys},t.exports=i},function(t,e,r){"use strict";var n=r(14);function i(){this.set={}}o(i,"HashSet"),i.prototype.add=function(a){var s=n.createID(a);this.contains(s)||(this.set[s]=a)},i.prototype.remove=function(a){delete this.set[n.createID(a)]},i.prototype.clear=function(){this.set={}},i.prototype.contains=function(a){return this.set[n.createID(a)]==a},i.prototype.isEmpty=function(){return this.size()===0},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAllTo=function(a){for(var s=Object.keys(this.set),l=s.length,u=0;u<l;u++)a.push(this.set[s[u]])},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAll=function(a){for(var s=a.length,l=0;l<s;l++){var u=a[l];this.add(u)}},t.exports=i},function(t,e,r){"use strict";function n(){}o(n,"Matrix"),n.multMat=function(i,a){for(var s=[],l=0;l<i.length;l++){s[l]=[];for(var u=0;u<a[0].length;u++){s[l][u]=0;for(var h=0;h<i[0].length;h++)s[l][u]+=i[l][h]*a[h][u]}}return s},n.transpose=function(i){for(var a=[],s=0;s<i[0].length;s++){a[s]=[];for(var l=0;l<i.length;l++)a[s][l]=i[l][s]}return a},n.multCons=function(i,a){for(var s=[],l=0;l<i.length;l++)s[l]=i[l]*a;return s},n.minusOp=function(i,a){for(var s=[],l=0;l<i.length;l++)s[l]=i[l]-a[l];return s},n.dotProduct=function(i,a){for(var s=0,l=0;l<i.length;l++)s+=i[l]*a[l];return s},n.mag=function(i){return Math.sqrt(this.dotProduct(i,i))},n.normalize=function(i){for(var a=[],s=this.mag(i),l=0;l<i.length;l++)a[l]=i[l]/s;return a},n.multGamma=function(i){for(var a=[],s=0,l=0;l<i.length;l++)s+=i[l];s*=-1/i.length;for(var u=0;u<i.length;u++)a[u]=s+i[u];return a},n.multL=function(i,a,s){for(var l=[],u=[],h=[],f=0;f<a[0].length;f++){for(var d=0,p=0;p<a.length;p++)d+=-.5*a[p][f]*i[p];u[f]=d}for(var m=0;m<s.length;m++){for(var g=0,y=0;y<s.length;y++)g+=s[m][y]*u[y];h[m]=g}for(var v=0;v<a.length;v++){for(var x=0,b=0;b<a[0].length;b++)x+=a[v][b]*h[b];l[v]=x}return l},t.exports=n},function(t,e,r){"use strict";var n=function(){function l(u,h){for(var f=0;f<h.length;f++){var d=h[f];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(u,d.key,d)}}return o(l,"defineProperties"),function(u,h,f){return h&&l(u.prototype,h),f&&l(u,f),u}}();function i(l,u){if(!(l instanceof u))throw new TypeError("Cannot call a class as a function")}o(i,"_classCallCheck");var a=r(11),s=function(){function l(u,h){i(this,l),(h!==null||h!==void 0)&&(this.compareFunction=this._defaultCompareFunction);var f=void 0;u instanceof a?f=u.size():f=u.length,this._quicksort(u,0,f-1)}return o(l,"Quicksort"),n(l,[{key:"_quicksort",value:o(function(h,f,d){if(f<d){var p=this._partition(h,f,d);this._quicksort(h,f,p),this._quicksort(h,p+1,d)}},"_quicksort")},{key:"_partition",value:o(function(h,f,d){for(var p=this._get(h,f),m=f,g=d;;){for(;this.compareFunction(p,this._get(h,g));)g--;for(;this.compareFunction(this._get(h,m),p);)m++;if(m<g)this._swap(h,m,g),m++,g--;else return g}},"_partition")},{key:"_get",value:o(function(h,f){return h instanceof a?h.get_object_at(f):h[f]},"_get")},{key:"_set",value:o(function(h,f,d){h instanceof a?h.set_object_at(f,d):h[f]=d},"_set")},{key:"_swap",value:o(function(h,f,d){var p=this._get(h,f);this._set(h,f,this._get(h,d)),this._set(h,d,p)},"_swap")},{key:"_defaultCompareFunction",value:o(function(h,f){return f>h},"_defaultCompareFunction")}]),l}();t.exports=s},function(t,e,r){"use strict";function n(){}o(n,"SVD"),n.svd=function(i){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=i.length,this.n=i[0].length;var a=Math.min(this.m,this.n);this.s=function(xt){for(var ut=[];xt-- >0;)ut.push(0);return ut}(Math.min(this.m+1,this.n)),this.U=function(xt){var ut=o(function Et(ft){if(ft.length==0)return 0;for(var yt=[],nt=0;nt<ft[0];nt++)yt.push(Et(ft.slice(1)));return yt},"allocate");return ut(xt)}([this.m,a]),this.V=function(xt){var ut=o(function Et(ft){if(ft.length==0)return 0;for(var yt=[],nt=0;nt<ft[0];nt++)yt.push(Et(ft.slice(1)));return yt},"allocate");return ut(xt)}([this.n,this.n]);for(var s=function(xt){for(var ut=[];xt-- >0;)ut.push(0);return ut}(this.n),l=function(xt){for(var ut=[];xt-- >0;)ut.push(0);return ut}(this.m),u=!0,h=!0,f=Math.min(this.m-1,this.n),d=Math.max(0,Math.min(this.n-2,this.m)),p=0;p<Math.max(f,d);p++){if(p<f){this.s[p]=0;for(var m=p;m<this.m;m++)this.s[p]=n.hypot(this.s[p],i[m][p]);if(this.s[p]!==0){i[p][p]<0&&(this.s[p]=-this.s[p]);for(var g=p;g<this.m;g++)i[g][p]/=this.s[p];i[p][p]+=1}this.s[p]=-this.s[p]}for(var y=p+1;y<this.n;y++){if(function(xt,ut){return xt&&ut}(p<f,this.s[p]!==0)){for(var v=0,x=p;x<this.m;x++)v+=i[x][p]*i[x][y];v=-v/i[p][p];for(var b=p;b<this.m;b++)i[b][y]+=v*i[b][p]}s[y]=i[p][y]}if(function(xt,ut){return xt&&ut}(u,p<f))for(var w=p;w<this.m;w++)this.U[w][p]=i[w][p];if(p<d){s[p]=0;for(var C=p+1;C<this.n;C++)s[p]=n.hypot(s[p],s[C]);if(s[p]!==0){s[p+1]<0&&(s[p]=-s[p]);for(var T=p+1;T<this.n;T++)s[T]/=s[p];s[p+1]+=1}if(s[p]=-s[p],function(xt,ut){return xt&&ut}(p+1<this.m,s[p]!==0)){for(var E=p+1;E<this.m;E++)l[E]=0;for(var A=p+1;A<this.n;A++)for(var S=p+1;S<this.m;S++)l[S]+=s[A]*i[S][A];for(var _=p+1;_<this.n;_++)for(var I=-s[_]/s[p+1],D=p+1;D<this.m;D++)i[D][_]+=I*l[D]}if(h)for(var k=p+1;k<this.n;k++)this.V[k][p]=s[k]}}var L=Math.min(this.n,this.m+1);if(f<this.n&&(this.s[f]=i[f][f]),this.m<L&&(this.s[L-1]=0),d+1<L&&(s[d]=i[d][L-1]),s[L-1]=0,u){for(var R=f;R<a;R++){for(var O=0;O<this.m;O++)this.U[O][R]=0;this.U[R][R]=1}for(var M=f-1;M>=0;M--)if(this.s[M]!==0){for(var B=M+1;B<a;B++){for(var F=0,P=M;P<this.m;P++)F+=this.U[P][M]*this.U[P][B];F=-F/this.U[M][M];for(var z=M;z<this.m;z++)this.U[z][B]+=F*this.U[z][M]}for(var $=M;$<this.m;$++)this.U[$][M]=-this.U[$][M];this.U[M][M]=1+this.U[M][M];for(var H=0;H<M-1;H++)this.U[H][M]=0}else{for(var Q=0;Q<this.m;Q++)this.U[Q][M]=0;this.U[M][M]=1}}if(h)for(var j=this.n-1;j>=0;j--){if(function(xt,ut){return xt&&ut}(j<d,s[j]!==0))for(var ie=j+1;ie<a;ie++){for(var ne=0,le=j+1;le<this.n;le++)ne+=this.V[le][j]*this.V[le][ie];ne=-ne/this.V[j+1][j];for(var he=j+1;he<this.n;he++)this.V[he][ie]+=ne*this.V[he][j]}for(var K=0;K<this.n;K++)this.V[K][j]=0;this.V[j][j]=1}for(var X=L-1,te=0,J=Math.pow(2,-52),se=Math.pow(2,-966);L>0;){var ue=void 0,Z=void 0;for(ue=L-2;ue>=-1&&ue!==-1;ue--)if(Math.abs(s[ue])<=se+J*(Math.abs(this.s[ue])+Math.abs(this.s[ue+1]))){s[ue]=0;break}if(ue===L-2)Z=4;else{var Se=void 0;for(Se=L-1;Se>=ue&&Se!==ue;Se--){var ce=(Se!==L?Math.abs(s[Se]):0)+(Se!==ue+1?Math.abs(s[Se-1]):0);if(Math.abs(this.s[Se])<=se+J*ce){this.s[Se]=0;break}}Se===ue?Z=3:Se===L-1?Z=1:(Z=2,ue=Se)}switch(ue++,Z){case 1:{var ae=s[L-2];s[L-2]=0;for(var Oe=L-2;Oe>=ue;Oe--){var ge=n.hypot(this.s[Oe],ae),ze=this.s[Oe]/ge,He=ae/ge;if(this.s[Oe]=ge,Oe!==ue&&(ae=-He*s[Oe-1],s[Oe-1]=ze*s[Oe-1]),h)for(var $e=0;$e<this.n;$e++)ge=ze*this.V[$e][Oe]+He*this.V[$e][L-1],this.V[$e][L-1]=-He*this.V[$e][Oe]+ze*this.V[$e][L-1],this.V[$e][Oe]=ge}}break;case 2:{var Re=s[ue-1];s[ue-1]=0;for(var Ie=ue;Ie<L;Ie++){var be=n.hypot(this.s[Ie],Re),W=this.s[Ie]/be,de=Re/be;if(this.s[Ie]=be,Re=-de*s[Ie],s[Ie]=W*s[Ie],u)for(var re=0;re<this.m;re++)be=W*this.U[re][Ie]+de*this.U[re][ue-1],this.U[re][ue-1]=-de*this.U[re][Ie]+W*this.U[re][ue-1],this.U[re][Ie]=be}}break;case 3:{var oe=Math.max(Math.max(Math.max(Math.max(Math.abs(this.s[L-1]),Math.abs(this.s[L-2])),Math.abs(s[L-2])),Math.abs(this.s[ue])),Math.abs(s[ue])),V=this.s[L-1]/oe,xe=this.s[L-2]/oe,q=s[L-2]/oe,pe=this.s[ue]/oe,ve=s[ue]/oe,Pe=((xe+V)*(xe-V)+q*q)/2,_e=V*q*(V*q),we=0;(function(xt,ut){return xt||ut})(Pe!==0,_e!==0)&&(we=Math.sqrt(Pe*Pe+_e),Pe<0&&(we=-we),we=_e/(Pe+we));for(var Ve=(pe+V)*(pe-V)+we,De=pe*ve,qe=ue;qe<L-1;qe++){var at=n.hypot(Ve,De),Rt=Ve/at,st=De/at;if(qe!==ue&&(s[qe-1]=at),Ve=Rt*this.s[qe]+st*s[qe],s[qe]=Rt*s[qe]-st*this.s[qe],De=st*this.s[qe+1],this.s[qe+1]=Rt*this.s[qe+1],h)for(var Ue=0;Ue<this.n;Ue++)at=Rt*this.V[Ue][qe]+st*this.V[Ue][qe+1],this.V[Ue][qe+1]=-st*this.V[Ue][qe]+Rt*this.V[Ue][qe+1],this.V[Ue][qe]=at;if(at=n.hypot(Ve,De),Rt=Ve/at,st=De/at,this.s[qe]=at,Ve=Rt*s[qe]+st*this.s[qe+1],this.s[qe+1]=-st*s[qe]+Rt*this.s[qe+1],De=st*s[qe+1],s[qe+1]=Rt*s[qe+1],u&&qe<this.m-1)for(var ct=0;ct<this.m;ct++)at=Rt*this.U[ct][qe]+st*this.U[ct][qe+1],this.U[ct][qe+1]=-st*this.U[ct][qe]+Rt*this.U[ct][qe+1],this.U[ct][qe]=at}s[L-2]=Ve,te=te+1}break;case 4:{if(this.s[ue]<=0&&(this.s[ue]=this.s[ue]<0?-this.s[ue]:0,h))for(var We=0;We<=X;We++)this.V[We][ue]=-this.V[We][ue];for(;ue<X&&!(this.s[ue]>=this.s[ue+1]);){var ot=this.s[ue];if(this.s[ue]=this.s[ue+1],this.s[ue+1]=ot,h&&ue<this.n-1)for(var Yt=0;Yt<this.n;Yt++)ot=this.V[Yt][ue+1],this.V[Yt][ue+1]=this.V[Yt][ue],this.V[Yt][ue]=ot;if(u&&ue<this.m-1)for(var bt=0;bt<this.m;bt++)ot=this.U[bt][ue+1],this.U[bt][ue+1]=this.U[bt][ue],this.U[bt][ue]=ot;ue++}te=0,L--}break}}var Mt={U:this.U,V:this.V,S:this.s};return Mt},n.hypot=function(i,a){var s=void 0;return Math.abs(i)>Math.abs(a)?(s=a/i,s=Math.abs(i)*Math.sqrt(1+s*s)):a!=0?(s=i/a,s=Math.abs(a)*Math.sqrt(1+s*s)):s=0,s},t.exports=n},function(t,e,r){"use strict";var n=function(){function s(l,u){for(var h=0;h<u.length;h++){var f=u[h];f.enumerable=f.enumerable||!1,f.configurable=!0,"value"in f&&(f.writable=!0),Object.defineProperty(l,f.key,f)}}return o(s,"defineProperties"),function(l,u,h){return u&&s(l.prototype,u),h&&s(l,h),l}}();function i(s,l){if(!(s instanceof l))throw new TypeError("Cannot call a class as a function")}o(i,"_classCallCheck");var a=function(){function s(l,u){var h=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,f=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,d=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;i(this,s),this.sequence1=l,this.sequence2=u,this.match_score=h,this.mismatch_penalty=f,this.gap_penalty=d,this.iMax=l.length+1,this.jMax=u.length+1,this.grid=new Array(this.iMax);for(var p=0;p<this.iMax;p++){this.grid[p]=new Array(this.jMax);for(var m=0;m<this.jMax;m++)this.grid[p][m]=0}this.tracebackGrid=new Array(this.iMax);for(var g=0;g<this.iMax;g++){this.tracebackGrid[g]=new Array(this.jMax);for(var y=0;y<this.jMax;y++)this.tracebackGrid[g][y]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return o(s,"NeedlemanWunsch"),n(s,[{key:"getScore",value:o(function(){return this.score},"getScore")},{key:"getAlignments",value:o(function(){return this.alignments},"getAlignments")},{key:"computeGrids",value:o(function(){for(var u=1;u<this.jMax;u++)this.grid[0][u]=this.grid[0][u-1]+this.gap_penalty,this.tracebackGrid[0][u]=[!1,!1,!0];for(var h=1;h<this.iMax;h++)this.grid[h][0]=this.grid[h-1][0]+this.gap_penalty,this.tracebackGrid[h][0]=[!1,!0,!1];for(var f=1;f<this.iMax;f++)for(var d=1;d<this.jMax;d++){var p=void 0;this.sequence1[f-1]===this.sequence2[d-1]?p=this.grid[f-1][d-1]+this.match_score:p=this.grid[f-1][d-1]+this.mismatch_penalty;var m=this.grid[f-1][d]+this.gap_penalty,g=this.grid[f][d-1]+this.gap_penalty,y=[p,m,g],v=this.arrayAllMaxIndexes(y);this.grid[f][d]=y[v[0]],this.tracebackGrid[f][d]=[v.includes(0),v.includes(1),v.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]},"computeGrids")},{key:"alignmentTraceback",value:o(function(){var u=[];for(u.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});u[0];){var h=u[0],f=this.tracebackGrid[h.pos[0]][h.pos[1]];f[0]&&u.push({pos:[h.pos[0]-1,h.pos[1]-1],seq1:this.sequence1[h.pos[0]-1]+h.seq1,seq2:this.sequence2[h.pos[1]-1]+h.seq2}),f[1]&&u.push({pos:[h.pos[0]-1,h.pos[1]],seq1:this.sequence1[h.pos[0]-1]+h.seq1,seq2:"-"+h.seq2}),f[2]&&u.push({pos:[h.pos[0],h.pos[1]-1],seq1:"-"+h.seq1,seq2:this.sequence2[h.pos[1]-1]+h.seq2}),h.pos[0]===0&&h.pos[1]===0&&this.alignments.push({sequence1:h.seq1,sequence2:h.seq2}),u.shift()}return this.alignments},"alignmentTraceback")},{key:"getAllIndexes",value:o(function(u,h){for(var f=[],d=-1;(d=u.indexOf(h,d+1))!==-1;)f.push(d);return f},"getAllIndexes")},{key:"arrayAllMaxIndexes",value:o(function(u){return this.getAllIndexes(u,Math.max.apply(null,u))},"arrayAllMaxIndexes")}]),s}();t.exports=a},function(t,e,r){"use strict";var n=o(function(){},"layoutBase");n.FDLayout=r(18),n.FDLayoutConstants=r(4),n.FDLayoutEdge=r(19),n.FDLayoutNode=r(20),n.DimensionD=r(21),n.HashMap=r(22),n.HashSet=r(23),n.IGeometry=r(8),n.IMath=r(9),n.Integer=r(10),n.Point=r(12),n.PointD=r(5),n.RandomSeed=r(16),n.RectangleD=r(13),n.Transform=r(17),n.UniqueIDGeneretor=r(14),n.Quicksort=r(25),n.LinkedList=r(11),n.LGraphObject=r(2),n.LGraph=r(6),n.LEdge=r(1),n.LGraphManager=r(7),n.LNode=r(3),n.Layout=r(15),n.LayoutConstants=r(0),n.NeedlemanWunsch=r(27),n.Matrix=r(24),n.SVD=r(26),t.exports=n},function(t,e,r){"use strict";function n(){this.listeners=[]}o(n,"Emitter");var i=n.prototype;i.addListener=function(a,s){this.listeners.push({event:a,callback:s})},i.removeListener=function(a,s){for(var l=this.listeners.length;l>=0;l--){var u=this.listeners[l];u.event===a&&u.callback===s&&this.listeners.splice(l,1)}},i.emit=function(a,s){for(var l=0;l<this.listeners.length;l++){var u=this.listeners[l];a===u.event&&u.callback(s)}},t.exports=n}])})});var mF=Mi((k4,pF)=>{"use strict";o(function(e,r){typeof k4=="object"&&typeof pF=="object"?pF.exports=r(dF()):typeof define=="function"&&define.amd?define(["layout-base"],r):typeof k4=="object"?k4.coseBase=r(dF()):e.coseBase=r(e.layoutBase)},"webpackUniversalModuleDefinition")(k4,function(t){return(()=>{"use strict";var e={45:(a,s,l)=>{var u={};u.layoutBase=l(551),u.CoSEConstants=l(806),u.CoSEEdge=l(767),u.CoSEGraph=l(880),u.CoSEGraphManager=l(578),u.CoSELayout=l(765),u.CoSENode=l(991),u.ConstraintHandler=l(902),a.exports=u},806:(a,s,l)=>{var u=l(551).FDLayoutConstants;function h(){}o(h,"CoSEConstants");for(var f in u)h[f]=u[f];h.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,h.DEFAULT_RADIAL_SEPARATION=u.DEFAULT_EDGE_LENGTH,h.DEFAULT_COMPONENT_SEPERATION=60,h.TILE=!0,h.TILING_PADDING_VERTICAL=10,h.TILING_PADDING_HORIZONTAL=10,h.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,h.ENFORCE_CONSTRAINTS=!0,h.APPLY_LAYOUT=!0,h.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,h.TREE_REDUCTION_ON_INCREMENTAL=!0,h.PURE_INCREMENTAL=h.DEFAULT_INCREMENTAL,a.exports=h},767:(a,s,l)=>{var u=l(551).FDLayoutEdge;function h(d,p,m){u.call(this,d,p,m)}o(h,"CoSEEdge"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},880:(a,s,l)=>{var u=l(551).LGraph;function h(d,p,m){u.call(this,d,p,m)}o(h,"CoSEGraph"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},578:(a,s,l)=>{var u=l(551).LGraphManager;function h(d){u.call(this,d)}o(h,"CoSEGraphManager"),h.prototype=Object.create(u.prototype);for(var f in u)h[f]=u[f];a.exports=h},765:(a,s,l)=>{var u=l(551).FDLayout,h=l(578),f=l(880),d=l(991),p=l(767),m=l(806),g=l(902),y=l(551).FDLayoutConstants,v=l(551).LayoutConstants,x=l(551).Point,b=l(551).PointD,w=l(551).DimensionD,C=l(551).Layout,T=l(551).Integer,E=l(551).IGeometry,A=l(551).LGraph,S=l(551).Transform,_=l(551).LinkedList;function I(){u.call(this),this.toBeTiled={},this.constraints={}}o(I,"CoSELayout"),I.prototype=Object.create(u.prototype);for(var D in u)I[D]=u[D];I.prototype.newGraphManager=function(){var k=new h(this);return this.graphManager=k,k},I.prototype.newGraph=function(k){return new f(null,this.graphManager,k)},I.prototype.newNode=function(k){return new d(this.graphManager,k)},I.prototype.newEdge=function(k){return new p(null,null,k)},I.prototype.initParameters=function(){u.prototype.initParameters.call(this,arguments),this.isSubLayout||(m.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=m.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=m.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=y.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=y.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=y.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=y.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},I.prototype.initSpringEmbedder=function(){u.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/y.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},I.prototype.layout=function(){var k=v.DEFAULT_CREATE_BENDS_AS_NEEDED;return k&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},I.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(m.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var L=new Set(this.getAllNodes()),R=this.nodesWithGravity.filter(function(B){return L.has(B)});this.graphManager.setAllNodesToApplyGravitation(R)}}else{var k=this.getFlatForest();if(k.length>0)this.positionNodesRadially(k);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var L=new Set(this.getAllNodes()),R=this.nodesWithGravity.filter(function(O){return L.has(O)});this.graphManager.setAllNodesToApplyGravitation(R),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(g.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),m.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},I.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%y.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var k=new Set(this.getAllNodes()),L=this.nodesWithGravity.filter(function(M){return k.has(M)});this.graphManager.setAllNodesToApplyGravitation(L),this.graphManager.updateBounds(),this.updateGrid(),m.PURE_INCREMENTAL?this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),m.PURE_INCREMENTAL?this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=y.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var R=!this.isTreeGrowing&&!this.isGrowthFinished,O=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(R,O),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},I.prototype.getPositionsData=function(){for(var k=this.graphManager.getAllNodes(),L={},R=0;R<k.length;R++){var O=k[R].rect,M=k[R].id;L[M]={id:M,x:O.getCenterX(),y:O.getCenterY(),w:O.width,h:O.height}}return L},I.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var k=!1;if(y.ANIMATE==="during")this.emit("layoutstarted");else{for(;!k;)k=this.tick();this.graphManager.updateBounds()}},I.prototype.moveNodes=function(){for(var k=this.getAllNodes(),L,R=0;R<k.length;R++)L=k[R],L.calculateDisplacement();Object.keys(this.constraints).length>0&&this.updateDisplacements();for(var R=0;R<k.length;R++)L=k[R],L.move()},I.prototype.initConstraintVariables=function(){var k=this;this.idToNodeMap=new Map,this.fixedNodeSet=new Set;for(var L=this.graphManager.getAllNodes(),R=0;R<L.length;R++){var O=L[R];this.idToNodeMap.set(O.id,O)}var M=o(function le(he){for(var K=he.getChild().getNodes(),X,te=0,J=0;J<K.length;J++)X=K[J],X.getChild()==null?k.fixedNodeSet.has(X.id)&&(te+=100):te+=le(X);return te},"calculateCompoundWeight");if(this.constraints.fixedNodeConstraint){this.constraints.fixedNodeConstraint.forEach(function(K){k.fixedNodeSet.add(K.nodeId)});for(var L=this.graphManager.getAllNodes(),O,R=0;R<L.length;R++)if(O=L[R],O.getChild()!=null){var B=M(O);B>0&&(O.fixedNodeWeight=B)}}if(this.constraints.relativePlacementConstraint){var F=new Map,P=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach(function(le){k.fixedNodesOnHorizontal.add(le),k.fixedNodesOnVertical.add(le)}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var z=this.constraints.alignmentConstraint.vertical,R=0;R<z.length;R++)this.dummyToNodeForVerticalAlignment.set("dummy"+R,[]),z[R].forEach(function(he){F.set(he,"dummy"+R),k.dummyToNodeForVerticalAlignment.get("dummy"+R).push(he),k.fixedNodeSet.has(he)&&k.fixedNodesOnHorizontal.add("dummy"+R)});if(this.constraints.alignmentConstraint.horizontal)for(var $=this.constraints.alignmentConstraint.horizontal,R=0;R<$.length;R++)this.dummyToNodeForHorizontalAlignment.set("dummy"+R,[]),$[R].forEach(function(he){P.set(he,"dummy"+R),k.dummyToNodeForHorizontalAlignment.get("dummy"+R).push(he),k.fixedNodeSet.has(he)&&k.fixedNodesOnVertical.add("dummy"+R)})}if(m.RELAX_MOVEMENT_ON_CONSTRAINTS)this.shuffle=function(le){var he,K,X;for(X=le.length-1;X>=2*le.length/3;X--)he=Math.floor(Math.random()*(X+1)),K=le[X],le[X]=le[he],le[he]=K;return le},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach(function(le){if(le.left){var he=F.has(le.left)?F.get(le.left):le.left,K=F.has(le.right)?F.get(le.right):le.right;k.nodesInRelativeHorizontal.includes(he)||(k.nodesInRelativeHorizontal.push(he),k.nodeToRelativeConstraintMapHorizontal.set(he,[]),k.dummyToNodeForVerticalAlignment.has(he)?k.nodeToTempPositionMapHorizontal.set(he,k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(he)[0]).getCenterX()):k.nodeToTempPositionMapHorizontal.set(he,k.idToNodeMap.get(he).getCenterX())),k.nodesInRelativeHorizontal.includes(K)||(k.nodesInRelativeHorizontal.push(K),k.nodeToRelativeConstraintMapHorizontal.set(K,[]),k.dummyToNodeForVerticalAlignment.has(K)?k.nodeToTempPositionMapHorizontal.set(K,k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(K)[0]).getCenterX()):k.nodeToTempPositionMapHorizontal.set(K,k.idToNodeMap.get(K).getCenterX())),k.nodeToRelativeConstraintMapHorizontal.get(he).push({right:K,gap:le.gap}),k.nodeToRelativeConstraintMapHorizontal.get(K).push({left:he,gap:le.gap})}else{var X=P.has(le.top)?P.get(le.top):le.top,te=P.has(le.bottom)?P.get(le.bottom):le.bottom;k.nodesInRelativeVertical.includes(X)||(k.nodesInRelativeVertical.push(X),k.nodeToRelativeConstraintMapVertical.set(X,[]),k.dummyToNodeForHorizontalAlignment.has(X)?k.nodeToTempPositionMapVertical.set(X,k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(X)[0]).getCenterY()):k.nodeToTempPositionMapVertical.set(X,k.idToNodeMap.get(X).getCenterY())),k.nodesInRelativeVertical.includes(te)||(k.nodesInRelativeVertical.push(te),k.nodeToRelativeConstraintMapVertical.set(te,[]),k.dummyToNodeForHorizontalAlignment.has(te)?k.nodeToTempPositionMapVertical.set(te,k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(te)[0]).getCenterY()):k.nodeToTempPositionMapVertical.set(te,k.idToNodeMap.get(te).getCenterY())),k.nodeToRelativeConstraintMapVertical.get(X).push({bottom:te,gap:le.gap}),k.nodeToRelativeConstraintMapVertical.get(te).push({top:X,gap:le.gap})}});else{var H=new Map,Q=new Map;this.constraints.relativePlacementConstraint.forEach(function(le){if(le.left){var he=F.has(le.left)?F.get(le.left):le.left,K=F.has(le.right)?F.get(le.right):le.right;H.has(he)?H.get(he).push(K):H.set(he,[K]),H.has(K)?H.get(K).push(he):H.set(K,[he])}else{var X=P.has(le.top)?P.get(le.top):le.top,te=P.has(le.bottom)?P.get(le.bottom):le.bottom;Q.has(X)?Q.get(X).push(te):Q.set(X,[te]),Q.has(te)?Q.get(te).push(X):Q.set(te,[X])}});var j=o(function(he,K){var X=[],te=[],J=new _,se=new Set,ue=0;return he.forEach(function(Z,Se){if(!se.has(Se)){X[ue]=[],te[ue]=!1;var ce=Se;for(J.push(ce),se.add(ce),X[ue].push(ce);J.length!=0;){ce=J.shift(),K.has(ce)&&(te[ue]=!0);var ae=he.get(ce);ae.forEach(function(Oe){se.has(Oe)||(J.push(Oe),se.add(Oe),X[ue].push(Oe))})}ue++}}),{components:X,isFixed:te}},"constructComponents"),ie=j(H,k.fixedNodesOnHorizontal);this.componentsOnHorizontal=ie.components,this.fixedComponentsOnHorizontal=ie.isFixed;var ne=j(Q,k.fixedNodesOnVertical);this.componentsOnVertical=ne.components,this.fixedComponentsOnVertical=ne.isFixed}}},I.prototype.updateDisplacements=function(){var k=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach(function(ne){var le=k.idToNodeMap.get(ne.nodeId);le.displacementX=0,le.displacementY=0}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var L=this.constraints.alignmentConstraint.vertical,R=0;R<L.length;R++){for(var O=0,M=0;M<L[R].length;M++){if(this.fixedNodeSet.has(L[R][M])){O=0;break}O+=this.idToNodeMap.get(L[R][M]).displacementX}for(var B=O/L[R].length,M=0;M<L[R].length;M++)this.idToNodeMap.get(L[R][M]).displacementX=B}if(this.constraints.alignmentConstraint.horizontal)for(var F=this.constraints.alignmentConstraint.horizontal,R=0;R<F.length;R++){for(var P=0,M=0;M<F[R].length;M++){if(this.fixedNodeSet.has(F[R][M])){P=0;break}P+=this.idToNodeMap.get(F[R][M]).displacementY}for(var z=P/F[R].length,M=0;M<F[R].length;M++)this.idToNodeMap.get(F[R][M]).displacementY=z}}if(this.constraints.relativePlacementConstraint)if(m.RELAX_MOVEMENT_ON_CONSTRAINTS)this.totalIterations%10==0&&(this.shuffle(this.nodesInRelativeHorizontal),this.shuffle(this.nodesInRelativeVertical)),this.nodesInRelativeHorizontal.forEach(function(ne){if(!k.fixedNodesOnHorizontal.has(ne)){var le=0;k.dummyToNodeForVerticalAlignment.has(ne)?le=k.idToNodeMap.get(k.dummyToNodeForVerticalAlignment.get(ne)[0]).displacementX:le=k.idToNodeMap.get(ne).displacementX,k.nodeToRelativeConstraintMapHorizontal.get(ne).forEach(function(he){if(he.right){var K=k.nodeToTempPositionMapHorizontal.get(he.right)-k.nodeToTempPositionMapHorizontal.get(ne)-le;K<he.gap&&(le-=he.gap-K)}else{var K=k.nodeToTempPositionMapHorizontal.get(ne)-k.nodeToTempPositionMapHorizontal.get(he.left)+le;K<he.gap&&(le+=he.gap-K)}}),k.nodeToTempPositionMapHorizontal.set(ne,k.nodeToTempPositionMapHorizontal.get(ne)+le),k.dummyToNodeForVerticalAlignment.has(ne)?k.dummyToNodeForVerticalAlignment.get(ne).forEach(function(he){k.idToNodeMap.get(he).displacementX=le}):k.idToNodeMap.get(ne).displacementX=le}}),this.nodesInRelativeVertical.forEach(function(ne){if(!k.fixedNodesOnHorizontal.has(ne)){var le=0;k.dummyToNodeForHorizontalAlignment.has(ne)?le=k.idToNodeMap.get(k.dummyToNodeForHorizontalAlignment.get(ne)[0]).displacementY:le=k.idToNodeMap.get(ne).displacementY,k.nodeToRelativeConstraintMapVertical.get(ne).forEach(function(he){if(he.bottom){var K=k.nodeToTempPositionMapVertical.get(he.bottom)-k.nodeToTempPositionMapVertical.get(ne)-le;K<he.gap&&(le-=he.gap-K)}else{var K=k.nodeToTempPositionMapVertical.get(ne)-k.nodeToTempPositionMapVertical.get(he.top)+le;K<he.gap&&(le+=he.gap-K)}}),k.nodeToTempPositionMapVertical.set(ne,k.nodeToTempPositionMapVertical.get(ne)+le),k.dummyToNodeForHorizontalAlignment.has(ne)?k.dummyToNodeForHorizontalAlignment.get(ne).forEach(function(he){k.idToNodeMap.get(he).displacementY=le}):k.idToNodeMap.get(ne).displacementY=le}});else{for(var R=0;R<this.componentsOnHorizontal.length;R++){var $=this.componentsOnHorizontal[R];if(this.fixedComponentsOnHorizontal[R])for(var M=0;M<$.length;M++)this.dummyToNodeForVerticalAlignment.has($[M])?this.dummyToNodeForVerticalAlignment.get($[M]).forEach(function(he){k.idToNodeMap.get(he).displacementX=0}):this.idToNodeMap.get($[M]).displacementX=0;else{for(var H=0,Q=0,M=0;M<$.length;M++)if(this.dummyToNodeForVerticalAlignment.has($[M])){var j=this.dummyToNodeForVerticalAlignment.get($[M]);H+=j.length*this.idToNodeMap.get(j[0]).displacementX,Q+=j.length}else H+=this.idToNodeMap.get($[M]).displacementX,Q++;for(var ie=H/Q,M=0;M<$.length;M++)this.dummyToNodeForVerticalAlignment.has($[M])?this.dummyToNodeForVerticalAlignment.get($[M]).forEach(function(he){k.idToNodeMap.get(he).displacementX=ie}):this.idToNodeMap.get($[M]).displacementX=ie}}for(var R=0;R<this.componentsOnVertical.length;R++){var $=this.componentsOnVertical[R];if(this.fixedComponentsOnVertical[R])for(var M=0;M<$.length;M++)this.dummyToNodeForHorizontalAlignment.has($[M])?this.dummyToNodeForHorizontalAlignment.get($[M]).forEach(function(K){k.idToNodeMap.get(K).displacementY=0}):this.idToNodeMap.get($[M]).displacementY=0;else{for(var H=0,Q=0,M=0;M<$.length;M++)if(this.dummyToNodeForHorizontalAlignment.has($[M])){var j=this.dummyToNodeForHorizontalAlignment.get($[M]);H+=j.length*this.idToNodeMap.get(j[0]).displacementY,Q+=j.length}else H+=this.idToNodeMap.get($[M]).displacementY,Q++;for(var ie=H/Q,M=0;M<$.length;M++)this.dummyToNodeForHorizontalAlignment.has($[M])?this.dummyToNodeForHorizontalAlignment.get($[M]).forEach(function(J){k.idToNodeMap.get(J).displacementY=ie}):this.idToNodeMap.get($[M]).displacementY=ie}}}},I.prototype.calculateNodesToApplyGravitationTo=function(){var k=[],L,R=this.graphManager.getGraphs(),O=R.length,M;for(M=0;M<O;M++)L=R[M],L.updateConnected(),L.isConnected||(k=k.concat(L.getNodes()));return k},I.prototype.createBendpoints=function(){var k=[];k=k.concat(this.graphManager.getAllEdges());var L=new Set,R;for(R=0;R<k.length;R++){var O=k[R];if(!L.has(O)){var M=O.getSource(),B=O.getTarget();if(M==B)O.getBendpoints().push(new b),O.getBendpoints().push(new b),this.createDummyNodesForBendpoints(O),L.add(O);else{var F=[];if(F=F.concat(M.getEdgeListToNode(B)),F=F.concat(B.getEdgeListToNode(M)),!L.has(F[0])){if(F.length>1){var P;for(P=0;P<F.length;P++){var z=F[P];z.getBendpoints().push(new b),this.createDummyNodesForBendpoints(z)}}F.forEach(function($){L.add($)})}}}if(L.size==k.length)break}},I.prototype.positionNodesRadially=function(k){for(var L=new x(0,0),R=Math.ceil(Math.sqrt(k.length)),O=0,M=0,B=0,F=new b(0,0),P=0;P<k.length;P++){P%R==0&&(B=0,M=O,P!=0&&(M+=m.DEFAULT_COMPONENT_SEPERATION),O=0);var z=k[P],$=C.findCenterOfTree(z);L.x=B,L.y=M,F=I.radialLayout(z,$,L),F.y>O&&(O=Math.floor(F.y)),B=Math.floor(F.x+m.DEFAULT_COMPONENT_SEPERATION)}this.transform(new b(v.WORLD_CENTER_X-F.x/2,v.WORLD_CENTER_Y-F.y/2))},I.radialLayout=function(k,L,R){var O=Math.max(this.maxDiagonalInTree(k),m.DEFAULT_RADIAL_SEPARATION);I.branchRadialLayout(L,null,0,359,0,O);var M=A.calculateBounds(k),B=new S;B.setDeviceOrgX(M.getMinX()),B.setDeviceOrgY(M.getMinY()),B.setWorldOrgX(R.x),B.setWorldOrgY(R.y);for(var F=0;F<k.length;F++){var P=k[F];P.transform(B)}var z=new b(M.getMaxX(),M.getMaxY());return B.inverseTransformPoint(z)},I.branchRadialLayout=function(k,L,R,O,M,B){var F=(O-R+1)/2;F<0&&(F+=180);var P=(F+R)%360,z=P*E.TWO_PI/360,$=Math.cos(z),H=M*Math.cos(z),Q=M*Math.sin(z);k.setCenter(H,Q);var j=[];j=j.concat(k.getEdges());var ie=j.length;L!=null&&ie--;for(var ne=0,le=j.length,he,K=k.getEdgesBetween(L);K.length>1;){var X=K[0];K.splice(0,1);var te=j.indexOf(X);te>=0&&j.splice(te,1),le--,ie--}L!=null?he=(j.indexOf(K[0])+1)%le:he=0;for(var J=Math.abs(O-R)/ie,se=he;ne!=ie;se=++se%le){var ue=j[se].getOtherEnd(k);if(ue!=L){var Z=(R+ne*J)%360,Se=(Z+J)%360;I.branchRadialLayout(ue,k,Z,Se,M+B,B),ne++}}},I.maxDiagonalInTree=function(k){for(var L=T.MIN_VALUE,R=0;R<k.length;R++){var O=k[R],M=O.getDiagonal();M>L&&(L=M)}return L},I.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},I.prototype.groupZeroDegreeMembers=function(){var k=this,L={};this.memberGroups={},this.idToDummyNode={};for(var R=[],O=this.graphManager.getAllNodes(),M=0;M<O.length;M++){var B=O[M],F=B.getParent();this.getNodeDegreeWithChildren(B)===0&&(F.id==null||!this.getToBeTiled(F))&&R.push(B)}for(var M=0;M<R.length;M++){var B=R[M],P=B.getParent().id;typeof L[P]>"u"&&(L[P]=[]),L[P]=L[P].concat(B)}Object.keys(L).forEach(function(z){if(L[z].length>1){var $="DummyCompound_"+z;k.memberGroups[$]=L[z];var H=L[z][0].getParent(),Q=new d(k.graphManager);Q.id=$,Q.paddingLeft=H.paddingLeft||0,Q.paddingRight=H.paddingRight||0,Q.paddingBottom=H.paddingBottom||0,Q.paddingTop=H.paddingTop||0,k.idToDummyNode[$]=Q;var j=k.getGraphManager().add(k.newGraph(),Q),ie=H.getChild();ie.add(Q);for(var ne=0;ne<L[z].length;ne++){var le=L[z][ne];ie.remove(le),j.add(le)}}})},I.prototype.clearCompounds=function(){var k={},L={};this.performDFSOnCompounds();for(var R=0;R<this.compoundOrder.length;R++)L[this.compoundOrder[R].id]=this.compoundOrder[R],k[this.compoundOrder[R].id]=[].concat(this.compoundOrder[R].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[R].getChild()),this.compoundOrder[R].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(k,L)},I.prototype.clearZeroDegreeMembers=function(){var k=this,L=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(R){var O=k.idToDummyNode[R];if(L[R]=k.tileNodes(k.memberGroups[R],O.paddingLeft+O.paddingRight),O.rect.width=L[R].width,O.rect.height=L[R].height,O.setCenter(L[R].centerX,L[R].centerY),O.labelMarginLeft=0,O.labelMarginTop=0,m.NODE_DIMENSIONS_INCLUDE_LABELS){var M=O.rect.width,B=O.rect.height;O.labelWidth&&(O.labelPosHorizontal=="left"?(O.rect.x-=O.labelWidth,O.setWidth(M+O.labelWidth),O.labelMarginLeft=O.labelWidth):O.labelPosHorizontal=="center"&&O.labelWidth>M?(O.rect.x-=(O.labelWidth-M)/2,O.setWidth(O.labelWidth),O.labelMarginLeft=(O.labelWidth-M)/2):O.labelPosHorizontal=="right"&&O.setWidth(M+O.labelWidth)),O.labelHeight&&(O.labelPosVertical=="top"?(O.rect.y-=O.labelHeight,O.setHeight(B+O.labelHeight),O.labelMarginTop=O.labelHeight):O.labelPosVertical=="center"&&O.labelHeight>B?(O.rect.y-=(O.labelHeight-B)/2,O.setHeight(O.labelHeight),O.labelMarginTop=(O.labelHeight-B)/2):O.labelPosVertical=="bottom"&&O.setHeight(B+O.labelHeight))}})},I.prototype.repopulateCompounds=function(){for(var k=this.compoundOrder.length-1;k>=0;k--){var L=this.compoundOrder[k],R=L.id,O=L.paddingLeft,M=L.paddingTop,B=L.labelMarginLeft,F=L.labelMarginTop;this.adjustLocations(this.tiledMemberPack[R],L.rect.x,L.rect.y,O,M,B,F)}},I.prototype.repopulateZeroDegreeMembers=function(){var k=this,L=this.tiledZeroDegreePack;Object.keys(L).forEach(function(R){var O=k.idToDummyNode[R],M=O.paddingLeft,B=O.paddingTop,F=O.labelMarginLeft,P=O.labelMarginTop;k.adjustLocations(L[R],O.rect.x,O.rect.y,M,B,F,P)})},I.prototype.getToBeTiled=function(k){var L=k.id;if(this.toBeTiled[L]!=null)return this.toBeTiled[L];var R=k.getChild();if(R==null)return this.toBeTiled[L]=!1,!1;for(var O=R.getNodes(),M=0;M<O.length;M++){var B=O[M];if(this.getNodeDegree(B)>0)return this.toBeTiled[L]=!1,!1;if(B.getChild()==null){this.toBeTiled[B.id]=!1;continue}if(!this.getToBeTiled(B))return this.toBeTiled[L]=!1,!1}return this.toBeTiled[L]=!0,!0},I.prototype.getNodeDegree=function(k){for(var L=k.id,R=k.getEdges(),O=0,M=0;M<R.length;M++){var B=R[M];B.getSource().id!==B.getTarget().id&&(O=O+1)}return O},I.prototype.getNodeDegreeWithChildren=function(k){var L=this.getNodeDegree(k);if(k.getChild()==null)return L;for(var R=k.getChild().getNodes(),O=0;O<R.length;O++){var M=R[O];L+=this.getNodeDegreeWithChildren(M)}return L},I.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},I.prototype.fillCompexOrderByDFS=function(k){for(var L=0;L<k.length;L++){var R=k[L];R.getChild()!=null&&this.fillCompexOrderByDFS(R.getChild().getNodes()),this.getToBeTiled(R)&&this.compoundOrder.push(R)}},I.prototype.adjustLocations=function(k,L,R,O,M,B,F){L+=O+B,R+=M+F;for(var P=L,z=0;z<k.rows.length;z++){var $=k.rows[z];L=P;for(var H=0,Q=0;Q<$.length;Q++){var j=$[Q];j.rect.x=L,j.rect.y=R,L+=j.rect.width+k.horizontalPadding,j.rect.height>H&&(H=j.rect.height)}R+=H+k.verticalPadding}},I.prototype.tileCompoundMembers=function(k,L){var R=this;this.tiledMemberPack=[],Object.keys(k).forEach(function(O){var M=L[O];if(R.tiledMemberPack[O]=R.tileNodes(k[O],M.paddingLeft+M.paddingRight),M.rect.width=R.tiledMemberPack[O].width,M.rect.height=R.tiledMemberPack[O].height,M.setCenter(R.tiledMemberPack[O].centerX,R.tiledMemberPack[O].centerY),M.labelMarginLeft=0,M.labelMarginTop=0,m.NODE_DIMENSIONS_INCLUDE_LABELS){var B=M.rect.width,F=M.rect.height;M.labelWidth&&(M.labelPosHorizontal=="left"?(M.rect.x-=M.labelWidth,M.setWidth(B+M.labelWidth),M.labelMarginLeft=M.labelWidth):M.labelPosHorizontal=="center"&&M.labelWidth>B?(M.rect.x-=(M.labelWidth-B)/2,M.setWidth(M.labelWidth),M.labelMarginLeft=(M.labelWidth-B)/2):M.labelPosHorizontal=="right"&&M.setWidth(B+M.labelWidth)),M.labelHeight&&(M.labelPosVertical=="top"?(M.rect.y-=M.labelHeight,M.setHeight(F+M.labelHeight),M.labelMarginTop=M.labelHeight):M.labelPosVertical=="center"&&M.labelHeight>F?(M.rect.y-=(M.labelHeight-F)/2,M.setHeight(M.labelHeight),M.labelMarginTop=(M.labelHeight-F)/2):M.labelPosVertical=="bottom"&&M.setHeight(F+M.labelHeight))}})},I.prototype.tileNodes=function(k,L){var R=this.tileNodesByFavoringDim(k,L,!0),O=this.tileNodesByFavoringDim(k,L,!1),M=this.getOrgRatio(R),B=this.getOrgRatio(O),F;return B<M?F=O:F=R,F},I.prototype.getOrgRatio=function(k){var L=k.width,R=k.height,O=L/R;return O<1&&(O=1/O),O},I.prototype.calcIdealRowWidth=function(k,L){var R=m.TILING_PADDING_VERTICAL,O=m.TILING_PADDING_HORIZONTAL,M=k.length,B=0,F=0,P=0;k.forEach(function(ne){B+=ne.getWidth(),F+=ne.getHeight(),ne.getWidth()>P&&(P=ne.getWidth())});var z=B/M,$=F/M,H=Math.pow(R-O,2)+4*(z+O)*($+R)*M,Q=(O-R+Math.sqrt(H))/(2*(z+O)),j;L?(j=Math.ceil(Q),j==Q&&j++):j=Math.floor(Q);var ie=j*(z+O)-O;return P>ie&&(ie=P),ie+=O*2,ie},I.prototype.tileNodesByFavoringDim=function(k,L,R){var O=m.TILING_PADDING_VERTICAL,M=m.TILING_PADDING_HORIZONTAL,B=m.TILING_COMPARE_BY,F={rows:[],rowWidth:[],rowHeight:[],width:0,height:L,verticalPadding:O,horizontalPadding:M,centerX:0,centerY:0};B&&(F.idealRowWidth=this.calcIdealRowWidth(k,R));var P=o(function(le){return le.rect.width*le.rect.height},"getNodeArea"),z=o(function(le,he){return P(he)-P(le)},"areaCompareFcn");k.sort(function(ne,le){var he=z;return F.idealRowWidth?(he=B,he(ne.id,le.id)):he(ne,le)});for(var $=0,H=0,Q=0;Q<k.length;Q++){var j=k[Q];$+=j.getCenterX(),H+=j.getCenterY()}F.centerX=$/k.length,F.centerY=H/k.length;for(var Q=0;Q<k.length;Q++){var j=k[Q];if(F.rows.length==0)this.insertNodeToRow(F,j,0,L);else if(this.canAddHorizontal(F,j.rect.width,j.rect.height)){var ie=F.rows.length-1;F.idealRowWidth||(ie=this.getShortestRowIndex(F)),this.insertNodeToRow(F,j,ie,L)}else this.insertNodeToRow(F,j,F.rows.length,L);this.shiftToLastRow(F)}return F},I.prototype.insertNodeToRow=function(k,L,R,O){var M=O;if(R==k.rows.length){var B=[];k.rows.push(B),k.rowWidth.push(M),k.rowHeight.push(0)}var F=k.rowWidth[R]+L.rect.width;k.rows[R].length>0&&(F+=k.horizontalPadding),k.rowWidth[R]=F,k.width<F&&(k.width=F);var P=L.rect.height;R>0&&(P+=k.verticalPadding);var z=0;P>k.rowHeight[R]&&(z=k.rowHeight[R],k.rowHeight[R]=P,z=k.rowHeight[R]-z),k.height+=z,k.rows[R].push(L)},I.prototype.getShortestRowIndex=function(k){for(var L=-1,R=Number.MAX_VALUE,O=0;O<k.rows.length;O++)k.rowWidth[O]<R&&(L=O,R=k.rowWidth[O]);return L},I.prototype.getLongestRowIndex=function(k){for(var L=-1,R=Number.MIN_VALUE,O=0;O<k.rows.length;O++)k.rowWidth[O]>R&&(L=O,R=k.rowWidth[O]);return L},I.prototype.canAddHorizontal=function(k,L,R){if(k.idealRowWidth){var O=k.rows.length-1,M=k.rowWidth[O];return M+L+k.horizontalPadding<=k.idealRowWidth}var B=this.getShortestRowIndex(k);if(B<0)return!0;var F=k.rowWidth[B];if(F+k.horizontalPadding+L<=k.width)return!0;var P=0;k.rowHeight[B]<R&&B>0&&(P=R+k.verticalPadding-k.rowHeight[B]);var z;k.width-F>=L+k.horizontalPadding?z=(k.height+P)/(F+L+k.horizontalPadding):z=(k.height+P)/k.width,P=R+k.verticalPadding;var $;return k.width<L?$=(k.height+P)/L:$=(k.height+P)/k.width,$<1&&($=1/$),z<1&&(z=1/z),z<$},I.prototype.shiftToLastRow=function(k){var L=this.getLongestRowIndex(k),R=k.rowWidth.length-1,O=k.rows[L],M=O[O.length-1],B=M.width+k.horizontalPadding;if(k.width-k.rowWidth[R]>B&&L!=R){O.splice(-1,1),k.rows[R].push(M),k.rowWidth[L]=k.rowWidth[L]-B,k.rowWidth[R]=k.rowWidth[R]+B,k.width=k.rowWidth[instance.getLongestRowIndex(k)];for(var F=Number.MIN_VALUE,P=0;P<O.length;P++)O[P].height>F&&(F=O[P].height);L>0&&(F+=k.verticalPadding);var z=k.rowHeight[L]+k.rowHeight[R];k.rowHeight[L]=F,k.rowHeight[R]<M.height+k.verticalPadding&&(k.rowHeight[R]=M.height+k.verticalPadding);var $=k.rowHeight[L]+k.rowHeight[R];k.height+=$-z,this.shiftToLastRow(k)}},I.prototype.tilingPreLayout=function(){m.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},I.prototype.tilingPostLayout=function(){m.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},I.prototype.reduceTrees=function(){for(var k=[],L=!0,R;L;){var O=this.graphManager.getAllNodes(),M=[];L=!1;for(var B=0;B<O.length;B++)if(R=O[B],R.getEdges().length==1&&!R.getEdges()[0].isInterGraph&&R.getChild()==null){if(m.PURE_INCREMENTAL){var F=R.getEdges()[0].getOtherEnd(R),P=new w(R.getCenterX()-F.getCenterX(),R.getCenterY()-F.getCenterY());M.push([R,R.getEdges()[0],R.getOwner(),P])}else M.push([R,R.getEdges()[0],R.getOwner()]);L=!0}if(L==!0){for(var z=[],$=0;$<M.length;$++)M[$][0].getEdges().length==1&&(z.push(M[$]),M[$][0].getOwner().remove(M[$][0]));k.push(z),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=k},I.prototype.growTree=function(k){for(var L=k.length,R=k[L-1],O,M=0;M<R.length;M++)O=R[M],this.findPlaceforPrunedNode(O),O[2].add(O[0]),O[2].add(O[1],O[1].source,O[1].target);k.splice(k.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},I.prototype.findPlaceforPrunedNode=function(k){var L,R,O=k[0];if(O==k[1].source?R=k[1].target:R=k[1].source,m.PURE_INCREMENTAL)O.setCenter(R.getCenterX()+k[3].getWidth(),R.getCenterY()+k[3].getHeight());else{var M=R.startX,B=R.finishX,F=R.startY,P=R.finishY,z=0,$=0,H=0,Q=0,j=[z,H,$,Q];if(F>0)for(var ie=M;ie<=B;ie++)j[0]+=this.grid[ie][F-1].length+this.grid[ie][F].length-1;if(B<this.grid.length-1)for(var ie=F;ie<=P;ie++)j[1]+=this.grid[B+1][ie].length+this.grid[B][ie].length-1;if(P<this.grid[0].length-1)for(var ie=M;ie<=B;ie++)j[2]+=this.grid[ie][P+1].length+this.grid[ie][P].length-1;if(M>0)for(var ie=F;ie<=P;ie++)j[3]+=this.grid[M-1][ie].length+this.grid[M][ie].length-1;for(var ne=T.MAX_VALUE,le,he,K=0;K<j.length;K++)j[K]<ne?(ne=j[K],le=1,he=K):j[K]==ne&&le++;if(le==3&&ne==0)j[0]==0&&j[1]==0&&j[2]==0?L=1:j[0]==0&&j[1]==0&&j[3]==0?L=0:j[0]==0&&j[2]==0&&j[3]==0?L=3:j[1]==0&&j[2]==0&&j[3]==0&&(L=2);else if(le==2&&ne==0){var X=Math.floor(Math.random()*2);j[0]==0&&j[1]==0?X==0?L=0:L=1:j[0]==0&&j[2]==0?X==0?L=0:L=2:j[0]==0&&j[3]==0?X==0?L=0:L=3:j[1]==0&&j[2]==0?X==0?L=1:L=2:j[1]==0&&j[3]==0?X==0?L=1:L=3:X==0?L=2:L=3}else if(le==4&&ne==0){var X=Math.floor(Math.random()*4);L=X}else L=he;L==0?O.setCenter(R.getCenterX(),R.getCenterY()-R.getHeight()/2-y.DEFAULT_EDGE_LENGTH-O.getHeight()/2):L==1?O.setCenter(R.getCenterX()+R.getWidth()/2+y.DEFAULT_EDGE_LENGTH+O.getWidth()/2,R.getCenterY()):L==2?O.setCenter(R.getCenterX(),R.getCenterY()+R.getHeight()/2+y.DEFAULT_EDGE_LENGTH+O.getHeight()/2):O.setCenter(R.getCenterX()-R.getWidth()/2-y.DEFAULT_EDGE_LENGTH-O.getWidth()/2,R.getCenterY())}},a.exports=I},991:(a,s,l)=>{var u=l(551).FDLayoutNode,h=l(551).IMath;function f(p,m,g,y){u.call(this,p,m,g,y)}o(f,"CoSENode"),f.prototype=Object.create(u.prototype);for(var d in u)f[d]=u[d];f.prototype.calculateDisplacement=function(){var p=this.graphManager.getLayout();this.getChild()!=null&&this.fixedNodeWeight?(this.displacementX+=p.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=p.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=p.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=p.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>p.coolingFactor*p.maxNodeDisplacement&&(this.displacementX=p.coolingFactor*p.maxNodeDisplacement*h.sign(this.displacementX)),Math.abs(this.displacementY)>p.coolingFactor*p.maxNodeDisplacement&&(this.displacementY=p.coolingFactor*p.maxNodeDisplacement*h.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},f.prototype.propogateDisplacementToChildren=function(p,m){for(var g=this.getChild().getNodes(),y,v=0;v<g.length;v++)y=g[v],y.getChild()==null?(y.displacementX+=p,y.displacementY+=m):y.propogateDisplacementToChildren(p,m)},f.prototype.move=function(){var p=this.graphManager.getLayout();(this.child==null||this.child.getNodes().length==0)&&(this.moveBy(this.displacementX,this.displacementY),p.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY)),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},f.prototype.setPred1=function(p){this.pred1=p},f.prototype.getPred1=function(){return pred1},f.prototype.getPred2=function(){return pred2},f.prototype.setNext=function(p){this.next=p},f.prototype.getNext=function(){return next},f.prototype.setProcessed=function(p){this.processed=p},f.prototype.isProcessed=function(){return processed},a.exports=f},902:(a,s,l)=>{function u(g){if(Array.isArray(g)){for(var y=0,v=Array(g.length);y<g.length;y++)v[y]=g[y];return v}else return Array.from(g)}o(u,"_toConsumableArray");var h=l(806),f=l(551).LinkedList,d=l(551).Matrix,p=l(551).SVD;function m(){}o(m,"ConstraintHandler"),m.handleConstraints=function(g){var y={};y.fixedNodeConstraint=g.constraints.fixedNodeConstraint,y.alignmentConstraint=g.constraints.alignmentConstraint,y.relativePlacementConstraint=g.constraints.relativePlacementConstraint;for(var v=new Map,x=new Map,b=[],w=[],C=g.getAllNodes(),T=0,E=0;E<C.length;E++){var A=C[E];A.getChild()==null&&(x.set(A.id,T++),b.push(A.getCenterX()),w.push(A.getCenterY()),v.set(A.id,A))}y.relativePlacementConstraint&&y.relativePlacementConstraint.forEach(function(oe){!oe.gap&&oe.gap!=0&&(oe.left?oe.gap=h.DEFAULT_EDGE_LENGTH+v.get(oe.left).getWidth()/2+v.get(oe.right).getWidth()/2:oe.gap=h.DEFAULT_EDGE_LENGTH+v.get(oe.top).getHeight()/2+v.get(oe.bottom).getHeight()/2)});var S=o(function(V,xe){return{x:V.x-xe.x,y:V.y-xe.y}},"calculatePositionDiff"),_=o(function(V){var xe=0,q=0;return V.forEach(function(pe){xe+=b[x.get(pe)],q+=w[x.get(pe)]}),{x:xe/V.size,y:q/V.size}},"calculateAvgPosition"),I=o(function(V,xe,q,pe,ve){function Pe(st,Ue){var ct=new Set(st),We=!0,ot=!1,Yt=void 0;try{for(var bt=Ue[Symbol.iterator](),Mt;!(We=(Mt=bt.next()).done);We=!0){var xt=Mt.value;ct.add(xt)}}catch(ut){ot=!0,Yt=ut}finally{try{!We&&bt.return&&bt.return()}finally{if(ot)throw Yt}}return ct}o(Pe,"setUnion");var _e=new Map;V.forEach(function(st,Ue){_e.set(Ue,0)}),V.forEach(function(st,Ue){st.forEach(function(ct){_e.set(ct.id,_e.get(ct.id)+1)})});var we=new Map,Ve=new Map,De=new f;_e.forEach(function(st,Ue){st==0?(De.push(Ue),q||(xe=="horizontal"?we.set(Ue,x.has(Ue)?b[x.get(Ue)]:pe.get(Ue)):we.set(Ue,x.has(Ue)?w[x.get(Ue)]:pe.get(Ue)))):we.set(Ue,Number.NEGATIVE_INFINITY),q&&Ve.set(Ue,new Set([Ue]))}),q&&ve.forEach(function(st){var Ue=[];if(st.forEach(function(ot){q.has(ot)&&Ue.push(ot)}),Ue.length>0){var ct=0;Ue.forEach(function(ot){xe=="horizontal"?(we.set(ot,x.has(ot)?b[x.get(ot)]:pe.get(ot)),ct+=we.get(ot)):(we.set(ot,x.has(ot)?w[x.get(ot)]:pe.get(ot)),ct+=we.get(ot))}),ct=ct/Ue.length,st.forEach(function(ot){q.has(ot)||we.set(ot,ct)})}else{var We=0;st.forEach(function(ot){xe=="horizontal"?We+=x.has(ot)?b[x.get(ot)]:pe.get(ot):We+=x.has(ot)?w[x.get(ot)]:pe.get(ot)}),We=We/st.length,st.forEach(function(ot){we.set(ot,We)})}});for(var qe=o(function(){var Ue=De.shift(),ct=V.get(Ue);ct.forEach(function(We){if(we.get(We.id)<we.get(Ue)+We.gap)if(q&&q.has(We.id)){var ot=void 0;if(xe=="horizontal"?ot=x.has(We.id)?b[x.get(We.id)]:pe.get(We.id):ot=x.has(We.id)?w[x.get(We.id)]:pe.get(We.id),we.set(We.id,ot),ot<we.get(Ue)+We.gap){var Yt=we.get(Ue)+We.gap-ot;Ve.get(Ue).forEach(function(bt){we.set(bt,we.get(bt)-Yt)})}}else we.set(We.id,we.get(Ue)+We.gap);_e.set(We.id,_e.get(We.id)-1),_e.get(We.id)==0&&De.push(We.id),q&&Ve.set(We.id,Pe(Ve.get(Ue),Ve.get(We.id)))})},"_loop");De.length!=0;)qe();if(q){var at=new Set;V.forEach(function(st,Ue){st.length==0&&at.add(Ue)});var Rt=[];Ve.forEach(function(st,Ue){if(at.has(Ue)){var ct=!1,We=!0,ot=!1,Yt=void 0;try{for(var bt=st[Symbol.iterator](),Mt;!(We=(Mt=bt.next()).done);We=!0){var xt=Mt.value;q.has(xt)&&(ct=!0)}}catch(ft){ot=!0,Yt=ft}finally{try{!We&&bt.return&&bt.return()}finally{if(ot)throw Yt}}if(!ct){var ut=!1,Et=void 0;Rt.forEach(function(ft,yt){ft.has([].concat(u(st))[0])&&(ut=!0,Et=yt)}),ut?st.forEach(function(ft){Rt[Et].add(ft)}):Rt.push(new Set(st))}}}),Rt.forEach(function(st,Ue){var ct=Number.POSITIVE_INFINITY,We=Number.POSITIVE_INFINITY,ot=Number.NEGATIVE_INFINITY,Yt=Number.NEGATIVE_INFINITY,bt=!0,Mt=!1,xt=void 0;try{for(var ut=st[Symbol.iterator](),Et;!(bt=(Et=ut.next()).done);bt=!0){var ft=Et.value,yt=void 0;xe=="horizontal"?yt=x.has(ft)?b[x.get(ft)]:pe.get(ft):yt=x.has(ft)?w[x.get(ft)]:pe.get(ft);var nt=we.get(ft);yt<ct&&(ct=yt),yt>ot&&(ot=yt),nt<We&&(We=nt),nt>Yt&&(Yt=nt)}}catch(At){Mt=!0,xt=At}finally{try{!bt&&ut.return&&ut.return()}finally{if(Mt)throw xt}}var dn=(ct+ot)/2-(We+Yt)/2,Tt=!0,On=!1,tn=void 0;try{for(var _r=st[Symbol.iterator](),Dr;!(Tt=(Dr=_r.next()).done);Tt=!0){var Pn=Dr.value;we.set(Pn,we.get(Pn)+dn)}}catch(At){On=!0,tn=At}finally{try{!Tt&&_r.return&&_r.return()}finally{if(On)throw tn}}})}return we},"findAppropriatePositionForRelativePlacement"),D=o(function(V){var xe=0,q=0,pe=0,ve=0;if(V.forEach(function(Ve){Ve.left?b[x.get(Ve.left)]-b[x.get(Ve.right)]>=0?xe++:q++:w[x.get(Ve.top)]-w[x.get(Ve.bottom)]>=0?pe++:ve++}),xe>q&&pe>ve)for(var Pe=0;Pe<x.size;Pe++)b[Pe]=-1*b[Pe],w[Pe]=-1*w[Pe];else if(xe>q)for(var _e=0;_e<x.size;_e++)b[_e]=-1*b[_e];else if(pe>ve)for(var we=0;we<x.size;we++)w[we]=-1*w[we]},"applyReflectionForRelativePlacement"),k=o(function(V){var xe=[],q=new f,pe=new Set,ve=0;return V.forEach(function(Pe,_e){if(!pe.has(_e)){xe[ve]=[];var we=_e;for(q.push(we),pe.add(we),xe[ve].push(we);q.length!=0;){we=q.shift();var Ve=V.get(we);Ve.forEach(function(De){pe.has(De.id)||(q.push(De.id),pe.add(De.id),xe[ve].push(De.id))})}ve++}}),xe},"findComponents"),L=o(function(V){var xe=new Map;return V.forEach(function(q,pe){xe.set(pe,[])}),V.forEach(function(q,pe){q.forEach(function(ve){xe.get(pe).push(ve),xe.get(ve.id).push({id:pe,gap:ve.gap,direction:ve.direction})})}),xe},"dagToUndirected"),R=o(function(V){var xe=new Map;return V.forEach(function(q,pe){xe.set(pe,[])}),V.forEach(function(q,pe){q.forEach(function(ve){xe.get(ve.id).push({id:pe,gap:ve.gap,direction:ve.direction})})}),xe},"dagToReversed"),O=[],M=[],B=!1,F=!1,P=new Set,z=new Map,$=new Map,H=[];if(y.fixedNodeConstraint&&y.fixedNodeConstraint.forEach(function(oe){P.add(oe.nodeId)}),y.relativePlacementConstraint&&(y.relativePlacementConstraint.forEach(function(oe){oe.left?(z.has(oe.left)?z.get(oe.left).push({id:oe.right,gap:oe.gap,direction:"horizontal"}):z.set(oe.left,[{id:oe.right,gap:oe.gap,direction:"horizontal"}]),z.has(oe.right)||z.set(oe.right,[])):(z.has(oe.top)?z.get(oe.top).push({id:oe.bottom,gap:oe.gap,direction:"vertical"}):z.set(oe.top,[{id:oe.bottom,gap:oe.gap,direction:"vertical"}]),z.has(oe.bottom)||z.set(oe.bottom,[]))}),$=L(z),H=k($)),h.TRANSFORM_ON_CONSTRAINT_HANDLING){if(y.fixedNodeConstraint&&y.fixedNodeConstraint.length>1)y.fixedNodeConstraint.forEach(function(oe,V){O[V]=[oe.position.x,oe.position.y],M[V]=[b[x.get(oe.nodeId)],w[x.get(oe.nodeId)]]}),B=!0;else if(y.alignmentConstraint)(function(){var oe=0;if(y.alignmentConstraint.vertical){for(var V=y.alignmentConstraint.vertical,xe=o(function(we){var Ve=new Set;V[we].forEach(function(at){Ve.add(at)});var De=new Set([].concat(u(Ve)).filter(function(at){return P.has(at)})),qe=void 0;De.size>0?qe=b[x.get(De.values().next().value)]:qe=_(Ve).x,V[we].forEach(function(at){O[oe]=[qe,w[x.get(at)]],M[oe]=[b[x.get(at)],w[x.get(at)]],oe++})},"_loop2"),q=0;q<V.length;q++)xe(q);B=!0}if(y.alignmentConstraint.horizontal){for(var pe=y.alignmentConstraint.horizontal,ve=o(function(we){var Ve=new Set;pe[we].forEach(function(at){Ve.add(at)});var De=new Set([].concat(u(Ve)).filter(function(at){return P.has(at)})),qe=void 0;De.size>0?qe=b[x.get(De.values().next().value)]:qe=_(Ve).y,pe[we].forEach(function(at){O[oe]=[b[x.get(at)],qe],M[oe]=[b[x.get(at)],w[x.get(at)]],oe++})},"_loop3"),Pe=0;Pe<pe.length;Pe++)ve(Pe);B=!0}y.relativePlacementConstraint&&(F=!0)})();else if(y.relativePlacementConstraint){for(var Q=0,j=0,ie=0;ie<H.length;ie++)H[ie].length>Q&&(Q=H[ie].length,j=ie);if(Q<$.size/2)D(y.relativePlacementConstraint),B=!1,F=!1;else{var ne=new Map,le=new Map,he=[];H[j].forEach(function(oe){z.get(oe).forEach(function(V){V.direction=="horizontal"?(ne.has(oe)?ne.get(oe).push(V):ne.set(oe,[V]),ne.has(V.id)||ne.set(V.id,[]),he.push({left:oe,right:V.id})):(le.has(oe)?le.get(oe).push(V):le.set(oe,[V]),le.has(V.id)||le.set(V.id,[]),he.push({top:oe,bottom:V.id}))})}),D(he),F=!1;var K=I(ne,"horizontal"),X=I(le,"vertical");H[j].forEach(function(oe,V){M[V]=[b[x.get(oe)],w[x.get(oe)]],O[V]=[],K.has(oe)?O[V][0]=K.get(oe):O[V][0]=b[x.get(oe)],X.has(oe)?O[V][1]=X.get(oe):O[V][1]=w[x.get(oe)]}),B=!0}}if(B){for(var te=void 0,J=d.transpose(O),se=d.transpose(M),ue=0;ue<J.length;ue++)J[ue]=d.multGamma(J[ue]),se[ue]=d.multGamma(se[ue]);var Z=d.multMat(J,d.transpose(se)),Se=p.svd(Z);te=d.multMat(Se.V,d.transpose(Se.U));for(var ce=0;ce<x.size;ce++){var ae=[b[ce],w[ce]],Oe=[te[0][0],te[1][0]],ge=[te[0][1],te[1][1]];b[ce]=d.dotProduct(ae,Oe),w[ce]=d.dotProduct(ae,ge)}F&&D(y.relativePlacementConstraint)}}if(h.ENFORCE_CONSTRAINTS){if(y.fixedNodeConstraint&&y.fixedNodeConstraint.length>0){var ze={x:0,y:0};y.fixedNodeConstraint.forEach(function(oe,V){var xe={x:b[x.get(oe.nodeId)],y:w[x.get(oe.nodeId)]},q=oe.position,pe=S(q,xe);ze.x+=pe.x,ze.y+=pe.y}),ze.x/=y.fixedNodeConstraint.length,ze.y/=y.fixedNodeConstraint.length,b.forEach(function(oe,V){b[V]+=ze.x}),w.forEach(function(oe,V){w[V]+=ze.y}),y.fixedNodeConstraint.forEach(function(oe){b[x.get(oe.nodeId)]=oe.position.x,w[x.get(oe.nodeId)]=oe.position.y})}if(y.alignmentConstraint){if(y.alignmentConstraint.vertical)for(var He=y.alignmentConstraint.vertical,$e=o(function(V){var xe=new Set;He[V].forEach(function(ve){xe.add(ve)});var q=new Set([].concat(u(xe)).filter(function(ve){return P.has(ve)})),pe=void 0;q.size>0?pe=b[x.get(q.values().next().value)]:pe=_(xe).x,xe.forEach(function(ve){P.has(ve)||(b[x.get(ve)]=pe)})},"_loop4"),Re=0;Re<He.length;Re++)$e(Re);if(y.alignmentConstraint.horizontal)for(var Ie=y.alignmentConstraint.horizontal,be=o(function(V){var xe=new Set;Ie[V].forEach(function(ve){xe.add(ve)});var q=new Set([].concat(u(xe)).filter(function(ve){return P.has(ve)})),pe=void 0;q.size>0?pe=w[x.get(q.values().next().value)]:pe=_(xe).y,xe.forEach(function(ve){P.has(ve)||(w[x.get(ve)]=pe)})},"_loop5"),W=0;W<Ie.length;W++)be(W)}y.relativePlacementConstraint&&function(){var oe=new Map,V=new Map,xe=new Map,q=new Map,pe=new Map,ve=new Map,Pe=new Set,_e=new Set;if(P.forEach(function(Hr){Pe.add(Hr),_e.add(Hr)}),y.alignmentConstraint){if(y.alignmentConstraint.vertical)for(var we=y.alignmentConstraint.vertical,Ve=o(function(et){xe.set("dummy"+et,[]),we[et].forEach(function(mt){oe.set(mt,"dummy"+et),xe.get("dummy"+et).push(mt),P.has(mt)&&Pe.add("dummy"+et)}),pe.set("dummy"+et,b[x.get(we[et][0])])},"_loop6"),De=0;De<we.length;De++)Ve(De);if(y.alignmentConstraint.horizontal)for(var qe=y.alignmentConstraint.horizontal,at=o(function(et){q.set("dummy"+et,[]),qe[et].forEach(function(mt){V.set(mt,"dummy"+et),q.get("dummy"+et).push(mt),P.has(mt)&&_e.add("dummy"+et)}),ve.set("dummy"+et,w[x.get(qe[et][0])])},"_loop7"),Rt=0;Rt<qe.length;Rt++)at(Rt)}var st=new Map,Ue=new Map,ct=o(function(et){z.get(et).forEach(function(mt){var Kt=void 0,lt=void 0;mt.direction=="horizontal"?(Kt=oe.get(et)?oe.get(et):et,oe.get(mt.id)?lt={id:oe.get(mt.id),gap:mt.gap,direction:mt.direction}:lt=mt,st.has(Kt)?st.get(Kt).push(lt):st.set(Kt,[lt]),st.has(lt.id)||st.set(lt.id,[])):(Kt=V.get(et)?V.get(et):et,V.get(mt.id)?lt={id:V.get(mt.id),gap:mt.gap,direction:mt.direction}:lt=mt,Ue.has(Kt)?Ue.get(Kt).push(lt):Ue.set(Kt,[lt]),Ue.has(lt.id)||Ue.set(lt.id,[]))})},"_loop8"),We=!0,ot=!1,Yt=void 0;try{for(var bt=z.keys()[Symbol.iterator](),Mt;!(We=(Mt=bt.next()).done);We=!0){var xt=Mt.value;ct(xt)}}catch(Hr){ot=!0,Yt=Hr}finally{try{!We&&bt.return&&bt.return()}finally{if(ot)throw Yt}}var ut=L(st),Et=L(Ue),ft=k(ut),yt=k(Et),nt=R(st),dn=R(Ue),Tt=[],On=[];ft.forEach(function(Hr,et){Tt[et]=[],Hr.forEach(function(mt){nt.get(mt).length==0&&Tt[et].push(mt)})}),yt.forEach(function(Hr,et){On[et]=[],Hr.forEach(function(mt){dn.get(mt).length==0&&On[et].push(mt)})});var tn=I(st,"horizontal",Pe,pe,Tt),_r=I(Ue,"vertical",_e,ve,On),Dr=o(function(et){xe.get(et)?xe.get(et).forEach(function(mt){b[x.get(mt)]=tn.get(et)}):b[x.get(et)]=tn.get(et)},"_loop9"),Pn=!0,At=!1,Ce=void 0;try{for(var tt=tn.keys()[Symbol.iterator](),St;!(Pn=(St=tt.next()).done);Pn=!0){var mr=St.value;Dr(mr)}}catch(Hr){At=!0,Ce=Hr}finally{try{!Pn&&tt.return&&tt.return()}finally{if(At)throw Ce}}var rn=o(function(et){q.get(et)?q.get(et).forEach(function(mt){w[x.get(mt)]=_r.get(et)}):w[x.get(et)]=_r.get(et)},"_loop10"),gn=!0,Zr=!1,Ni=void 0;try{for(var Zn=_r.keys()[Symbol.iterator](),Sn;!(gn=(Sn=Zn.next()).done);gn=!0){var mr=Sn.value;rn(mr)}}catch(Hr){Zr=!0,Ni=Hr}finally{try{!gn&&Zn.return&&Zn.return()}finally{if(Zr)throw Ni}}}()}for(var de=0;de<C.length;de++){var re=C[de];re.getChild()==null&&re.setCenter(b[x.get(re.id)],w[x.get(re.id)])}},a.exports=m},551:a=>{a.exports=t}},r={};function n(a){var s=r[a];if(s!==void 0)return s.exports;var l=r[a]={exports:{}};return e[a](l,l.exports,n),l.exports}o(n,"__webpack_require__");var i=n(45);return i})()})});var Pve=Mi((E4,gF)=>{"use strict";o(function(e,r){typeof E4=="object"&&typeof gF=="object"?gF.exports=r(mF()):typeof define=="function"&&define.amd?define(["cose-base"],r):typeof E4=="object"?E4.cytoscapeFcose=r(mF()):e.cytoscapeFcose=r(e.coseBase)},"webpackUniversalModuleDefinition")(E4,function(t){return(()=>{"use strict";var e={658:a=>{a.exports=Object.assign!=null?Object.assign.bind(Object):function(s){for(var l=arguments.length,u=Array(l>1?l-1:0),h=1;h<l;h++)u[h-1]=arguments[h];return u.forEach(function(f){Object.keys(f).forEach(function(d){return s[d]=f[d]})}),s}},548:(a,s,l)=>{var u=function(){function d(p,m){var g=[],y=!0,v=!1,x=void 0;try{for(var b=p[Symbol.iterator](),w;!(y=(w=b.next()).done)&&(g.push(w.value),!(m&&g.length===m));y=!0);}catch(C){v=!0,x=C}finally{try{!y&&b.return&&b.return()}finally{if(v)throw x}}return g}return o(d,"sliceIterator"),function(p,m){if(Array.isArray(p))return p;if(Symbol.iterator in Object(p))return d(p,m);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),h=l(140).layoutBase.LinkedList,f={};f.getTopMostNodes=function(d){for(var p={},m=0;m<d.length;m++)p[d[m].id()]=!0;var g=d.filter(function(y,v){typeof y=="number"&&(y=v);for(var x=y.parent()[0];x!=null;){if(p[x.id()])return!1;x=x.parent()[0]}return!0});return g},f.connectComponents=function(d,p,m,g){var y=new h,v=new Set,x=[],b=void 0,w=void 0,C=void 0,T=!1,E=1,A=[],S=[],_=o(function(){var D=d.collection();S.push(D);var k=m[0],L=d.collection();L.merge(k).merge(k.descendants().intersection(p)),x.push(k),L.forEach(function(M){y.push(M),v.add(M),D.merge(M)});for(var R=o(function(){k=y.shift();var B=d.collection();k.neighborhood().nodes().forEach(function($){p.intersection(k.edgesWith($)).length>0&&B.merge($)});for(var F=0;F<B.length;F++){var P=B[F];if(b=m.intersection(P.union(P.ancestors())),b!=null&&!v.has(b[0])){var z=b.union(b.descendants());z.forEach(function($){y.push($),v.add($),D.merge($),m.has($)&&x.push($)})}}},"_loop2");y.length!=0;)R();if(D.forEach(function(M){p.intersection(M.connectedEdges()).forEach(function(B){D.has(B.source())&&D.has(B.target())&&D.merge(B)})}),x.length==m.length&&(T=!0),!T||T&&E>1){w=x[0],C=w.connectedEdges().length,x.forEach(function(M){M.connectedEdges().length<C&&(C=M.connectedEdges().length,w=M)}),A.push(w.id());var O=d.collection();O.merge(x[0]),x.forEach(function(M){O.merge(M)}),x=[],m=m.difference(O),E++}},"_loop");do _();while(!T);return g&&A.length>0&&g.set("dummy"+(g.size+1),A),S},f.relocateComponent=function(d,p,m){if(!m.fixedNodeConstraint){var g=Number.POSITIVE_INFINITY,y=Number.NEGATIVE_INFINITY,v=Number.POSITIVE_INFINITY,x=Number.NEGATIVE_INFINITY;if(m.quality=="draft"){var b=!0,w=!1,C=void 0;try{for(var T=p.nodeIndexes[Symbol.iterator](),E;!(b=(E=T.next()).done);b=!0){var A=E.value,S=u(A,2),_=S[0],I=S[1],D=m.cy.getElementById(_);if(D){var k=D.boundingBox(),L=p.xCoords[I]-k.w/2,R=p.xCoords[I]+k.w/2,O=p.yCoords[I]-k.h/2,M=p.yCoords[I]+k.h/2;L<g&&(g=L),R>y&&(y=R),O<v&&(v=O),M>x&&(x=M)}}}catch($){w=!0,C=$}finally{try{!b&&T.return&&T.return()}finally{if(w)throw C}}var B=d.x-(y+g)/2,F=d.y-(x+v)/2;p.xCoords=p.xCoords.map(function($){return $+B}),p.yCoords=p.yCoords.map(function($){return $+F})}else{Object.keys(p).forEach(function($){var H=p[$],Q=H.getRect().x,j=H.getRect().x+H.getRect().width,ie=H.getRect().y,ne=H.getRect().y+H.getRect().height;Q<g&&(g=Q),j>y&&(y=j),ie<v&&(v=ie),ne>x&&(x=ne)});var P=d.x-(y+g)/2,z=d.y-(x+v)/2;Object.keys(p).forEach(function($){var H=p[$];H.setCenter(H.getCenterX()+P,H.getCenterY()+z)})}}},f.calcBoundingBox=function(d,p,m,g){for(var y=Number.MAX_SAFE_INTEGER,v=Number.MIN_SAFE_INTEGER,x=Number.MAX_SAFE_INTEGER,b=Number.MIN_SAFE_INTEGER,w=void 0,C=void 0,T=void 0,E=void 0,A=d.descendants().not(":parent"),S=A.length,_=0;_<S;_++){var I=A[_];w=p[g.get(I.id())]-I.width()/2,C=p[g.get(I.id())]+I.width()/2,T=m[g.get(I.id())]-I.height()/2,E=m[g.get(I.id())]+I.height()/2,y>w&&(y=w),v<C&&(v=C),x>T&&(x=T),b<E&&(b=E)}var D={};return D.topLeftX=y,D.topLeftY=x,D.width=v-y,D.height=b-x,D},f.calcParentsWithoutChildren=function(d,p){var m=d.collection();return p.nodes(":parent").forEach(function(g){var y=!1;g.children().forEach(function(v){v.css("display")!="none"&&(y=!0)}),y||m.merge(g)}),m},a.exports=f},816:(a,s,l)=>{var u=l(548),h=l(140).CoSELayout,f=l(140).CoSENode,d=l(140).layoutBase.PointD,p=l(140).layoutBase.DimensionD,m=l(140).layoutBase.LayoutConstants,g=l(140).layoutBase.FDLayoutConstants,y=l(140).CoSEConstants,v=o(function(b,w){var C=b.cy,T=b.eles,E=T.nodes(),A=T.edges(),S=void 0,_=void 0,I=void 0,D={};b.randomize&&(S=w.nodeIndexes,_=w.xCoords,I=w.yCoords);var k=o(function($){return typeof $=="function"},"isFn"),L=o(function($,H){return k($)?$(H):$},"optFn"),R=u.calcParentsWithoutChildren(C,T),O=o(function z($,H,Q,j){for(var ie=H.length,ne=0;ne<ie;ne++){var le=H[ne],he=null;le.intersection(R).length==0&&(he=le.children());var K=void 0,X=le.layoutDimensions({nodeDimensionsIncludeLabels:j.nodeDimensionsIncludeLabels});if(le.outerWidth()!=null&&le.outerHeight()!=null)if(j.randomize)if(!le.isParent())K=$.add(new f(Q.graphManager,new d(_[S.get(le.id())]-X.w/2,I[S.get(le.id())]-X.h/2),new p(parseFloat(X.w),parseFloat(X.h))));else{var te=u.calcBoundingBox(le,_,I,S);le.intersection(R).length==0?K=$.add(new f(Q.graphManager,new d(te.topLeftX,te.topLeftY),new p(te.width,te.height))):K=$.add(new f(Q.graphManager,new d(te.topLeftX,te.topLeftY),new p(parseFloat(X.w),parseFloat(X.h))))}else K=$.add(new f(Q.graphManager,new d(le.position("x")-X.w/2,le.position("y")-X.h/2),new p(parseFloat(X.w),parseFloat(X.h))));else K=$.add(new f(this.graphManager));if(K.id=le.data("id"),K.nodeRepulsion=L(j.nodeRepulsion,le),K.paddingLeft=parseInt(le.css("padding")),K.paddingTop=parseInt(le.css("padding")),K.paddingRight=parseInt(le.css("padding")),K.paddingBottom=parseInt(le.css("padding")),j.nodeDimensionsIncludeLabels&&(K.labelWidth=le.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).w,K.labelHeight=le.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).h,K.labelPosVertical=le.css("text-valign"),K.labelPosHorizontal=le.css("text-halign")),D[le.data("id")]=K,isNaN(K.rect.x)&&(K.rect.x=0),isNaN(K.rect.y)&&(K.rect.y=0),he!=null&&he.length>0){var J=void 0;J=Q.getGraphManager().add(Q.newGraph(),K),z(J,he,Q,j)}}},"processChildrenList"),M=o(function($,H,Q){for(var j=0,ie=0,ne=0;ne<Q.length;ne++){var le=Q[ne],he=D[le.data("source")],K=D[le.data("target")];if(he&&K&&he!==K&&he.getEdgesBetween(K).length==0){var X=H.add($.newEdge(),he,K);X.id=le.id(),X.idealLength=L(b.idealEdgeLength,le),X.edgeElasticity=L(b.edgeElasticity,le),j+=X.idealLength,ie++}}b.idealEdgeLength!=null&&(ie>0?y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=j/ie:k(b.idealEdgeLength)?y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=50:y.DEFAULT_EDGE_LENGTH=g.DEFAULT_EDGE_LENGTH=b.idealEdgeLength,y.MIN_REPULSION_DIST=g.MIN_REPULSION_DIST=g.DEFAULT_EDGE_LENGTH/10,y.DEFAULT_RADIAL_SEPARATION=g.DEFAULT_EDGE_LENGTH)},"processEdges"),B=o(function($,H){H.fixedNodeConstraint&&($.constraints.fixedNodeConstraint=H.fixedNodeConstraint),H.alignmentConstraint&&($.constraints.alignmentConstraint=H.alignmentConstraint),H.relativePlacementConstraint&&($.constraints.relativePlacementConstraint=H.relativePlacementConstraint)},"processConstraints");b.nestingFactor!=null&&(y.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=g.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=b.nestingFactor),b.gravity!=null&&(y.DEFAULT_GRAVITY_STRENGTH=g.DEFAULT_GRAVITY_STRENGTH=b.gravity),b.numIter!=null&&(y.MAX_ITERATIONS=g.MAX_ITERATIONS=b.numIter),b.gravityRange!=null&&(y.DEFAULT_GRAVITY_RANGE_FACTOR=g.DEFAULT_GRAVITY_RANGE_FACTOR=b.gravityRange),b.gravityCompound!=null&&(y.DEFAULT_COMPOUND_GRAVITY_STRENGTH=g.DEFAULT_COMPOUND_GRAVITY_STRENGTH=b.gravityCompound),b.gravityRangeCompound!=null&&(y.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=g.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=b.gravityRangeCompound),b.initialEnergyOnIncremental!=null&&(y.DEFAULT_COOLING_FACTOR_INCREMENTAL=g.DEFAULT_COOLING_FACTOR_INCREMENTAL=b.initialEnergyOnIncremental),b.tilingCompareBy!=null&&(y.TILING_COMPARE_BY=b.tilingCompareBy),b.quality=="proof"?m.QUALITY=2:m.QUALITY=0,y.NODE_DIMENSIONS_INCLUDE_LABELS=g.NODE_DIMENSIONS_INCLUDE_LABELS=m.NODE_DIMENSIONS_INCLUDE_LABELS=b.nodeDimensionsIncludeLabels,y.DEFAULT_INCREMENTAL=g.DEFAULT_INCREMENTAL=m.DEFAULT_INCREMENTAL=!b.randomize,y.ANIMATE=g.ANIMATE=m.ANIMATE=b.animate,y.TILE=b.tile,y.TILING_PADDING_VERTICAL=typeof b.tilingPaddingVertical=="function"?b.tilingPaddingVertical.call():b.tilingPaddingVertical,y.TILING_PADDING_HORIZONTAL=typeof b.tilingPaddingHorizontal=="function"?b.tilingPaddingHorizontal.call():b.tilingPaddingHorizontal,y.DEFAULT_INCREMENTAL=g.DEFAULT_INCREMENTAL=m.DEFAULT_INCREMENTAL=!0,y.PURE_INCREMENTAL=!b.randomize,m.DEFAULT_UNIFORM_LEAF_NODE_SIZES=b.uniformNodeDimensions,b.step=="transformed"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,y.ENFORCE_CONSTRAINTS=!1,y.APPLY_LAYOUT=!1),b.step=="enforced"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!0,y.APPLY_LAYOUT=!1),b.step=="cose"&&(y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!1,y.APPLY_LAYOUT=!0),b.step=="all"&&(b.randomize?y.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:y.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,y.ENFORCE_CONSTRAINTS=!0,y.APPLY_LAYOUT=!0),b.fixedNodeConstraint||b.alignmentConstraint||b.relativePlacementConstraint?y.TREE_REDUCTION_ON_INCREMENTAL=!1:y.TREE_REDUCTION_ON_INCREMENTAL=!0;var F=new h,P=F.newGraphManager();return O(P.addRoot(),u.getTopMostNodes(E),F,b),M(F,P,A),B(F,b),F.runLayout(),D},"coseLayout");a.exports={coseLayout:v}},212:(a,s,l)=>{var u=function(){function b(w,C){for(var T=0;T<C.length;T++){var E=C[T];E.enumerable=E.enumerable||!1,E.configurable=!0,"value"in E&&(E.writable=!0),Object.defineProperty(w,E.key,E)}}return o(b,"defineProperties"),function(w,C,T){return C&&b(w.prototype,C),T&&b(w,T),w}}();function h(b,w){if(!(b instanceof w))throw new TypeError("Cannot call a class as a function")}o(h,"_classCallCheck");var f=l(658),d=l(548),p=l(657),m=p.spectralLayout,g=l(816),y=g.coseLayout,v=Object.freeze({quality:"default",randomize:!0,animate:!0,animationDuration:1e3,animationEasing:void 0,fit:!0,padding:30,nodeDimensionsIncludeLabels:!1,uniformNodeDimensions:!1,packComponents:!0,step:"all",samplingType:!0,sampleSize:25,nodeSeparation:75,piTol:1e-7,nodeRepulsion:o(function(w){return 4500},"nodeRepulsion"),idealEdgeLength:o(function(w){return 50},"idealEdgeLength"),edgeElasticity:o(function(w){return .45},"edgeElasticity"),nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,tilingCompareBy:void 0,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.3,fixedNodeConstraint:void 0,alignmentConstraint:void 0,relativePlacementConstraint:void 0,ready:o(function(){},"ready"),stop:o(function(){},"stop")}),x=function(){function b(w){h(this,b),this.options=f({},v,w)}return o(b,"Layout"),u(b,[{key:"run",value:o(function(){var C=this,T=this.options,E=T.cy,A=T.eles,S=[],_=void 0,I=void 0,D=[],k=void 0,L=[];T.fixedNodeConstraint&&(!Array.isArray(T.fixedNodeConstraint)||T.fixedNodeConstraint.length==0)&&(T.fixedNodeConstraint=void 0),T.alignmentConstraint&&(T.alignmentConstraint.vertical&&(!Array.isArray(T.alignmentConstraint.vertical)||T.alignmentConstraint.vertical.length==0)&&(T.alignmentConstraint.vertical=void 0),T.alignmentConstraint.horizontal&&(!Array.isArray(T.alignmentConstraint.horizontal)||T.alignmentConstraint.horizontal.length==0)&&(T.alignmentConstraint.horizontal=void 0)),T.relativePlacementConstraint&&(!Array.isArray(T.relativePlacementConstraint)||T.relativePlacementConstraint.length==0)&&(T.relativePlacementConstraint=void 0);var R=T.fixedNodeConstraint||T.alignmentConstraint||T.relativePlacementConstraint;R&&(T.tile=!1,T.packComponents=!1);var O=void 0,M=!1;if(E.layoutUtilities&&T.packComponents&&(O=E.layoutUtilities("get"),O||(O=E.layoutUtilities()),M=!0),A.nodes().length>0)if(M){var P=d.getTopMostNodes(T.eles.nodes());if(k=d.connectComponents(E,T.eles,P),k.forEach(function(ce){var ae=ce.boundingBox();L.push({x:ae.x1+ae.w/2,y:ae.y1+ae.h/2})}),T.randomize&&k.forEach(function(ce){T.eles=ce,S.push(m(T))}),T.quality=="default"||T.quality=="proof"){var z=E.collection();if(T.tile){var $=new Map,H=[],Q=[],j=0,ie={nodeIndexes:$,xCoords:H,yCoords:Q},ne=[];if(k.forEach(function(ce,ae){ce.edges().length==0&&(ce.nodes().forEach(function(Oe,ge){z.merge(ce.nodes()[ge]),Oe.isParent()||(ie.nodeIndexes.set(ce.nodes()[ge].id(),j++),ie.xCoords.push(ce.nodes()[0].position().x),ie.yCoords.push(ce.nodes()[0].position().y))}),ne.push(ae))}),z.length>1){var le=z.boundingBox();L.push({x:le.x1+le.w/2,y:le.y1+le.h/2}),k.push(z),S.push(ie);for(var he=ne.length-1;he>=0;he--)k.splice(ne[he],1),S.splice(ne[he],1),L.splice(ne[he],1)}}k.forEach(function(ce,ae){T.eles=ce,D.push(y(T,S[ae])),d.relocateComponent(L[ae],D[ae],T)})}else k.forEach(function(ce,ae){d.relocateComponent(L[ae],S[ae],T)});var K=new Set;if(k.length>1){var X=[],te=A.filter(function(ce){return ce.css("display")=="none"});k.forEach(function(ce,ae){var Oe=void 0;if(T.quality=="draft"&&(Oe=S[ae].nodeIndexes),ce.nodes().not(te).length>0){var ge={};ge.edges=[],ge.nodes=[];var ze=void 0;ce.nodes().not(te).forEach(function(He){if(T.quality=="draft")if(!He.isParent())ze=Oe.get(He.id()),ge.nodes.push({x:S[ae].xCoords[ze]-He.boundingbox().w/2,y:S[ae].yCoords[ze]-He.boundingbox().h/2,width:He.boundingbox().w,height:He.boundingbox().h});else{var $e=d.calcBoundingBox(He,S[ae].xCoords,S[ae].yCoords,Oe);ge.nodes.push({x:$e.topLeftX,y:$e.topLeftY,width:$e.width,height:$e.height})}else D[ae][He.id()]&&ge.nodes.push({x:D[ae][He.id()].getLeft(),y:D[ae][He.id()].getTop(),width:D[ae][He.id()].getWidth(),height:D[ae][He.id()].getHeight()})}),ce.edges().forEach(function(He){var $e=He.source(),Re=He.target();if($e.css("display")!="none"&&Re.css("display")!="none")if(T.quality=="draft"){var Ie=Oe.get($e.id()),be=Oe.get(Re.id()),W=[],de=[];if($e.isParent()){var re=d.calcBoundingBox($e,S[ae].xCoords,S[ae].yCoords,Oe);W.push(re.topLeftX+re.width/2),W.push(re.topLeftY+re.height/2)}else W.push(S[ae].xCoords[Ie]),W.push(S[ae].yCoords[Ie]);if(Re.isParent()){var oe=d.calcBoundingBox(Re,S[ae].xCoords,S[ae].yCoords,Oe);de.push(oe.topLeftX+oe.width/2),de.push(oe.topLeftY+oe.height/2)}else de.push(S[ae].xCoords[be]),de.push(S[ae].yCoords[be]);ge.edges.push({startX:W[0],startY:W[1],endX:de[0],endY:de[1]})}else D[ae][$e.id()]&&D[ae][Re.id()]&&ge.edges.push({startX:D[ae][$e.id()].getCenterX(),startY:D[ae][$e.id()].getCenterY(),endX:D[ae][Re.id()].getCenterX(),endY:D[ae][Re.id()].getCenterY()})}),ge.nodes.length>0&&(X.push(ge),K.add(ae))}});var J=O.packComponents(X,T.randomize).shifts;if(T.quality=="draft")S.forEach(function(ce,ae){var Oe=ce.xCoords.map(function(ze){return ze+J[ae].dx}),ge=ce.yCoords.map(function(ze){return ze+J[ae].dy});ce.xCoords=Oe,ce.yCoords=ge});else{var se=0;K.forEach(function(ce){Object.keys(D[ce]).forEach(function(ae){var Oe=D[ce][ae];Oe.setCenter(Oe.getCenterX()+J[se].dx,Oe.getCenterY()+J[se].dy)}),se++})}}}else{var B=T.eles.boundingBox();if(L.push({x:B.x1+B.w/2,y:B.y1+B.h/2}),T.randomize){var F=m(T);S.push(F)}T.quality=="default"||T.quality=="proof"?(D.push(y(T,S[0])),d.relocateComponent(L[0],D[0],T)):d.relocateComponent(L[0],S[0],T)}var ue=o(function(ae,Oe){if(T.quality=="default"||T.quality=="proof"){typeof ae=="number"&&(ae=Oe);var ge=void 0,ze=void 0,He=ae.data("id");return D.forEach(function(Re){He in Re&&(ge={x:Re[He].getRect().getCenterX(),y:Re[He].getRect().getCenterY()},ze=Re[He])}),T.nodeDimensionsIncludeLabels&&(ze.labelWidth&&(ze.labelPosHorizontal=="left"?ge.x+=ze.labelWidth/2:ze.labelPosHorizontal=="right"&&(ge.x-=ze.labelWidth/2)),ze.labelHeight&&(ze.labelPosVertical=="top"?ge.y+=ze.labelHeight/2:ze.labelPosVertical=="bottom"&&(ge.y-=ze.labelHeight/2))),ge==null&&(ge={x:ae.position("x"),y:ae.position("y")}),{x:ge.x,y:ge.y}}else{var $e=void 0;return S.forEach(function(Re){var Ie=Re.nodeIndexes.get(ae.id());Ie!=null&&($e={x:Re.xCoords[Ie],y:Re.yCoords[Ie]})}),$e==null&&($e={x:ae.position("x"),y:ae.position("y")}),{x:$e.x,y:$e.y}}},"getPositions");if(T.quality=="default"||T.quality=="proof"||T.randomize){var Z=d.calcParentsWithoutChildren(E,A),Se=A.filter(function(ce){return ce.css("display")=="none"});T.eles=A.not(Se),A.nodes().not(":parent").not(Se).layoutPositions(C,T,ue),Z.length>0&&Z.forEach(function(ce){ce.position(ue(ce))})}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")},"run")}]),b}();a.exports=x},657:(a,s,l)=>{var u=l(548),h=l(140).layoutBase.Matrix,f=l(140).layoutBase.SVD,d=o(function(m){var g=m.cy,y=m.eles,v=y.nodes(),x=y.nodes(":parent"),b=new Map,w=new Map,C=new Map,T=[],E=[],A=[],S=[],_=[],I=[],D=[],k=[],L=void 0,R=void 0,O=1e8,M=1e-9,B=m.piTol,F=m.samplingType,P=m.nodeSeparation,z=void 0,$=o(function(){for(var xe=0,q=0,pe=!1;q<z;){xe=Math.floor(Math.random()*R),pe=!1;for(var ve=0;ve<q;ve++)if(S[ve]==xe){pe=!0;break}if(!pe)S[q]=xe,q++;else continue}},"randomSampleCR"),H=o(function(xe,q,pe){for(var ve=[],Pe=0,_e=0,we=0,Ve=void 0,De=[],qe=0,at=1,Rt=0;Rt<R;Rt++)De[Rt]=O;for(ve[_e]=xe,De[xe]=0;_e>=Pe;){we=ve[Pe++];for(var st=T[we],Ue=0;Ue<st.length;Ue++)Ve=w.get(st[Ue]),De[Ve]==O&&(De[Ve]=De[we]+1,ve[++_e]=Ve);I[we][q]=De[we]*P}if(pe){for(var ct=0;ct<R;ct++)I[ct][q]<_[ct]&&(_[ct]=I[ct][q]);for(var We=0;We<R;We++)_[We]>qe&&(qe=_[We],at=We)}return at},"BFS"),Q=o(function(xe){var q=void 0;if(xe){q=Math.floor(Math.random()*R),L=q;for(var ve=0;ve<R;ve++)_[ve]=O;for(var Pe=0;Pe<z;Pe++)S[Pe]=q,q=H(q,Pe,xe)}else{$();for(var pe=0;pe<z;pe++)H(S[pe],pe,xe,!1)}for(var _e=0;_e<R;_e++)for(var we=0;we<z;we++)I[_e][we]*=I[_e][we];for(var Ve=0;Ve<z;Ve++)D[Ve]=[];for(var De=0;De<z;De++)for(var qe=0;qe<z;qe++)D[De][qe]=I[S[qe]][De]},"allBFS"),j=o(function(){for(var xe=f.svd(D),q=xe.S,pe=xe.U,ve=xe.V,Pe=q[0]*q[0]*q[0],_e=[],we=0;we<z;we++){_e[we]=[];for(var Ve=0;Ve<z;Ve++)_e[we][Ve]=0,we==Ve&&(_e[we][Ve]=q[we]/(q[we]*q[we]+Pe/(q[we]*q[we])))}k=h.multMat(h.multMat(ve,_e),h.transpose(pe))},"sample"),ie=o(function(){for(var xe=void 0,q=void 0,pe=[],ve=[],Pe=[],_e=[],we=0;we<R;we++)pe[we]=Math.random(),ve[we]=Math.random();pe=h.normalize(pe),ve=h.normalize(ve);for(var Ve=0,De=M,qe=M,at=void 0;;){Ve++;for(var Rt=0;Rt<R;Rt++)Pe[Rt]=pe[Rt];if(pe=h.multGamma(h.multL(h.multGamma(Pe),I,k)),xe=h.dotProduct(Pe,pe),pe=h.normalize(pe),De=h.dotProduct(Pe,pe),at=Math.abs(De/qe),at<=1+B&&at>=1)break;qe=De}for(var st=0;st<R;st++)Pe[st]=pe[st];for(Ve=0,qe=M;;){Ve++;for(var Ue=0;Ue<R;Ue++)_e[Ue]=ve[Ue];if(_e=h.minusOp(_e,h.multCons(Pe,h.dotProduct(Pe,_e))),ve=h.multGamma(h.multL(h.multGamma(_e),I,k)),q=h.dotProduct(_e,ve),ve=h.normalize(ve),De=h.dotProduct(_e,ve),at=Math.abs(De/qe),at<=1+B&&at>=1)break;qe=De}for(var ct=0;ct<R;ct++)_e[ct]=ve[ct];E=h.multCons(Pe,Math.sqrt(Math.abs(xe))),A=h.multCons(_e,Math.sqrt(Math.abs(q)))},"powerIteration");u.connectComponents(g,y,u.getTopMostNodes(v),b),x.forEach(function(V){u.connectComponents(g,y,u.getTopMostNodes(V.descendants().intersection(y)),b)});for(var ne=0,le=0;le<v.length;le++)v[le].isParent()||w.set(v[le].id(),ne++);var he=!0,K=!1,X=void 0;try{for(var te=b.keys()[Symbol.iterator](),J;!(he=(J=te.next()).done);he=!0){var se=J.value;w.set(se,ne++)}}catch(V){K=!0,X=V}finally{try{!he&&te.return&&te.return()}finally{if(K)throw X}}for(var ue=0;ue<w.size;ue++)T[ue]=[];x.forEach(function(V){for(var xe=V.children().intersection(y);xe.nodes(":childless").length==0;)xe=xe.nodes()[0].children().intersection(y);var q=0,pe=xe.nodes(":childless")[0].connectedEdges().length;xe.nodes(":childless").forEach(function(ve,Pe){ve.connectedEdges().length<pe&&(pe=ve.connectedEdges().length,q=Pe)}),C.set(V.id(),xe.nodes(":childless")[q].id())}),v.forEach(function(V){var xe=void 0;V.isParent()?xe=w.get(C.get(V.id())):xe=w.get(V.id()),V.neighborhood().nodes().forEach(function(q){y.intersection(V.edgesWith(q)).length>0&&(q.isParent()?T[xe].push(C.get(q.id())):T[xe].push(q.id()))})});var Z=o(function(xe){var q=w.get(xe),pe=void 0;b.get(xe).forEach(function(ve){g.getElementById(ve).isParent()?pe=C.get(ve):pe=ve,T[q].push(pe),T[w.get(pe)].push(xe)})},"_loop"),Se=!0,ce=!1,ae=void 0;try{for(var Oe=b.keys()[Symbol.iterator](),ge;!(Se=(ge=Oe.next()).done);Se=!0){var ze=ge.value;Z(ze)}}catch(V){ce=!0,ae=V}finally{try{!Se&&Oe.return&&Oe.return()}finally{if(ce)throw ae}}R=w.size;var He=void 0;if(R>2){z=R<m.sampleSize?R:m.sampleSize;for(var $e=0;$e<R;$e++)I[$e]=[];for(var Re=0;Re<z;Re++)k[Re]=[];return m.quality=="draft"||m.step=="all"?(Q(F),j(),ie(),He={nodeIndexes:w,xCoords:E,yCoords:A}):(w.forEach(function(V,xe){E.push(g.getElementById(xe).position("x")),A.push(g.getElementById(xe).position("y"))}),He={nodeIndexes:w,xCoords:E,yCoords:A}),He}else{var Ie=w.keys(),be=g.getElementById(Ie.next().value),W=be.position(),de=be.outerWidth();if(E.push(W.x),A.push(W.y),R==2){var re=g.getElementById(Ie.next().value),oe=re.outerWidth();E.push(W.x+de/2+oe/2+m.idealEdgeLength),A.push(W.y)}return He={nodeIndexes:w,xCoords:E,yCoords:A},He}},"spectralLayout");a.exports={spectralLayout:d}},579:(a,s,l)=>{var u=l(212),h=o(function(d){d&&d("layout","fcose",u)},"register");typeof cytoscape<"u"&&h(cytoscape),a.exports=h},140:a=>{a.exports=t}},r={};function n(a){var s=r[a];if(s!==void 0)return s.exports;var l=r[a]={exports:{}};return e[a](l,l.exports,n),l.exports}o(n,"__webpack_require__");var i=n(579);return i})()})});var dy,Zp,yF=N(()=>{"use strict";tu();dy=o(t=>`<g><rect width="80" height="80" style="fill: #087ebf; stroke-width: 0px;"/>${t}</g>`,"wrapIcon"),Zp={prefix:"mermaid-architecture",height:80,width:80,icons:{database:{body:dy('<path id="b" data-name="4" d="m20,57.86c0,3.94,8.95,7.14,20,7.14s20-3.2,20-7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path id="c" data-name="3" d="m20,45.95c0,3.94,8.95,7.14,20,7.14s20-3.2,20-7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path id="d" data-name="2" d="m20,34.05c0,3.94,8.95,7.14,20,7.14s20-3.2,20-7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse id="e" data-name="1" cx="40" cy="22.14" rx="20" ry="7.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="20" y1="57.86" x2="20" y2="22.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="60" y1="57.86" x2="60" y2="22.14" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/>')},server:{body:dy('<rect x="17.5" y="17.5" width="45" height="45" rx="2" ry="2" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="17.5" y1="32.5" x2="62.5" y2="32.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="17.5" y1="47.5" x2="62.5" y2="47.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><g><path d="m56.25,25c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: #fff; stroke-width: 0px;"/><path d="m56.25,25c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10;"/></g><g><path d="m56.25,40c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: #fff; stroke-width: 0px;"/><path d="m56.25,40c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10;"/></g><g><path d="m56.25,55c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: #fff; stroke-width: 0px;"/><path d="m56.25,55c0,.27-.45.5-1,.5h-10.5c-.55,0-1-.23-1-.5s.45-.5,1-.5h10.5c.55,0,1,.23,1,.5Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10;"/></g><g><circle cx="32.5" cy="25" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="27.5" cy="25" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="22.5" cy="25" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/></g><g><circle cx="32.5" cy="40" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="27.5" cy="40" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="22.5" cy="40" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/></g><g><circle cx="32.5" cy="55" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="27.5" cy="55" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/><circle cx="22.5" cy="55" r=".75" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10;"/></g>')},disk:{body:dy('<rect x="20" y="15" width="40" height="50" rx="1" ry="1" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="24" cy="19.17" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="56" cy="19.17" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="24" cy="60.83" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="56" cy="60.83" rx=".8" ry=".83" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="40" cy="33.75" rx="14" ry="14.58" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><ellipse cx="40" cy="33.75" rx="4" ry="4.17" style="fill: #fff; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path d="m37.51,42.52l-4.83,13.22c-.26.71-1.1,1.02-1.76.64l-4.18-2.42c-.66-.38-.81-1.26-.33-1.84l9.01-10.8c.88-1.05,2.56-.08,2.09,1.2Z" style="fill: #fff; stroke-width: 0px;"/>')},internet:{body:dy('<circle cx="40" cy="40" r="22.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="40" y1="17.5" x2="40" y2="62.5" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="17.5" y1="40" x2="62.5" y2="40" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path d="m39.99,17.51c-15.28,11.1-15.28,33.88,0,44.98" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><path d="m40.01,17.51c15.28,11.1,15.28,33.88,0,44.98" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="19.75" y1="30.1" x2="60.25" y2="30.1" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/><line x1="19.75" y1="49.9" x2="60.25" y2="49.9" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/>')},cloud:{body:dy('<path d="m65,47.5c0,2.76-2.24,5-5,5H20c-2.76,0-5-2.24-5-5,0-1.87,1.03-3.51,2.56-4.36-.04-.21-.06-.42-.06-.64,0-2.6,2.48-4.74,5.65-4.97,1.65-4.51,6.34-7.76,11.85-7.76.86,0,1.69.08,2.5.23,2.09-1.57,4.69-2.5,7.5-2.5,6.1,0,11.19,4.38,12.28,10.17,2.14.56,3.72,2.51,3.72,4.83,0,.03,0,.07-.01.1,2.29.46,4.01,2.48,4.01,4.9Z" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 2px;"/>')},unknown:OC,blank:{body:dy("")}}}});var Bve,Fve,$ve,zve,Gve=N(()=>{"use strict";tu();zt();to();w4();yF();oC();Bve=o(async function(t,e){let r=Li("padding"),n=Li("iconSize"),i=n/2,a=n/6,s=a/2;await Promise.all(e.edges().map(async l=>{let{source:u,sourceDir:h,sourceArrow:f,sourceGroup:d,target:p,targetDir:m,targetArrow:g,targetGroup:y,label:v}=sC(l),{x,y:b}=l[0].sourceEndpoint(),{x:w,y:C}=l[0].midpoint(),{x:T,y:E}=l[0].targetEndpoint(),A=r+4;if(d&&(Ha(h)?x+=h==="L"?-A:A:b+=h==="T"?-A:A+18),y&&(Ha(m)?T+=m==="L"?-A:A:E+=m==="T"?-A:A+18),!d&&Qp.getNode(u)?.type==="junction"&&(Ha(h)?x+=h==="L"?i:-i:b+=h==="T"?i:-i),!y&&Qp.getNode(p)?.type==="junction"&&(Ha(m)?T+=m==="L"?i:-i:E+=m==="T"?i:-i),l[0]._private.rscratch){let S=t.insert("g");if(S.insert("path").attr("d",`M ${x},${b} L ${w},${C} L${T},${E} `).attr("class","edge"),f){let _=Ha(h)?v4[h](x,a):x-s,I=Zc(h)?v4[h](b,a):b-s;S.insert("polygon").attr("points",cF[h](a)).attr("transform",`translate(${_},${I})`).attr("class","arrow")}if(g){let _=Ha(m)?v4[m](T,a):T-s,I=Zc(m)?v4[m](E,a):E-s;S.insert("polygon").attr("points",cF[m](a)).attr("transform",`translate(${_},${I})`).attr("class","arrow")}if(v){let _=x4(h,m)?"XY":Ha(h)?"X":"Y",I=0;_==="X"?I=Math.abs(x-T):_==="Y"?I=Math.abs(b-E)/1.5:I=Math.abs(x-T)/2;let D=S.append("g");if(await Hn(D,v,{useHtmlLabels:!1,width:I,classes:"architecture-service-label"},me()),D.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),_==="X")D.attr("transform","translate("+w+", "+C+")");else if(_==="Y")D.attr("transform","translate("+w+", "+C+") rotate(-90)");else if(_==="XY"){let k=b4(h,m);if(k&&Sve(k)){let L=D.node().getBoundingClientRect(),[R,O]=Ave(k);D.attr("dominant-baseline","auto").attr("transform",`rotate(${-1*R*O*45})`);let M=D.node().getBoundingClientRect();D.attr("transform",`
+ translate(${w}, ${C-L.height/2})
+ translate(${R*M.width/2}, ${O*M.height/2})
+ rotate(${-1*R*O*45}, 0, ${L.height/2})
+ `)}}}}}))},"drawEdges"),Fve=o(async function(t,e){let n=Li("padding")*.75,i=Li("fontSize"),s=Li("iconSize")/2;await Promise.all(e.nodes().map(async l=>{let u=Ff(l);if(u.type==="group"){let{h,w:f,x1:d,y1:p}=l.boundingBox();t.append("rect").attr("x",d+s).attr("y",p+s).attr("width",f).attr("height",h).attr("class","node-bkg");let m=t.append("g"),g=d,y=p;if(u.icon){let v=m.append("g");v.html(`<g>${await wo(u.icon,{height:n,width:n,fallbackPrefix:Zp.prefix})}</g>`),v.attr("transform","translate("+(g+s+1)+", "+(y+s+1)+")"),g+=n,y+=i/2-1-2}if(u.label){let v=m.append("g");await Hn(v,u.label,{useHtmlLabels:!1,width:f,classes:"architecture-service-label"},me()),v.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","start").attr("text-anchor","start"),v.attr("transform","translate("+(g+s+4)+", "+(y+s+2)+")")}}}))},"drawGroups"),$ve=o(async function(t,e,r){for(let n of r){let i=e.append("g"),a=Li("iconSize");if(n.title){let h=i.append("g");await Hn(h,n.title,{useHtmlLabels:!1,width:a*1.5,classes:"architecture-service-label"},me()),h.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),h.attr("transform","translate("+a/2+", "+a+")")}let s=i.append("g");if(n.icon)s.html(`<g>${await wo(n.icon,{height:a,width:a,fallbackPrefix:Zp.prefix})}</g>`);else if(n.iconText){s.html(`<g>${await wo("blank",{height:a,width:a,fallbackPrefix:Zp.prefix})}</g>`);let d=s.append("g").append("foreignObject").attr("width",a).attr("height",a).append("div").attr("class","node-icon-text").attr("style",`height: ${a}px;`).append("div").html(n.iconText),p=parseInt(window.getComputedStyle(d.node(),null).getPropertyValue("font-size").replace(/\D/g,""))??16;d.attr("style",`-webkit-line-clamp: ${Math.floor((a-2)/p)};`)}else s.append("path").attr("class","node-bkg").attr("id","node-"+n.id).attr("d",`M0 ${a} v${-a} q0,-5 5,-5 h${a} q5,0 5,5 v${a} H0 Z`);i.attr("class","architecture-service");let{width:l,height:u}=i._groups[0][0].getBBox();n.width=l,n.height=u,t.setElementForId(n.id,i)}return 0},"drawServices"),zve=o(function(t,e,r){r.forEach(n=>{let i=e.append("g"),a=Li("iconSize");i.append("g").append("rect").attr("id","node-"+n.id).attr("fill-opacity","0").attr("width",a).attr("height",a),i.attr("class","architecture-junction");let{width:l,height:u}=i._groups[0][0].getBBox();i.width=l,i.height=u,t.setElementForId(n.id,i)})},"drawJunctions")});function Srt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"service",id:r.id,icon:r.icon,label:r.title,parent:r.in,width:Li("iconSize"),height:Li("iconSize")},classes:"node-service"})})}function Crt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"junction",id:r.id,parent:r.in,width:Li("iconSize"),height:Li("iconSize")},classes:"node-junction"})})}function Art(t,e){e.nodes().map(r=>{let n=Ff(r);if(n.type==="group")return;n.x=r.position().x,n.y=r.position().y,t.getElementById(n.id).attr("transform","translate("+(n.x||0)+","+(n.y||0)+")")})}function _rt(t,e){t.forEach(r=>{e.add({group:"nodes",data:{type:"group",id:r.id,icon:r.icon,label:r.title,parent:r.in},classes:"node-group"})})}function Drt(t,e){t.forEach(r=>{let{lhsId:n,rhsId:i,lhsInto:a,lhsGroup:s,rhsInto:l,lhsDir:u,rhsDir:h,rhsGroup:f,title:d}=r,p=x4(r.lhsDir,r.rhsDir)?"segments":"straight",m={id:`${n}-${i}`,label:d,source:n,sourceDir:u,sourceArrow:a,sourceGroup:s,sourceEndpoint:u==="L"?"0 50%":u==="R"?"100% 50%":u==="T"?"50% 0":"50% 100%",target:i,targetDir:h,targetArrow:l,targetGroup:f,targetEndpoint:h==="L"?"0 50%":h==="R"?"100% 50%":h==="T"?"50% 0":"50% 100%"};e.add({group:"edges",data:m,classes:p})})}function Lrt(t,e,r){let n=o((l,u)=>Object.entries(l).reduce((h,[f,d])=>{let p=0,m=Object.entries(d);if(m.length===1)return h[f]=m[0][1],h;for(let g=0;g<m.length-1;g++)for(let y=g+1;y<m.length;y++){let[v,x]=m[g],[b,w]=m[y];if(r[v]?.[b]===u)h[f]??=[],h[f]=[...h[f],...x,...w];else if(v==="default"||b==="default")h[f]??=[],h[f]=[...h[f],...x,...w];else{let T=`${f}-${p++}`;h[T]=x;let E=`${f}-${p++}`;h[E]=w}}return h},{}),"flattenAlignments"),i=e.map(l=>{let u={},h={};return Object.entries(l).forEach(([f,[d,p]])=>{let m=t.getNode(f)?.in??"default";u[p]??={},u[p][m]??=[],u[p][m].push(f),h[d]??={},h[d][m]??=[],h[d][m].push(f)}),{horiz:Object.values(n(u,"horizontal")).filter(f=>f.length>1),vert:Object.values(n(h,"vertical")).filter(f=>f.length>1)}}),[a,s]=i.reduce(([l,u],{horiz:h,vert:f})=>[[...l,...h],[...u,...f]],[[],[]]);return{horizontal:a,vertical:s}}function Rrt(t){let e=[],r=o(i=>`${i[0]},${i[1]}`,"posToStr"),n=o(i=>i.split(",").map(a=>parseInt(a)),"strToPos");return t.forEach(i=>{let a=Object.fromEntries(Object.entries(i).map(([h,f])=>[r(f),h])),s=[r([0,0])],l={},u={L:[-1,0],R:[1,0],T:[0,1],B:[0,-1]};for(;s.length>0;){let h=s.shift();if(h){l[h]=1;let f=a[h];if(f){let d=n(h);Object.entries(u).forEach(([p,m])=>{let g=r([d[0]+m[0],d[1]+m[1]]),y=a[g];y&&!l[g]&&(s.push(g),e.push({[lF[p]]:y,[lF[Eve(p)]]:f,gap:1.5*Li("iconSize")}))})}}}}),e}function Nrt(t,e,r,n,i,{spatialMaps:a,groupAlignments:s}){return new Promise(l=>{let u=Ge("body").append("div").attr("id","cy").attr("style","display:none"),h=rl({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"straight",label:"data(label)","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"edge.segments",style:{"curve-style":"segments","segment-weights":"0","segment-distances":[.5],"edge-distances":"endpoints","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"node",style:{"compound-sizing-wrt-labels":"include"}},{selector:"node[label]",style:{"text-valign":"bottom","text-halign":"center","font-size":`${Li("fontSize")}px`}},{selector:".node-service",style:{label:"data(label)",width:"data(width)",height:"data(height)"}},{selector:".node-junction",style:{width:"data(width)",height:"data(height)"}},{selector:".node-group",style:{padding:`${Li("padding")}px`}}]});u.remove(),_rt(r,h),Srt(t,h),Crt(e,h),Drt(n,h);let f=Lrt(i,a,s),d=Rrt(a),p=h.layout({name:"fcose",quality:"proof",styleEnabled:!1,animate:!1,nodeDimensionsIncludeLabels:!1,idealEdgeLength(m){let[g,y]=m.connectedNodes(),{parent:v}=Ff(g),{parent:x}=Ff(y);return v===x?1.5*Li("iconSize"):.5*Li("iconSize")},edgeElasticity(m){let[g,y]=m.connectedNodes(),{parent:v}=Ff(g),{parent:x}=Ff(y);return v===x?.45:.001},alignmentConstraint:f,relativePlacementConstraint:d});p.one("layoutstop",()=>{function m(g,y,v,x){let b,w,{x:C,y:T}=g,{x:E,y:A}=y;w=(x-T+(C-v)*(T-A)/(C-E))/Math.sqrt(1+Math.pow((T-A)/(C-E),2)),b=Math.sqrt(Math.pow(x-T,2)+Math.pow(v-C,2)-Math.pow(w,2));let S=Math.sqrt(Math.pow(E-C,2)+Math.pow(A-T,2));b=b/S;let _=(E-C)*(x-T)-(A-T)*(v-C);switch(!0){case _>=0:_=1;break;case _<0:_=-1;break}let I=(E-C)*(v-C)+(A-T)*(x-T);switch(!0){case I>=0:I=1;break;case I<0:I=-1;break}return w=Math.abs(w)*_,b=b*I,{distances:w,weights:b}}o(m,"getSegmentWeights"),h.startBatch();for(let g of Object.values(h.edges()))if(g.data?.()){let{x:y,y:v}=g.source().position(),{x,y:b}=g.target().position();if(y!==x&&v!==b){let w=g.sourceEndpoint(),C=g.targetEndpoint(),{sourceDir:T}=sC(g),[E,A]=Zc(T)?[w.x,C.y]:[C.x,w.y],{weights:S,distances:_}=m(w,C,E,A);g.style("segment-distances",_),g.style("segment-weights",S)}}h.endBatch(),p.run()}),p.run(),h.ready(m=>{Y.info("Ready",m),l(h)})})}var Vve,Mrt,Uve,Hve=N(()=>{"use strict";tu();kB();Vve=Sa(Pve(),1);dr();vt();Vc();Ei();w4();yF();oC();Gve();P4([{name:Zp.prefix,icons:Zp}]);rl.use(Vve.default);o(Srt,"addServices");o(Crt,"addJunctions");o(Art,"positionNodes");o(_rt,"addGroups");o(Drt,"addEdges");o(Lrt,"getAlignments");o(Rrt,"getRelativeConstraints");o(Nrt,"layoutArchitecture");Mrt=o(async(t,e,r,n)=>{let i=n.db,a=i.getServices(),s=i.getJunctions(),l=i.getGroups(),u=i.getEdges(),h=i.getDataStructures(),f=sa(e),d=f.append("g");d.attr("class","architecture-edges");let p=f.append("g");p.attr("class","architecture-services");let m=f.append("g");m.attr("class","architecture-groups"),await $ve(i,p,a),zve(i,p,s);let g=await Nrt(a,s,l,u,i,h);await Bve(d,g),await Fve(m,g),Art(i,g),Ao(void 0,f,Li("padding"),Li("useMaxWidth"))},"draw"),Uve={draw:Mrt}});var Wve={};hr(Wve,{diagram:()=>Irt});var Irt,qve=N(()=>{"use strict";Mve();w4();Ove();Hve();Irt={parser:Nve,db:Qp,renderer:Uve,styles:Ive}});var bnt={};hr(bnt,{default:()=>xnt});tu();PC();Xf();var YX="c4",PCe=o(t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),"detector"),BCe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(qX(),WX));return{id:YX,diagram:t}},"loader"),FCe={id:YX,detector:PCe,loader:BCe},XX=FCe;var Xie="flowchart",xOe=o((t,e)=>e?.flowchart?.defaultRenderer==="dagre-wrapper"||e?.flowchart?.defaultRenderer==="elk"?!1:/^\s*graph/.test(t),"detector"),bOe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(ak(),ik));return{id:Xie,diagram:t}},"loader"),wOe={id:Xie,detector:xOe,loader:bOe},jie=wOe;var Kie="flowchart-v2",TOe=o((t,e)=>e?.flowchart?.defaultRenderer==="dagre-d3"?!1:(e?.flowchart?.defaultRenderer==="elk"&&(e.layout="elk"),/^\s*graph/.test(t)&&e?.flowchart?.defaultRenderer==="dagre-wrapper"?!0:/^\s*flowchart/.test(t)),"detector"),kOe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(ak(),ik));return{id:Kie,diagram:t}},"loader"),EOe={id:Kie,detector:TOe,loader:kOe},Qie=EOe;var sae="er",DOe=o(t=>/^\s*erDiagram/.test(t),"detector"),LOe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(aae(),iae));return{id:sae,diagram:t}},"loader"),ROe={id:sae,detector:DOe,loader:LOe},oae=ROe;var uue="gitGraph",tze=o(t=>/^\s*gitGraph/.test(t),"detector"),rze=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(cue(),lue));return{id:uue,diagram:t}},"loader"),nze={id:uue,detector:tze,loader:rze},hue=nze;var Gue="gantt",Hze=o(t=>/^\s*gantt/.test(t),"detector"),Wze=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(zue(),$ue));return{id:Gue,diagram:t}},"loader"),qze={id:Gue,detector:Hze,loader:Wze},Vue=qze;var Que="info",Zze=o(t=>/^\s*info/.test(t),"detector"),Jze=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Kue(),jue));return{id:Que,diagram:t}},"loader"),Zue={id:Que,detector:Zze,loader:Jze};var lhe="pie",fGe=o(t=>/^\s*pie/.test(t),"detector"),dGe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(ohe(),she));return{id:lhe,diagram:t}},"loader"),che={id:lhe,detector:fGe,loader:dGe};var The="quadrantChart",RGe=o(t=>/^\s*quadrantChart/.test(t),"detector"),NGe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(whe(),bhe));return{id:The,diagram:t}},"loader"),MGe={id:The,detector:RGe,loader:NGe},khe=MGe;var Khe="xychart",jGe=o(t=>/^\s*xychart-beta/.test(t),"detector"),KGe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(jhe(),Xhe));return{id:Khe,diagram:t}},"loader"),QGe={id:Khe,detector:jGe,loader:KGe},Qhe=QGe;var sfe="requirement",tVe=o(t=>/^\s*requirement(Diagram)?/.test(t),"detector"),rVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(afe(),ife));return{id:sfe,diagram:t}},"loader"),nVe={id:sfe,detector:tVe,loader:rVe},ofe=nVe;var Afe="sequence",zVe=o(t=>/^\s*sequenceDiagram/.test(t),"detector"),GVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Cfe(),Sfe));return{id:Afe,diagram:t}},"loader"),VVe={id:Afe,detector:zVe,loader:GVe},_fe=VVe;var Ife="class",XVe=o((t,e)=>e?.class?.defaultRenderer==="dagre-wrapper"?!1:/^\s*classDiagram/.test(t),"detector"),jVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Mfe(),Nfe));return{id:Ife,diagram:t}},"loader"),KVe={id:Ife,detector:XVe,loader:jVe},Ofe=KVe;var Ffe="classDiagram",ZVe=o((t,e)=>/^\s*classDiagram/.test(t)&&e?.class?.defaultRenderer==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(t),"detector"),JVe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Bfe(),Pfe));return{id:Ffe,diagram:t}},"loader"),eUe={id:Ffe,detector:ZVe,loader:JVe},$fe=eUe;var Ede="state",LUe=o((t,e)=>e?.state?.defaultRenderer==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(t),"detector"),RUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(kde(),Tde));return{id:Ede,diagram:t}},"loader"),NUe={id:Ede,detector:LUe,loader:RUe},Sde=NUe;var _de="stateDiagram",IUe=o((t,e)=>!!(/^\s*stateDiagram-v2/.test(t)||/^\s*stateDiagram/.test(t)&&e?.state?.defaultRenderer==="dagre-wrapper"),"detector"),OUe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Ade(),Cde));return{id:_de,diagram:t}},"loader"),PUe={id:_de,detector:IUe,loader:OUe},Dde=PUe;var Wde="journey",nHe=o(t=>/^\s*journey/.test(t),"detector"),iHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Hde(),Ude));return{id:Wde,diagram:t}},"loader"),aHe={id:Wde,detector:nHe,loader:iHe},qde=aHe;vt();Vc();Ei();var sHe=o((t,e,r)=>{Y.debug(`rendering svg for syntax error
+`);let n=sa(e),i=n.append("g");n.attr("viewBox","0 0 2412 512"),vn(n,100,512,!0),i.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),i.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),i.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),i.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),i.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),i.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),i.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),i.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)},"draw"),fP={draw:sHe},Yde=fP;var oHe={db:{},renderer:fP,parser:{parse:o(()=>{},"parse")}},Xde=oHe;var jde="flowchart-elk",lHe=o((t,e={})=>/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&e?.flowchart?.defaultRenderer==="elk"?(e.layout="elk",!0):!1,"detector"),cHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(ak(),ik));return{id:jde,diagram:t}},"loader"),uHe={id:jde,detector:lHe,loader:cHe},Kde=uHe;var Tpe="timeline",DHe=o(t=>/^\s*timeline/.test(t),"detector"),LHe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(wpe(),bpe));return{id:Tpe,diagram:t}},"loader"),RHe={id:Tpe,detector:DHe,loader:LHe},kpe=RHe;var e1e="mindmap",cJe=o(t=>/^\s*mindmap/.test(t),"detector"),uJe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(Jge(),Zge));return{id:e1e,diagram:t}},"loader"),hJe={id:e1e,detector:cJe,loader:uJe},t1e=hJe;var d1e="kanban",AJe=o(t=>/^\s*kanban/.test(t),"detector"),_Je=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(f1e(),h1e));return{id:d1e,diagram:t}},"loader"),DJe={id:d1e,detector:AJe,loader:_Je},p1e=DJe;var j1e="sankey",ZJe=o(t=>/^\s*sankey-beta/.test(t),"detector"),JJe=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(X1e(),Y1e));return{id:j1e,diagram:t}},"loader"),eet={id:j1e,detector:ZJe,loader:JJe},K1e=eet;var sye="packet",pet=o(t=>/^\s*packet-beta/.test(t),"detector"),met=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(aye(),iye));return{id:sye,diagram:t}},"loader"),oye={id:sye,detector:pet,loader:met};var vye="radar",Fet=o(t=>/^\s*radar-beta/.test(t),"detector"),$et=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(yye(),gye));return{id:vye,diagram:t}},"loader"),xye={id:vye,detector:Fet,loader:$et};var Tve="block",srt=o(t=>/^\s*block-beta/.test(t),"detector"),ort=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(wve(),bve));return{id:Tve,diagram:t}},"loader"),lrt={id:Tve,detector:srt,loader:ort},kve=lrt;var Yve="architecture",Ort=o(t=>/^\s*architecture/.test(t),"detector"),Prt=o(async()=>{let{diagram:t}=await Promise.resolve().then(()=>(qve(),Wve));return{id:Yve,diagram:t}},"loader"),Brt={id:Yve,detector:Ort,loader:Prt},Xve=Brt;Xf();zt();var jve=!1,py=o(()=>{jve||(jve=!0,ad("error",Xde,t=>t.toLowerCase().trim()==="error"),ad("---",{db:{clear:o(()=>{},"clear")},styles:{},renderer:{draw:o(()=>{},"draw")},parser:{parse:o(()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")},"parse")},init:o(()=>null,"init")},t=>t.toLowerCase().trimStart().startsWith("---")),z4(XX,p1e,$fe,Ofe,oae,Vue,Zue,che,ofe,_fe,Kde,Qie,jie,t1e,kpe,hue,Dde,Sde,qde,khe,K1e,oye,Qhe,kve,Xve,xye))},"addDiagrams");vt();Xf();zt();var Kve=o(async()=>{Y.debug("Loading registered diagrams");let e=(await Promise.allSettled(Object.entries(Yf).map(async([r,{detector:n,loader:i}])=>{if(i)try{jy(r)}catch{try{let{diagram:a,id:s}=await i();ad(s,a,n)}catch(a){throw Y.error(`Failed to load external diagram with key ${r}. Removing from detectors.`),delete Yf[r],a}}}))).filter(r=>r.status==="rejected");if(e.length>0){Y.error(`Failed to load ${e.length} external diagrams`);for(let r of e)Y.error(r);throw new Error(`Failed to load ${e.length} external diagrams`)}},"loadRegisteredDiagrams");vt();dr();var lC="comm",cC="rule",uC="decl";var Qve="@import";var Zve="@namespace",Jve="@keyframes";var e2e="@layer";var vF=Math.abs,S4=String.fromCharCode;function hC(t){return t.trim()}o(hC,"trim");function C4(t,e,r){return t.replace(e,r)}o(C4,"replace");function t2e(t,e,r){return t.indexOf(e,r)}o(t2e,"indexof");function $f(t,e){return t.charCodeAt(e)|0}o($f,"charat");function zf(t,e,r){return t.slice(e,r)}o(zf,"substr");function vo(t){return t.length}o(vo,"strlen");function r2e(t){return t.length}o(r2e,"sizeof");function my(t,e){return e.push(t),t}o(my,"append");var fC=1,gy=1,n2e=0,il=0,Ri=0,vy="";function dC(t,e,r,n,i,a,s,l){return{value:t,root:e,parent:r,type:n,props:i,children:a,line:fC,column:gy,length:s,return:"",siblings:l}}o(dC,"node");function i2e(){return Ri}o(i2e,"char");function a2e(){return Ri=il>0?$f(vy,--il):0,gy--,Ri===10&&(gy=1,fC--),Ri}o(a2e,"prev");function al(){return Ri=il<n2e?$f(vy,il++):0,gy++,Ri===10&&(gy=1,fC++),Ri}o(al,"next");function rh(){return $f(vy,il)}o(rh,"peek");function A4(){return il}o(A4,"caret");function pC(t,e){return zf(vy,t,e)}o(pC,"slice");function yy(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}o(yy,"token");function s2e(t){return fC=gy=1,n2e=vo(vy=t),il=0,[]}o(s2e,"alloc");function o2e(t){return vy="",t}o(o2e,"dealloc");function mC(t){return hC(pC(il-1,xF(t===91?t+2:t===40?t+1:t)))}o(mC,"delimit");function l2e(t){for(;(Ri=rh())&&Ri<33;)al();return yy(t)>2||yy(Ri)>3?"":" "}o(l2e,"whitespace");function c2e(t,e){for(;--e&&al()&&!(Ri<48||Ri>102||Ri>57&&Ri<65||Ri>70&&Ri<97););return pC(t,A4()+(e<6&&rh()==32&&al()==32))}o(c2e,"escaping");function xF(t){for(;al();)switch(Ri){case t:return il;case 34:case 39:t!==34&&t!==39&&xF(Ri);break;case 40:t===41&&xF(t);break;case 92:al();break}return il}o(xF,"delimiter");function u2e(t,e){for(;al()&&t+Ri!==57;)if(t+Ri===84&&rh()===47)break;return"/*"+pC(e,il-1)+"*"+S4(t===47?t:al())}o(u2e,"commenter");function h2e(t){for(;!yy(rh());)al();return pC(t,il)}o(h2e,"identifier");function p2e(t){return o2e(gC("",null,null,null,[""],t=s2e(t),0,[0],t))}o(p2e,"compile");function gC(t,e,r,n,i,a,s,l,u){for(var h=0,f=0,d=s,p=0,m=0,g=0,y=1,v=1,x=1,b=0,w="",C=i,T=a,E=n,A=w;v;)switch(g=b,b=al()){case 40:if(g!=108&&$f(A,d-1)==58){t2e(A+=C4(mC(b),"&","&\f"),"&\f",vF(h?l[h-1]:0))!=-1&&(x=-1);break}case 34:case 39:case 91:A+=mC(b);break;case 9:case 10:case 13:case 32:A+=l2e(g);break;case 92:A+=c2e(A4()-1,7);continue;case 47:switch(rh()){case 42:case 47:my(Frt(u2e(al(),A4()),e,r,u),u),(yy(g||1)==5||yy(rh()||1)==5)&&vo(A)&&zf(A,-1,void 0)!==" "&&(A+=" ");break;default:A+="/"}break;case 123*y:l[h++]=vo(A)*x;case 125*y:case 59:case 0:switch(b){case 0:case 125:v=0;case 59+f:x==-1&&(A=C4(A,/\f/g,"")),m>0&&(vo(A)-d||y===0&&g===47)&&my(m>32?d2e(A+";",n,r,d-1,u):d2e(C4(A," ","")+";",n,r,d-2,u),u);break;case 59:A+=";";default:if(my(E=f2e(A,e,r,h,f,i,l,w,C=[],T=[],d,a),a),b===123)if(f===0)gC(A,e,E,E,C,a,d,l,T);else{switch(p){case 99:if($f(A,3)===110)break;case 108:if($f(A,2)===97)break;default:f=0;case 100:case 109:case 115:}f?gC(t,E,E,n&&my(f2e(t,E,E,0,0,i,l,w,i,C=[],d,T),T),i,T,d,l,n?C:T):gC(A,E,E,E,[""],T,0,l,T)}}h=f=m=0,y=x=1,w=A="",d=s;break;case 58:d=1+vo(A),m=g;default:if(y<1){if(b==123)--y;else if(b==125&&y++==0&&a2e()==125)continue}switch(A+=S4(b),b*y){case 38:x=f>0?1:(A+="\f",-1);break;case 44:l[h++]=(vo(A)-1)*x,x=1;break;case 64:rh()===45&&(A+=mC(al())),p=rh(),f=d=vo(w=A+=h2e(A4())),b++;break;case 45:g===45&&vo(A)==2&&(y=0)}}return a}o(gC,"parse");function f2e(t,e,r,n,i,a,s,l,u,h,f,d){for(var p=i-1,m=i===0?a:[""],g=r2e(m),y=0,v=0,x=0;y<n;++y)for(var b=0,w=zf(t,p+1,p=vF(v=s[y])),C=t;b<g;++b)(C=hC(v>0?m[b]+" "+w:C4(w,/&\f/g,m[b])))&&(u[x++]=C);return dC(t,e,r,i===0?cC:l,u,h,f,d)}o(f2e,"ruleset");function Frt(t,e,r,n){return dC(t,e,r,lC,S4(i2e()),zf(t,2,-2),0,n)}o(Frt,"comment");function d2e(t,e,r,n,i){return dC(t,e,r,uC,zf(t,0,n),zf(t,n+1,-1),n,i)}o(d2e,"declaration");function yC(t,e){for(var r="",n=0;n<t.length;n++)r+=e(t[n],n,t,e)||"";return r}o(yC,"serialize");function m2e(t,e,r,n){switch(t.type){case e2e:if(t.children.length)break;case Qve:case Zve:case uC:return t.return=t.return||t.value;case lC:return"";case Jve:return t.return=t.value+"{"+yC(t.children,n)+"}";case cC:if(!vo(t.value=t.props.join(",")))return""}return vo(r=yC(t.children,n))?t.return=t.value+"{"+r+"}":""}o(m2e,"stringify");u7();HT();oO();var $rt="graphics-document document";function g2e(t,e){t.attr("role",$rt),e!==""&&t.attr("aria-roledescription",e)}o(g2e,"setA11yDiagramInfo");function y2e(t,e,r,n){if(t.insert!==void 0){if(r){let i=`chart-desc-${n}`;t.attr("aria-describedby",i),t.insert("desc",":first-child").attr("id",i).text(r)}if(e){let i=`chart-title-${n}`;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}o(y2e,"addSVGa11yTitleDescription");s0();ji();ji();zt();Xf();BC();ir();var xy=class t{constructor(e,r,n,i,a){this.type=e;this.text=r;this.db=n;this.parser=i;this.renderer=a}static{o(this,"Diagram")}static async fromText(e,r={}){let n=cr(),i=a0(e,n);e=PX(e)+`
+`;try{jy(i)}catch{let h=ZF(i);if(!h)throw new i0(`Diagram ${i} not found.`);let{id:f,diagram:d}=await h();ad(f,d)}let{db:a,parser:s,renderer:l,init:u}=jy(i);return s.parser&&(s.parser.yy=a),a.clear?.(),u?.(n),r.title&&a.setDiagramTitle?.(r.title),await s.parse(e),new t(i,e,a,s,l)}async render(e,r){await this.renderer.draw(this.text,e,r,this)}getParser(){return this.parser}getType(){return this.type}};gr();var v2e=[];var x2e=o(()=>{v2e.forEach(t=>{t()}),v2e=[]},"attachFunctions");vt();var b2e=o(t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart(),"cleanupComments");$4();Ew();function w2e(t){let e=t.match(F4);if(!e)return{text:t,metadata:{}};let r=cm(e[1],{schema:lm})??{};r=typeof r=="object"&&!Array.isArray(r)?r:{};let n={};return r.displayMode&&(n.displayMode=r.displayMode.toString()),r.title&&(n.title=r.title.toString()),r.config&&(n.config=r.config),{text:t.slice(e[0].length),metadata:n}}o(w2e,"extractFrontMatter");ir();var zrt=o(t=>t.replace(/\r\n?/g,`
+`).replace(/<(\w+)([^>]*)>/g,(e,r,n)=>"<"+r+n.replace(/="([^"]*)"/g,"='$1'")+">"),"cleanupText"),Grt=o(t=>{let{text:e,metadata:r}=w2e(t),{displayMode:n,title:i,config:a={}}=r;return n&&(a.gantt||(a.gantt={}),a.gantt.displayMode=n),{title:i,config:a,text:e}},"processFrontmatter"),Vrt=o(t=>{let e=Gt.detectInit(t)??{},r=Gt.detectDirective(t,"wrap");return Array.isArray(r)?e.wrap=r.some(({type:n})=>n==="wrap"):r?.type==="wrap"&&(e.wrap=!0),{text:IX(t),directive:e}},"processDirectives");function bF(t){let e=zrt(t),r=Grt(e),n=Vrt(r.text),i=Fi(r.config,n.directive);return t=b2e(n.text),{code:t,title:r.title,config:i}}o(bF,"preprocessDiagram");tA();q4();ir();function T2e(t){let e=new TextEncoder().encode(t),r=Array.from(e,n=>String.fromCodePoint(n)).join("");return btoa(r)}o(T2e,"toBase64");var Urt=5e4,Hrt="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa",Wrt="sandbox",qrt="loose",Yrt="http://www.w3.org/2000/svg",Xrt="http://www.w3.org/1999/xlink",jrt="http://www.w3.org/1999/xhtml",Krt="100%",Qrt="100%",Zrt="border:0;margin:0;",Jrt="margin:0",ent="allow-top-navigation-by-user-activation allow-popups",tnt='The "iframe" tag is not supported by your browser.',rnt=["foreignobject"],nnt=["dominant-baseline"];function C2e(t){let e=bF(t);return Ly(),W$(e.config??{}),e}o(C2e,"processAndSetConfigs");async function int(t,e){py();try{let{code:r,config:n}=C2e(t);return{diagramType:(await A2e(r)).type,config:n}}catch(r){if(e?.suppressErrors)return!1;throw r}}o(int,"parse");var k2e=o((t,e,r=[])=>`
+.${t} ${e} { ${r.join(" !important; ")} !important; }`,"cssImportantStyles"),ant=o((t,e=new Map)=>{let r="";if(t.themeCSS!==void 0&&(r+=`
+${t.themeCSS}`),t.fontFamily!==void 0&&(r+=`
+:root { --mermaid-font-family: ${t.fontFamily}}`),t.altFontFamily!==void 0&&(r+=`
+:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),e instanceof Map){let s=t.htmlLabels??t.flowchart?.htmlLabels?["> *","span"]:["rect","polygon","ellipse","circle","path"];e.forEach(l=>{ur(l.styles)||s.forEach(u=>{r+=k2e(l.id,u,l.styles)}),ur(l.textStyles)||(r+=k2e(l.id,"tspan",(l?.textStyles||[]).map(u=>u.replace("color","fill"))))})}return r},"createCssStyles"),snt=o((t,e,r,n)=>{let i=ant(t,r),a=zG(e,i,t.themeVariables);return yC(p2e(`${n}{${a}}`),m2e)},"createUserStyles"),ont=o((t="",e,r)=>{let n=t;return!r&&!e&&(n=n.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),n=na(n),n=n.replace(/<br>/g,"<br/>"),n},"cleanUpSvgCode"),lnt=o((t="",e)=>{let r=e?.viewBox?.baseVal?.height?e.viewBox.baseVal.height+"px":Qrt,n=T2e(`<body style="${Jrt}">${t}</body>`);return`<iframe style="width:${Krt};height:${r};${Zrt}" src="data:text/html;charset=UTF-8;base64,${n}" sandbox="${ent}">
+ ${tnt}
+</iframe>`},"putIntoIFrame"),E2e=o((t,e,r,n,i)=>{let a=t.append("div");a.attr("id",r),n&&a.attr("style",n);let s=a.append("svg").attr("id",e).attr("width","100%").attr("xmlns",Yrt);return i&&s.attr("xmlns:xlink",i),s.append("g"),t},"appendDivSvgG");function S2e(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}o(S2e,"sandboxedIframe");var cnt=o((t,e,r,n)=>{t.getElementById(e)?.remove(),t.getElementById(r)?.remove(),t.getElementById(n)?.remove()},"removeExistingElements"),unt=o(async function(t,e,r){py();let n=C2e(e);e=n.code;let i=cr();Y.debug(i),e.length>(i?.maxTextSize??Urt)&&(e=Hrt);let a="#"+t,s="i"+t,l="#"+s,u="d"+t,h="#"+u,f=o(()=>{let L=Ge(p?l:h).node();L&&"remove"in L&&L.remove()},"removeTempElements"),d=Ge("body"),p=i.securityLevel===Wrt,m=i.securityLevel===qrt,g=i.fontFamily;if(r!==void 0){if(r&&(r.innerHTML=""),p){let k=S2e(Ge(r),s);d=Ge(k.nodes()[0].contentDocument.body),d.node().style.margin=0}else d=Ge(r);E2e(d,t,u,`font-family: ${g}`,Xrt)}else{if(cnt(document,t,u,s),p){let k=S2e(Ge("body"),s);d=Ge(k.nodes()[0].contentDocument.body),d.node().style.margin=0}else d=Ge("body");E2e(d,t,u)}let y,v;try{y=await xy.fromText(e,{title:n.title})}catch(k){if(i.suppressErrorRendering)throw f(),k;y=await xy.fromText("error"),v=k}let x=d.select(h).node(),b=y.type,w=x.firstChild,C=w.firstChild,T=y.renderer.getClasses?.(e,y),E=snt(i,b,T,a),A=document.createElement("style");A.innerHTML=E,w.insertBefore(A,C);try{await y.renderer.draw(e,t,vb.version,y)}catch(k){throw i.suppressErrorRendering?f():Yde.draw(e,t,vb.version),k}let S=d.select(`${h} svg`),_=y.db.getAccTitle?.(),I=y.db.getAccDescription?.();fnt(b,S,_,I),d.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",jrt);let D=d.select(h).node().innerHTML;if(Y.debug("config.arrowMarkerAbsolute",i.arrowMarkerAbsolute),D=ont(D,p,fr(i.arrowMarkerAbsolute)),p){let k=d.select(h+" svg").node();D=lnt(D,k)}else m||(D=ch.sanitize(D,{ADD_TAGS:rnt,ADD_ATTR:nnt,HTML_INTEGRATION_POINTS:{foreignobject:!0}}));if(x2e(),v)throw v;return f(),{diagramType:b,svg:D,bindFunctions:y.db.bindFunctions}},"render");function hnt(t={}){let e=Gn({},t);e?.fontFamily&&!e.themeVariables?.fontFamily&&(e.themeVariables||(e.themeVariables={}),e.themeVariables.fontFamily=e.fontFamily),V$(e),e?.theme&&e.theme in To?e.themeVariables=To[e.theme].getThemeVariables(e.themeVariables):e&&(e.themeVariables=To.default.getThemeVariables(e.themeVariables));let r=typeof e=="object"?t7(e):r7();wy(r.logLevel),py()}o(hnt,"initialize");var A2e=o((t,e={})=>{let{code:r}=bF(t);return xy.fromText(r,e)},"getDiagramFromText");function fnt(t,e,r,n){g2e(e,t),y2e(e,r,n,e.attr("id"))}o(fnt,"addA11yInfo");var Gf=Object.freeze({render:unt,parse:int,getDiagramFromText:A2e,initialize:hnt,getConfig:cr,setConfig:X4,getSiteConfig:r7,updateSiteConfig:U$,reset:o(()=>{Ly()},"reset"),globalReset:o(()=>{Ly(lh)},"globalReset"),defaultConfig:lh});wy(cr().logLevel);Ly(cr());Yd();ir();var dnt=o((t,e,r)=>{Y.warn(t),Z9(t)?(r&&r(t.str,t.hash),e.push({...t,message:t.str,error:t})):(r&&r(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},"handleError"),_2e=o(async function(t={querySelector:".mermaid"}){try{await pnt(t)}catch(e){if(Z9(e)&&Y.error(e.str),nh.parseError&&nh.parseError(e),!t.suppressErrors)throw Y.error("Use the suppressErrors option to suppress these errors"),e}},"run"),pnt=o(async function({postRenderCallback:t,querySelector:e,nodes:r}={querySelector:".mermaid"}){let n=Gf.getConfig();Y.debug(`${t?"":"No "}Callback function found`);let i;if(r)i=r;else if(e)i=document.querySelectorAll(e);else throw new Error("Nodes and querySelector are both undefined");Y.debug(`Found ${i.length} diagrams`),n?.startOnLoad!==void 0&&(Y.debug("Start On Load: "+n?.startOnLoad),Gf.updateSiteConfig({startOnLoad:n?.startOnLoad}));let a=new Gt.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed),s,l=[];for(let u of Array.from(i)){Y.info("Rendering diagram: "+u.id);if(u.getAttribute("data-processed"))continue;u.setAttribute("data-processed","true");let h=`mermaid-${a.next()}`;s=u.innerHTML,s=B4(Gt.entityDecode(s)).trim().replace(/<br\s*\/?>/gi,"<br/>");let f=Gt.detectInit(s);f&&Y.debug("Detected early reinit: ",f);try{let{svg:d,bindFunctions:p}=await N2e(h,s,u);u.innerHTML=d,t&&await t(h),p&&p(u)}catch(d){dnt(d,l,nh.parseError)}}if(l.length>0)throw l[0]},"runThrowsErrors"),D2e=o(function(t){Gf.initialize(t)},"initialize"),mnt=o(async function(t,e,r){Y.warn("mermaid.init is deprecated. Please use run instead."),t&&D2e(t);let n={postRenderCallback:r,querySelector:".mermaid"};typeof e=="string"?n.querySelector=e:e&&(e instanceof HTMLElement?n.nodes=[e]:n.nodes=e),await _2e(n)},"init"),gnt=o(async(t,{lazyLoad:e=!0}={})=>{py(),z4(...t),e===!1&&await Kve()},"registerExternalDiagrams"),L2e=o(function(){if(nh.startOnLoad){let{startOnLoad:t}=Gf.getConfig();t&&nh.run().catch(e=>Y.error("Mermaid failed to initialize",e))}},"contentLoaded");if(typeof document<"u"){window.addEventListener("load",L2e,!1)}var ynt=o(function(t){nh.parseError=t},"setParseErrorHandler"),vC=[],wF=!1,R2e=o(async()=>{if(!wF){for(wF=!0;vC.length>0;){let t=vC.shift();if(t)try{await t()}catch(e){Y.error("Error executing queue",e)}}wF=!1}},"executeQueue"),vnt=o(async(t,e)=>new Promise((r,n)=>{let i=o(()=>new Promise((a,s)=>{Gf.parse(t,e).then(l=>{a(l),r(l)},l=>{Y.error("Error parsing",l),nh.parseError?.(l),s(l),n(l)})}),"performCall");vC.push(i),R2e().catch(n)}),"parse"),N2e=o((t,e,r)=>new Promise((n,i)=>{let a=o(()=>new Promise((s,l)=>{Gf.render(t,e,r).then(u=>{s(u),n(u)},u=>{Y.error("Error parsing",u),nh.parseError?.(u),l(u),i(u)})}),"performCall");vC.push(a),R2e().catch(i)}),"render"),nh={startOnLoad:!0,mermaidAPI:Gf,parse:vnt,render:N2e,init:mnt,run:_2e,registerExternalDiagrams:gnt,registerLayoutLoaders:vR,initialize:D2e,parseError:void 0,contentLoaded:L2e,setParseErrorHandler:ynt,detectType:a0,registerIconPacks:P4},xnt=nh;return V2e(bnt);})();
+/*! Check if previously processed */
+/*!
+ * Wait for document loaded before starting the execution
+ */
+/*! Bundled license information:
+
+dompurify/dist/purify.es.mjs:
+ (*! @license DOMPurify 3.2.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.4/LICENSE *)
+
+js-yaml/dist/js-yaml.mjs:
+ (*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT *)
+
+lodash-es/lodash.js:
+ (**
+ * @license
+ * Lodash (Custom Build) <https://lodash.com/>
+ * Build: `lodash modularize exports="es" -o ./`
+ * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
+ * Released under MIT license <https://lodash.com/license>
+ * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ *)
+
+cytoscape/dist/cytoscape.esm.mjs:
+ (*!
+ Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
+ Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com)
+ Licensed under The MIT License (http://opensource.org/licenses/MIT)
+ *)
+ (*!
+ Event object based on jQuery events, MIT license
+
+ https://jquery.org/license/
+ https://tldrlegal.com/license/mit-license
+ https://github.com/jquery/jquery/blob/master/src/event.js
+ *)
+ (*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License *)
+ (*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License *)
+*/
+globalThis.mermaid = globalThis.__esbuild_esm_mermaid.default;
diff --git a/src/zenserver/frontend/html/util/compactbinary.js b/src/zenserver/frontend/html/util/compactbinary.js
index 415fa4be8..270c96a2f 100644
--- a/src/zenserver/frontend/html/util/compactbinary.js
+++ b/src/zenserver/frontend/html/util/compactbinary.js
@@ -369,6 +369,14 @@ CbObjectView.prototype[Symbol.iterator] = function()
////////////////////////////////////////////////////////////////////////////////
CbObjectView.prototype.to_js_object = function()
{
+ const TicksPerMs = 10000;
+ const UnixEpochTicks = 621355968000000000n; // .NET ticks at 1970-01-01
+
+ const readTicks = function(data) {
+ const dv = new DataView(data.buffer, data.byteOffset, 8);
+ return dv.getBigInt64(0, false);
+ };
+
const impl = function(node)
{
if (node.is_object())
@@ -388,9 +396,40 @@ CbObjectView.prototype.to_js_object = function()
}
if (node.is_string()) return node.as_value();
- if (node.is_integer()) return node.as_value();
if (node.is_float()) return node.as_value();
+ if (node.is_integer())
+ {
+ const v = node.as_value();
+ if (v >= -9007199254740991n && v <= 9007199254740991n)
+ return Number(v);
+ return v;
+ }
+
+ const type = CbFieldTypeOps.get_type(node.get_type());
+
+ if (type == CbFieldType.DateTime)
+ {
+ const ticks = readTicks(node.as_value());
+ const unixMs = Number((ticks - UnixEpochTicks) / BigInt(TicksPerMs));
+ return new Date(unixMs).toISOString();
+ }
+
+ if (type == CbFieldType.TimeSpan)
+ {
+ const ticks = readTicks(node.as_value());
+ const absTicks = ticks < 0n ? -ticks : ticks;
+ const totalMs = Number(absTicks / BigInt(TicksPerMs));
+ const ms = totalMs % 1000;
+ const totalSec = Math.floor(totalMs / 1000);
+ const sec = totalSec % 60;
+ const totalMin = Math.floor(totalSec / 60);
+ const min = totalMin % 60;
+ const hours = Math.floor(totalMin / 60);
+ const sign = ticks < 0n ? "-" : "";
+ return `${sign}${hours}:${String(min).padStart(2, "0")}:${String(sec).padStart(2, "0")}.${String(ms).padStart(3, "0")}0000`;
+ }
+
var ret = node.as_value();
if (ret instanceof Uint8Array)
{
diff --git a/src/zenserver/frontend/html/util/friendly.js b/src/zenserver/frontend/html/util/friendly.js
index 5d4586165..f400bbce0 100644
--- a/src/zenserver/frontend/html/util/friendly.js
+++ b/src/zenserver/frontend/html/util/friendly.js
@@ -30,6 +30,59 @@ export class Friendly
return Friendly.sep(v * 1000000000, 0) + " ns";
}
+ /** Format a .NET-style TimeSpan string (e.g. "0:05:23.4560000") as a human-readable duration. */
+ static timespan(value)
+ {
+ if (typeof value === "number")
+ {
+ return Friendly._formatDurationMs(value);
+ }
+
+ const str = String(value);
+ const match = str.match(/^[+-]?(?:(\d+)\.)?(\d+):(\d+):(\d+)(?:\.(\d+))?$/);
+ if (!match)
+ {
+ return str;
+ }
+
+ const days = parseInt(match[1] || "0", 10);
+ const hours = parseInt(match[2], 10);
+ const minutes = parseInt(match[3], 10);
+ const seconds = parseInt(match[4], 10);
+ const frac = match[5] ? parseInt(match[5].substring(0, 3).padEnd(3, "0"), 10) : 0;
+ const totalMs = ((days * 86400 + hours * 3600 + minutes * 60 + seconds) * 1000) + frac;
+
+ return Friendly._formatDurationMs(totalMs);
+ }
+
+ static _formatDurationMs(ms)
+ {
+ const seconds = Math.floor(ms / 1000);
+ const minutes = Math.floor(seconds / 60);
+ const hours = Math.floor(minutes / 60);
+ const days = Math.floor(hours / 24);
+
+ if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`;
+ if (hours > 0) return `${hours}h ${minutes % 60}m`;
+ if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
+ if (seconds > 0) return `${seconds}.${String(ms % 1000).padStart(3, "0")}s`;
+ return `${ms}ms`;
+ }
+
+ /** Format an ISO / .NET datetime string as a friendly local date+time. */
+ static datetime(value)
+ {
+ const d = new Date(value);
+ if (isNaN(d.getTime()))
+ {
+ return String(value);
+ }
+ return d.toLocaleString(undefined, {
+ year: "numeric", month: "short", day: "numeric",
+ hour: "2-digit", minute: "2-digit", second: "2-digit",
+ });
+ }
+
static bytes(x)
{
const v = BigInt(Math.trunc(Number(x)));
diff --git a/src/zenserver/frontend/html/util/widgets.js b/src/zenserver/frontend/html/util/widgets.js
index 2964f92f2..17bd2fde7 100644
--- a/src/zenserver/frontend/html/util/widgets.js
+++ b/src/zenserver/frontend/html/util/widgets.js
@@ -243,7 +243,7 @@ export class Table extends Widget
var row = this._add_row(args);
this._rows.push(row);
- if ((this._flags & Table.Flag_AlignNumeric) && this._rows.length === 1)
+ if (this._flags & Table.Flag_AlignNumeric)
{
this._align_header();
}
@@ -253,19 +253,23 @@ export class Table extends Widget
_align_header()
{
- const first_row = this._rows[0];
- if (!first_row)
+ if (this._rows.length === 0)
{
return;
}
const header_elem = this._element.firstElementChild;
const header_cells = header_elem.children;
- const data_cells = first_row.inner().children;
- for (let i = 0; i < data_cells.length && i < header_cells.length; i++)
+
+ // A column is numeric if any data row has right-aligned content in it.
+ for (const row of this._rows)
{
- if (data_cells[i].style.textAlign === "right")
+ const data_cells = row.inner().children;
+ for (let i = 0; i < data_cells.length && i < header_cells.length; i++)
{
- header_cells[i].style.textAlign = "right";
+ if (data_cells[i].style.textAlign === "right")
+ {
+ header_cells[i].style.textAlign = "right";
+ }
}
}
}
diff --git a/src/zenserver/frontend/html/zen.css b/src/zenserver/frontend/html/zen.css
index 74336f0e1..cb3d78cf2 100644
--- a/src/zenserver/frontend/html/zen.css
+++ b/src/zenserver/frontend/html/zen.css
@@ -27,6 +27,7 @@
--theme_bright: #1f2328;
--theme_faint: #6e7781;
--theme_border_subtle: #d8dee4;
+ --theme_highlight: #b8860b44;
}
}
@@ -54,6 +55,7 @@
--theme_bright: #f0f6fc;
--theme_faint: #6e7681;
--theme_border_subtle: #21262d;
+ --theme_highlight: #e3b341aa;
}
}
@@ -81,6 +83,7 @@
--theme_bright: #1f2328;
--theme_faint: #6e7781;
--theme_border_subtle: #d8dee4;
+ --theme_highlight: #b8860b44;
}
:root[data-theme="dark"] {
@@ -106,6 +109,7 @@
--theme_bright: #f0f6fc;
--theme_faint: #6e7681;
--theme_border_subtle: #21262d;
+ --theme_highlight: #e3b341aa;
}
/* theme toggle ------------------------------------------------------------- */
@@ -214,34 +218,6 @@ button {
}
}
-/* service nav -------------------------------------------------------------- */
-
-#service_nav {
- display: flex;
- align-items: center;
- gap: 4px;
- margin-bottom: 16px;
- padding: 4px;
- background-color: var(--theme_g3);
- border: 1px solid var(--theme_g2);
- border-radius: 6px;
-
- a {
- padding: 6px 14px;
- border-radius: 4px;
- font-size: 13px;
- font-weight: 500;
- color: var(--theme_g1);
- text-decoration: none;
- transition: color 0.15s, background 0.15s;
- }
-
- a:hover {
- background-color: var(--theme_p4);
- color: var(--theme_g0);
- text-decoration: none;
- }
-}
/* links -------------------------------------------------------------------- */
@@ -358,6 +334,207 @@ a {
}
}
+/* sessions ----------------------------------------------------------------- */
+
+.sessions-section {
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 80px);
+}
+
+.sessions-layout {
+ display: flex;
+ gap: 1.5em;
+ align-items: flex-start;
+ flex-shrink: 0;
+}
+
+.sessions-table {
+ flex: 1;
+ min-width: 0;
+}
+
+.sessions-table .zen_table > div > div {
+ text-align: right;
+}
+
+.sessions-table .zen_table > div > div:nth-child(2) {
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+}
+
+.sessions-detail {
+ width: 600px;
+ flex-shrink: 0;
+ font-size: 13px;
+}
+
+.sessions-detail h3 {
+ margin: 0 0 0.6em 0;
+ font-size: 13px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: var(--theme_g1);
+}
+
+.sessions-detail .zen_table {
+ margin-bottom: 1em;
+}
+
+.sessions-detail-placeholder {
+ color: var(--theme_g1);
+ font-style: italic;
+}
+
+.sessions-selected {
+ background-color: var(--theme_p3) !important;
+}
+
+.sessions-log-panel {
+ margin-top: 12px;
+ border: 1px solid var(--theme_g3);
+ border-radius: 6px;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 200px;
+}
+.sessions-log-header {
+ display: flex;
+ align-items: center;
+ padding: 6px 12px;
+ background-color: var(--theme_bg1);
+ border-bottom: 1px solid var(--theme_g3);
+ flex-shrink: 0;
+}
+.sessions-log-title {
+ font-size: 12px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ color: var(--theme_g1);
+}
+.sessions-log-filter {
+ margin-left: 12px;
+ padding: 6px 12px;
+ font-size: 14px;
+ font-family: inherit;
+ border: 1px solid var(--theme_g2);
+ border-radius: 6px;
+ background: var(--theme_bg1);
+ color: var(--theme_bright);
+ outline: none;
+ width: 200px;
+}
+.sessions-log-filter:focus {
+ border-color: var(--theme_ln);
+ background: var(--theme_bg0);
+}
+.sessions-log-filter::placeholder {
+ color: var(--theme_g1);
+}
+.sessions-log-body {
+ flex: 1;
+ min-height: 0;
+ overflow-y: auto;
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 12px;
+ line-height: 1.5;
+ padding: 4px 0;
+ background-color: var(--theme_bg0);
+}
+.sessions-log-empty {
+ color: var(--theme_g1);
+ font-style: italic;
+ padding: 8px 12px;
+ font-family: inherit;
+}
+.sessions-log-trimmed {
+ color: var(--theme_g1);
+ font-style: italic;
+ padding: 2px 12px;
+ font-size: 11px;
+}
+.sessions-log-line {
+ padding: 0 12px;
+ white-space: pre;
+ display: flex;
+ gap: 8px;
+}
+.sessions-log-line:hover {
+ background-color: var(--theme_bg1);
+}
+.sessions-log-ts {
+ color: var(--theme_g1);
+ flex-shrink: 0;
+}
+.sessions-log-level {
+ flex-shrink: 0;
+ min-width: 4em;
+ font-weight: 600;
+}
+.sessions-log-level-info { color: var(--theme_ln); }
+.sessions-log-level-warn { color: #d29922; }
+.sessions-log-level-error { color: #f85149; }
+.sessions-log-level-debug { color: var(--theme_g1); }
+.sessions-log-msg {
+ white-space: pre-wrap;
+ word-break: break-all;
+}
+.sessions-log-data {
+ color: var(--theme_g1);
+ white-space: pre-wrap;
+ word-break: break-all;
+}
+
+.sessions-self-pill {
+ display: inline-block;
+ font-size: 0.7em;
+ font-weight: 600;
+ padding: 1px 6px;
+ margin-right: 6px;
+ border-radius: 8px;
+ background-color: var(--theme_p4);
+ color: var(--theme_g0);
+ vertical-align: middle;
+}
+
+.objectstore-bucket-detail {
+ grid-column: 1 / -1;
+ padding: 8px 16px;
+ background-color: var(--theme_bg1);
+ border-top: 1px solid var(--theme_g3);
+ font-size: 0.9em;
+}
+.objectstore-objects-table {
+ width: 100%;
+ border-collapse: collapse;
+}
+.objectstore-objects-table th {
+ text-align: left;
+ font-weight: 600;
+ padding: 4px 8px;
+ border-bottom: 1px solid var(--theme_g3);
+ color: var(--theme_g1);
+ font-size: 0.85em;
+}
+.objectstore-objects-table td {
+ padding: 2px 8px;
+ font-family: var(--font_mono);
+ font-size: 0.85em;
+}
+
+.sessions-pager {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-top: 8px;
+}
+.sessions-pager-label {
+ font-size: 0.85em;
+ opacity: 0.7;
+}
+
/* expandable cell ---------------------------------------------------------- */
.zen_expand_icon {
@@ -471,7 +648,7 @@ a {
border-radius: 6px;
background-color: var(--theme_p4);
border: 1px solid var(--theme_g2);
- width: 6em;
+ min-width: 6em;
cursor: pointer;
font-weight: 500;
transition: background 0.15s;
@@ -486,6 +663,8 @@ a {
padding: 2em;
min-height: 8em;
align-content: center;
+ white-space: pre-wrap;
+ text-align: left;
}
}
@@ -558,6 +737,20 @@ zen-banner {
margin-bottom: 24px;
}
+zen-banner:has(+ zen-nav) {
+ margin-bottom: -1px;
+}
+
+zen-banner:has(+ zen-nav)::part(banner) {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+zen-banner + zen-nav::part(nav-bar) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
/* error -------------------------------------------------------------------- */
#error {
@@ -610,18 +803,21 @@ zen-banner {
/* stats tiles -------------------------------------------------------------- */
-.stats-tiles {
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+.grid.stats-tiles {
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}
.stats-tile {
cursor: pointer;
- transition: border-color 0.15s, background 0.15s;
+ transition: border-color 0.15s;
}
.stats-tile:hover {
border-color: var(--theme_p0);
- background: var(--theme_p4);
+}
+
+.stats-tile[data-over="true"] {
+ border-color: var(--theme_fail);
}
.stats-tile-detailed {
@@ -680,6 +876,81 @@ zen-banner {
font-size: 28px;
}
+/* HTTP summary panel ------------------------------------------------------- */
+
+.stats-http-panel {
+ display: grid;
+ grid-template-columns: 20% 1fr 1fr;
+ align-items: center;
+ margin-bottom: 16px;
+}
+
+.http-title {
+ font-size: 22px;
+ font-weight: 700;
+ color: var(--theme_bright);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ line-height: 1;
+}
+
+.http-section {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ padding: 0 24px;
+ border-left: 1px solid var(--theme_g2);
+}
+
+.http-section-label {
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--theme_g1);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.stats-http-panel .tile-metrics {
+ flex-direction: row;
+ align-items: center;
+ gap: 20px;
+}
+
+/* workspaces page ---------------------------------------------------------- */
+
+.ws-id-wrap {
+ display: inline-flex;
+ align-items: center;
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 14px;
+}
+
+.ws-share-table {
+ width: 100%;
+ margin: 4px 0;
+}
+
+.ws-share-table th {
+ padding: 4px;
+}
+
+.ws-share-table td {
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 13px;
+ padding: 4px;
+}
+
+.ws-share-table td.ws-no-shares-cell {
+ color: var(--theme_g1);
+ font-style: italic;
+ font-family: inherit;
+ padding: 4px 8px;
+}
+
+.module-metrics-row td.ws-detail-cell {
+ padding-left: 24px;
+}
+
/* start -------------------------------------------------------------------- */
#start {
@@ -693,7 +964,7 @@ zen-banner {
/* info --------------------------------------------------------------------- */
-#info {
+#info, #storage, #network {
.info-tiles {
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
@@ -837,7 +1108,7 @@ html:has(#map) {
.card-title {
font-size: 14px;
font-weight: 600;
- color: var(--theme_g1);
+ color: var(--theme_g0);
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
@@ -1081,3 +1352,429 @@ tr:last-child td {
background: var(--theme_g2);
color: var(--theme_bright);
}
+
+/* docs --------------------------------------------------------------------- */
+
+.docs-filter {
+ display: block;
+ width: 100%;
+ max-width: 300px;
+ padding: 8px 12px;
+ font-size: 14px;
+ font-family: inherit;
+ border: 1px solid var(--theme_g2);
+ border-radius: 6px;
+ background: var(--theme_bg1);
+ color: var(--theme_bright);
+ outline: none;
+ margin-bottom: 12px;
+}
+.docs-filter:focus {
+ border-color: var(--theme_ln);
+ background: var(--theme_bg0);
+}
+.docs-filter::placeholder {
+ color: var(--theme_g1);
+}
+.docs-highlight {
+ background: var(--theme_highlight);
+ color: inherit;
+ border-radius: 2px;
+ padding: 0 1px;
+}
+.docs-layout {
+ display: flex;
+ gap: 24px;
+}
+.docs-sidebar {
+ flex-shrink: 0;
+ width: 200px;
+ border-right: 1px solid var(--theme_g3);
+ padding-right: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ position: sticky;
+ top: 16px;
+ align-self: flex-start;
+}
+.docs-sidebar-link {
+ display: block;
+ padding: 6px 10px;
+ font-size: 13px;
+ color: var(--theme_g1);
+ text-decoration: none;
+ border-radius: 4px;
+}
+.docs-sidebar-link:hover {
+ color: var(--theme_g0);
+ background: var(--theme_g4);
+}
+.docs-sidebar-link.active {
+ color: var(--theme_bright);
+ background: var(--theme_g3);
+ font-weight: 500;
+}
+.docs-content {
+ flex: 1;
+ min-width: 0;
+ font-size: 16px;
+ line-height: 1.5;
+ color: var(--theme_g0);
+}
+.docs-content h1 {
+ font-size: 24px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ margin: 0 0 16px 0;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--theme_g3);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+.docs-source-link {
+ font-size: 14px;
+ opacity: 0.4;
+ transition: opacity 0.15s;
+ text-decoration: none;
+}
+.docs-source-link::after {
+ content: "\2197";
+}
+.docs-source-link:hover,
+.docs-github-link:hover {
+ opacity: 1;
+}
+.docs-github-link {
+ font-size: 14px;
+ opacity: 0.4;
+ transition: opacity 0.15s;
+ text-decoration: none;
+}
+.docs-github-link::after {
+ content: "GH";
+ font-size: 10px;
+ font-weight: 700;
+ letter-spacing: -0.5px;
+}
+.docs-section {
+ margin-top: 16px;
+}
+.docs-section-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ cursor: pointer;
+ list-style: none;
+ user-select: none;
+ padding-bottom: 6px;
+ border-bottom: 1px solid var(--theme_g4);
+ margin-bottom: 8px;
+}
+.docs-section-title::-webkit-details-marker {
+ display: none;
+}
+.docs-section-title::before {
+ content: "\25B6";
+ display: inline-block;
+ margin-right: 8px;
+ font-size: 10px;
+ transition: transform 0.15s;
+ color: var(--theme_g1);
+}
+.docs-section[open] > .docs-section-title::before {
+ transform: rotate(90deg);
+}
+.docs-content h2 {
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ margin: 24px 0 8px 0;
+}
+.docs-content h3 {
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--theme_bright);
+ margin: 16px 0 6px 0;
+}
+.docs-content p {
+ margin: 0 0 12px 0;
+}
+.docs-content code {
+ background: var(--theme_bg1);
+ padding: 1px 5px;
+ border-radius: 3px;
+ font-family: 'SF Mono', 'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace;
+ font-size: 0.9em;
+ color: var(--theme_bright);
+}
+.docs-content pre {
+ background: var(--theme_bg1);
+ padding: 12px 16px;
+ border-radius: 6px;
+ overflow-x: auto;
+ margin: 0 0 12px 0;
+}
+.docs-content pre code {
+ background: none;
+ padding: 0;
+}
+.docs-content ul, .docs-content ol {
+ margin: 4px 0 12px 0;
+ padding-left: 24px;
+}
+.docs-content table {
+ border-collapse: collapse;
+ margin: 8px 0 12px 0;
+ font-size: 13px;
+}
+.docs-content th, .docs-content td {
+ border: 1px solid var(--theme_g3);
+ padding: 4px 10px;
+}
+.docs-content th {
+ background: var(--theme_bg1);
+ font-weight: 600;
+ color: var(--theme_bright);
+}
+.docs-content a {
+ color: var(--theme_ln);
+}
+.docs-mermaid {
+ margin: 12px 0;
+ overflow-x: auto;
+}
+.docs-mermaid svg {
+ max-width: 100%;
+ height: auto;
+}
+.docs-loading, .docs-error {
+ color: var(--theme_g1);
+ font-style: italic;
+}
+
+/* module action controls --------------------------------------------------- */
+
+.module-state-dot {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ margin-right: 6px;
+ vertical-align: middle;
+ flex-shrink: 0;
+}
+
+.module-state-dot[data-state="provisioned"] { background: var(--theme_ok); }
+.module-state-dot[data-state="hibernated"] { background: var(--theme_warn); }
+.module-state-dot[data-state="unprovisioned"] { background: var(--theme_g1); }
+.module-state-dot[data-state="crashed"] { background: var(--theme_fail); }
+
+@keyframes module-dot-recovering {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+
+@keyframes module-dot-hibernating {
+ 0%, 59.9% { background: var(--theme_warn); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+@keyframes module-dot-waking {
+ 0%, 59.9% { background: var(--theme_ok); }
+ 60%, 100% { background: var(--theme_warn); }
+}
+@keyframes module-dot-provisioning {
+ 0%, 59.9% { background: var(--theme_ok); }
+ 60%, 100% { background: var(--theme_g1); }
+}
+@keyframes module-dot-deprovisioning-from-provisioned {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_ok); }
+}
+@keyframes module-dot-deprovisioning-from-hibernated {
+ 0%, 59.9% { background: var(--theme_fail); }
+ 60%, 100% { background: var(--theme_warn); }
+}
+
+.module-state-dot[data-state="hibernating"] { animation: module-dot-hibernating 1s steps(1, end) infinite; }
+.module-state-dot[data-state="waking"] { animation: module-dot-waking 1s steps(1, end) infinite; }
+.module-state-dot[data-state="provisioning"] { animation: module-dot-provisioning 1s steps(1, end) infinite; }
+.module-state-dot[data-state="recovering"] { animation: module-dot-recovering 1s steps(1, end) infinite; }
+.module-state-dot[data-state="deprovisioning"][data-prev-state="provisioned"] {
+ animation: module-dot-deprovisioning-from-provisioned 1s steps(1, end) infinite;
+}
+.module-state-dot[data-state="deprovisioning"][data-prev-state="hibernated"] {
+ animation: module-dot-deprovisioning-from-hibernated 1s steps(1, end) infinite;
+}
+.module-state-dot[data-state="deprovisioning"] {
+ animation: module-dot-deprovisioning-from-provisioned 1s steps(1, end) infinite;
+}
+
+.module-action-cell {
+ white-space: nowrap;
+ display: flex;
+ gap: 4px;
+}
+
+.module-action-wrap {
+ display: inline-block;
+ cursor: default;
+}
+
+.module-action-wrap:has(button:disabled) {
+ cursor: default;
+}
+
+.module-action-btn {
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 13px;
+ line-height: 1;
+ padding: 3px 6px;
+ transition: background 0.1s, color 0.1s;
+}
+
+.module-action-btn:not(:disabled):hover {
+ background: var(--theme_g2);
+ color: var(--theme_bright);
+}
+
+.module-action-btn:disabled {
+ color: var(--theme_border_subtle);
+ border-color: var(--theme_border_subtle);
+ pointer-events: none;
+}
+
+.module-bulk-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 5px;
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 4px 10px;
+ color: var(--theme_g1);
+ transition: background 0.1s, color 0.1s;
+}
+
+.module-bulk-btn:not(:disabled):hover {
+ background: var(--theme_p3);
+ color: var(--theme_bright);
+}
+
+.module-bulk-btn:disabled {
+ opacity: 0.4;
+}
+
+.module-bulk-bar {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 10px;
+ margin-bottom: 8px;
+ background: var(--theme_g2);
+ border-radius: 4px;
+ font-size: 12px;
+}
+
+.module-bulk-label {
+ margin-right: 8px;
+ color: var(--theme_g1);
+}
+
+.module-bulk-sep {
+ flex: 1;
+}
+
+.module-pager {
+ position: absolute;
+ right: 0;
+ top: 0;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.module-pager-btn {
+ background: transparent;
+ border: 1px solid var(--theme_g2);
+ border-radius: 4px;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 12px;
+ padding: 4px 10px;
+ transition: background 0.1s, color 0.1s;
+}
+
+.module-pager-btn:not(:disabled):hover {
+ background: var(--theme_g2);
+ color: var(--theme_bright);
+}
+
+.module-pager-btn:disabled {
+ opacity: 0.35;
+ cursor: default;
+}
+
+.module-pager-label {
+ font-size: 12px;
+ color: var(--theme_g1);
+ min-width: 8em;
+ text-align: center;
+}
+
+.module-table td, .module-table th {
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+.module-expand-btn {
+ background: transparent;
+ border: none;
+ color: var(--theme_g1);
+ cursor: pointer;
+ font-size: 16px;
+ line-height: 1;
+ padding: 0 4px 0 0;
+ vertical-align: middle;
+}
+
+.module-expand-btn:hover {
+ color: var(--theme_bright);
+}
+
+.module-metrics-row td {
+ padding: 6px 10px 10px 42px;
+ background: var(--theme_g3);
+ border-bottom: 1px solid var(--theme_g2);
+}
+
+.module-metrics-grid {
+ display: grid;
+ grid-template-columns: max-content minmax(9em, 1fr) max-content minmax(9em, 1fr);
+ gap: 3px 12px;
+ font-size: 11px;
+ font-variant-numeric: tabular-nums;
+}
+
+.module-metrics-label {
+ color: var(--theme_faint);
+ white-space: nowrap;
+}
+
+/* Right-column labels get extra left padding to visually separate the two pairs */
+.module-metrics-label:nth-child(4n+3) {
+ padding-left: 16px;
+}
+
+.module-metrics-value {
+ color: var(--theme_g0);
+ text-align: right;
+}
diff --git a/src/zenserver/frontend/zipfs.cpp b/src/zenserver/frontend/zipfs.cpp
index 42df0520f..c7c8687ca 100644
--- a/src/zenserver/frontend/zipfs.cpp
+++ b/src/zenserver/frontend/zipfs.cpp
@@ -2,6 +2,12 @@
#include "zipfs.h"
+#include <zencore/logging.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <zlib.h>
+ZEN_THIRD_PARTY_INCLUDES_END
+
namespace zen {
//////////////////////////////////////////////////////////////////////////
@@ -126,15 +132,20 @@ ZipFs::ZipFs(IoBuffer&& Buffer)
const CentralDirectoryRecord& Cd = *CdCursor;
bool Acceptable = true;
- Acceptable &= (Cd.OriginalSize > 0); // has some content
- Acceptable &= (Cd.CompressionMethod == 0); // is stored uncomrpessed
+ Acceptable &= (Cd.OriginalSize > 0); // has some content
+ Acceptable &= (Cd.CompressionMethod == 0 || Cd.CompressionMethod == 8); // stored or deflate
if (Acceptable)
{
const uint8_t* Lfh = Cursor + Cd.Offset;
if (uintptr_t(Lfh - Cursor) < View.GetSize())
{
std::string_view FileName(Cd.FileName, Cd.FileNameLength);
- m_Files.insert(std::make_pair(FileName, FileItem{Lfh, size_t(0)}));
+ FileItem Item;
+ Item.View = MemoryView{Lfh, size_t(0)};
+ Item.CompressionMethod = Cd.CompressionMethod;
+ Item.CompressedSize = Cd.CompressedSize;
+ Item.UncompressedSize = Cd.OriginalSize;
+ m_Files.insert(std::make_pair(FileName, std::move(Item)));
}
}
@@ -159,23 +170,59 @@ ZipFs::GetFile(const std::string_view& FileName) const
}
const FileItem& Item = Iter->second;
- if (Item.GetSize() > 0)
+ if (Item.View.GetSize() > 0)
{
- return IoBuffer(IoBuffer::Wrap, Item.GetData(), Item.GetSize());
+ return IoBuffer(IoBuffer::Wrap, Item.View.GetData(), Item.View.GetSize());
}
}
RwLock::ExclusiveLockScope _(m_FilesLock);
FileItem& Item = m_Files.find(FileName)->second;
- if (Item.GetSize() > 0)
+ if (Item.View.GetSize() > 0)
+ {
+ return IoBuffer(IoBuffer::Wrap, Item.View.GetData(), Item.View.GetSize());
+ }
+
+ const auto* Lfh = (LocalFileHeader*)(Item.View.GetData());
+ const uint8_t* FileData = (const uint8_t*)(Lfh->FileName + Lfh->FileNameLength + Lfh->ExtraFieldLength);
+
+ if (Item.CompressionMethod == 0)
+ {
+ // Stored — point directly into the buffer
+ Item.View = MemoryView(FileData, Item.UncompressedSize);
+ }
+ else
{
- return IoBuffer(IoBuffer::Wrap, Item.GetData(), Item.GetSize());
+ // Deflate — decompress using zlib
+ Item.DecompressedData = IoBuffer(Item.UncompressedSize);
+
+ z_stream Stream = {};
+ Stream.next_in = const_cast<Bytef*>(FileData);
+ Stream.avail_in = Item.CompressedSize;
+ Stream.next_out = (Bytef*)Item.DecompressedData.GetMutableView().GetData();
+ Stream.avail_out = Item.UncompressedSize;
+
+ // Use raw inflate (-MAX_WBITS) since zip stores raw deflate streams
+ if (inflateInit2(&Stream, -MAX_WBITS) != Z_OK)
+ {
+ ZEN_WARN("failed to initialize inflate for '{}'", FileName);
+ return {};
+ }
+
+ int Result = inflate(&Stream, Z_FINISH);
+ inflateEnd(&Stream);
+
+ if (Result != Z_STREAM_END)
+ {
+ ZEN_WARN("failed to decompress '{}' (zlib error {})", FileName, Result);
+ return {};
+ }
+
+ Item.View = Item.DecompressedData.GetView();
}
- const auto* Lfh = (LocalFileHeader*)(Item.GetData());
- Item = MemoryView(Lfh->FileName + Lfh->FileNameLength + Lfh->ExtraFieldLength, Lfh->OriginalSize);
- return IoBuffer(IoBuffer::Wrap, Item.GetData(), Item.GetSize());
+ return IoBuffer(IoBuffer::Wrap, Item.View.GetData(), Item.View.GetSize());
}
} // namespace zen
diff --git a/src/zenserver/frontend/zipfs.h b/src/zenserver/frontend/zipfs.h
index 645121693..c6acf7334 100644
--- a/src/zenserver/frontend/zipfs.h
+++ b/src/zenserver/frontend/zipfs.h
@@ -17,8 +17,16 @@ public:
IoBuffer GetFile(const std::string_view& FileName) const;
private:
- using FileItem = MemoryView;
- using FileMap = std::unordered_map<std::string_view, FileItem>;
+ struct FileItem
+ {
+ MemoryView View; // Initially points to LFH (size=0); resolved to file data on first access
+ uint32_t CompressedSize = 0;
+ uint32_t UncompressedSize = 0;
+ uint16_t CompressionMethod = 0;
+ IoBuffer DecompressedData; // Owns decompressed buffer for deflate entries
+ };
+
+ using FileMap = std::unordered_map<std::string_view, FileItem>;
mutable RwLock m_FilesLock;
FileMap mutable m_Files;
IoBuffer m_Buffer;
diff --git a/src/zenserver/frontend/zipfs_test.cpp b/src/zenserver/frontend/zipfs_test.cpp
new file mode 100644
index 000000000..b5937b71c
--- /dev/null
+++ b/src/zenserver/frontend/zipfs_test.cpp
@@ -0,0 +1,214 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "zipfs.h"
+
+#include <zencore/iobuffer.h>
+
+#if ZEN_WITH_TESTS
+
+ZEN_THIRD_PARTY_INCLUDES_START
+# include <doctest/doctest.h>
+# include <zlib.h>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+# include <cstring>
+# include <vector>
+
+TEST_SUITE_BEGIN("server.zipfs");
+
+namespace {
+
+// Helpers to build a minimal zip file in memory
+struct ZipBuilder
+{
+ std::vector<uint8_t> Data;
+
+ struct Entry
+ {
+ std::string Name;
+ uint32_t LocalHeaderOffset;
+ uint16_t CompressionMethod;
+ uint32_t CompressedSize;
+ uint32_t UncompressedSize;
+ };
+
+ std::vector<Entry> Entries;
+
+ void Append(const void* Src, size_t Size)
+ {
+ const uint8_t* Bytes = (const uint8_t*)Src;
+ Data.insert(Data.end(), Bytes, Bytes + Size);
+ }
+
+ void AppendU16(uint16_t V) { Append(&V, 2); }
+ void AppendU32(uint32_t V) { Append(&V, 4); }
+
+ void AddFile(const std::string& Name, const void* Content, size_t ContentSize, bool Deflate)
+ {
+ std::vector<uint8_t> FileData;
+ uint16_t Method = 0;
+
+ if (Deflate)
+ {
+ // Compress with raw deflate (no zlib/gzip header)
+ uLongf BoundSize = compressBound((uLong)ContentSize);
+ std::vector<uint8_t> TempBuf(BoundSize);
+
+ z_stream Stream = {};
+ Stream.next_in = (Bytef*)Content;
+ Stream.avail_in = (uInt)ContentSize;
+ Stream.next_out = TempBuf.data();
+ Stream.avail_out = (uInt)TempBuf.size();
+
+ deflateInit2(&Stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
+ deflate(&Stream, Z_FINISH);
+ deflateEnd(&Stream);
+
+ TempBuf.resize(Stream.total_out);
+ FileData = std::move(TempBuf);
+ Method = 8;
+ }
+ else
+ {
+ FileData.assign((const uint8_t*)Content, (const uint8_t*)Content + ContentSize);
+ }
+
+ Entry E;
+ E.Name = Name;
+ E.LocalHeaderOffset = (uint32_t)Data.size();
+ E.CompressionMethod = Method;
+ E.CompressedSize = (uint32_t)FileData.size();
+ E.UncompressedSize = (uint32_t)ContentSize;
+ Entries.push_back(E);
+
+ // Local file header
+ AppendU32(0x04034b50); // signature
+ AppendU16(20); // version needed
+ AppendU16(0); // flags
+ AppendU16(Method); // compression method
+ AppendU16(0); // last mod time
+ AppendU16(0); // last mod date
+ AppendU32(0); // crc32 (not validated by ZipFs)
+ AppendU32(E.CompressedSize); // compressed size
+ AppendU32(E.UncompressedSize); // uncompressed size
+ AppendU16((uint16_t)Name.size()); // file name length
+ AppendU16(0); // extra field length
+ Append(Name.data(), Name.size()); // file name
+ Append(FileData.data(), FileData.size());
+ }
+
+ zen::IoBuffer Build()
+ {
+ uint32_t CdOffset = (uint32_t)Data.size();
+
+ for (const Entry& E : Entries)
+ {
+ // Central directory record
+ AppendU32(0x02014b50); // signature
+ AppendU16(20); // version made by
+ AppendU16(20); // version needed
+ AppendU16(0); // flags
+ AppendU16(E.CompressionMethod); // compression method
+ AppendU16(0); // last mod time
+ AppendU16(0); // last mod date
+ AppendU32(0); // crc32
+ AppendU32(E.CompressedSize); // compressed size
+ AppendU32(E.UncompressedSize); // uncompressed size
+ AppendU16((uint16_t)E.Name.size()); // file name length
+ AppendU16(0); // extra field length
+ AppendU16(0); // comment length
+ AppendU16(0); // disk index
+ AppendU16(0); // internal file attr
+ AppendU32(0); // external file attr
+ AppendU32(E.LocalHeaderOffset); // offset
+ Append(E.Name.data(), E.Name.size());
+ }
+
+ uint32_t CdSize = (uint32_t)Data.size() - CdOffset;
+
+ // End of central directory record
+ AppendU32(0x06054b50); // signature
+ AppendU16(0); // this disk
+ AppendU16(0); // cd start disk
+ AppendU16((uint16_t)Entries.size()); // cd records this disk
+ AppendU16((uint16_t)Entries.size()); // cd records total
+ AppendU32(CdSize); // cd size
+ AppendU32(CdOffset); // cd offset
+ AppendU16(0); // comment length
+
+ zen::IoBuffer Buffer(Data.size());
+ std::memcpy(Buffer.GetMutableView().GetData(), Data.data(), Data.size());
+ return Buffer;
+ }
+};
+
+} // namespace
+
+TEST_CASE("zipfs.stored")
+{
+ const char* Content = "Hello, World!";
+
+ ZipBuilder Zip;
+ Zip.AddFile("test.txt", Content, std::strlen(Content), false);
+
+ zen::ZipFs Fs(Zip.Build());
+
+ zen::IoBuffer Result = Fs.GetFile("test.txt");
+ REQUIRE(Result);
+ CHECK(Result.GetView().GetSize() == std::strlen(Content));
+ CHECK(std::memcmp(Result.GetView().GetData(), Content, std::strlen(Content)) == 0);
+}
+
+TEST_CASE("zipfs.deflate")
+{
+ const char* Content = "This is some content that will be deflate compressed in the zip file.";
+
+ ZipBuilder Zip;
+ Zip.AddFile("compressed.txt", Content, std::strlen(Content), true);
+
+ zen::ZipFs Fs(Zip.Build());
+
+ zen::IoBuffer Result = Fs.GetFile("compressed.txt");
+ REQUIRE(Result);
+ CHECK(Result.GetView().GetSize() == std::strlen(Content));
+ CHECK(std::memcmp(Result.GetView().GetData(), Content, std::strlen(Content)) == 0);
+}
+
+TEST_CASE("zipfs.mixed")
+{
+ const char* StoredContent = "stored content";
+ const char* DeflateContent = "deflate content that is compressed";
+
+ ZipBuilder Zip;
+ Zip.AddFile("stored.txt", StoredContent, std::strlen(StoredContent), false);
+ Zip.AddFile("deflated.txt", DeflateContent, std::strlen(DeflateContent), true);
+
+ zen::ZipFs Fs(Zip.Build());
+
+ zen::IoBuffer Stored = Fs.GetFile("stored.txt");
+ REQUIRE(Stored);
+ CHECK(Stored.GetView().GetSize() == std::strlen(StoredContent));
+ CHECK(std::memcmp(Stored.GetView().GetData(), StoredContent, std::strlen(StoredContent)) == 0);
+
+ zen::IoBuffer Deflated = Fs.GetFile("deflated.txt");
+ REQUIRE(Deflated);
+ CHECK(Deflated.GetView().GetSize() == std::strlen(DeflateContent));
+ CHECK(std::memcmp(Deflated.GetView().GetData(), DeflateContent, std::strlen(DeflateContent)) == 0);
+}
+
+TEST_CASE("zipfs.not_found")
+{
+ const char* Content = "data";
+
+ ZipBuilder Zip;
+ Zip.AddFile("exists.txt", Content, std::strlen(Content), false);
+
+ zen::ZipFs Fs(Zip.Build());
+
+ zen::IoBuffer Result = Fs.GetFile("missing.txt");
+ CHECK(!Result);
+}
+
+TEST_SUITE_END();
+
+#endif // ZEN_WITH_TESTS
diff --git a/src/zenserver/hub/httphubservice.cpp b/src/zenserver/hub/httphubservice.cpp
index 67ed0cfd8..eba816793 100644
--- a/src/zenserver/hub/httphubservice.cpp
+++ b/src/zenserver/hub/httphubservice.cpp
@@ -2,16 +2,53 @@
#include "httphubservice.h"
+#include "httpproxyhandler.h"
#include "hub.h"
#include "storageserverinstance.h"
#include <zencore/compactbinarybuilder.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
+#include <zenhttp/httpstats.h>
namespace zen {
-HttpHubService::HttpHubService(Hub& Hub) : m_Hub(Hub)
+namespace {
+ bool HandleFailureResults(HttpServerRequest& Request, const Hub::Response& Resp)
+ {
+ if (Resp.ResponseCode == Hub::EResponseCode::Rejected)
+ {
+ if (Resp.Message.empty())
+ {
+ Request.WriteResponse(HttpResponseCode::Conflict);
+ }
+ else
+ {
+ Request.WriteResponse(HttpResponseCode::Conflict, HttpContentType::kText, Resp.Message);
+ }
+ return true;
+ }
+ if (Resp.ResponseCode == Hub::EResponseCode::NotFound)
+ {
+ if (Resp.Message.empty())
+ {
+ Request.WriteResponse(HttpResponseCode::NotFound);
+ }
+ else
+ {
+ Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, Resp.Message);
+ }
+ return true;
+ }
+ return false;
+ }
+} // namespace
+
+HttpHubService::HttpHubService(Hub& Hub, HttpProxyHandler& Proxy, HttpStatsService& StatsService, HttpStatusService& StatusService)
+: m_Hub(Hub)
+, m_StatsService(StatsService)
+, m_StatusService(StatusService)
+, m_Proxy(Proxy)
{
using namespace std::literals;
@@ -32,15 +69,50 @@ HttpHubService::HttpHubService(Hub& Hub) : m_Hub(Hub)
return true;
});
+ m_Router.AddMatcher("port", [](std::string_view Str) -> bool {
+ if (Str.empty())
+ {
+ return false;
+ }
+ for (const auto C : Str)
+ {
+ if (!std::isdigit(C))
+ {
+ return false;
+ }
+ }
+ return true;
+ });
+
+ m_Router.AddMatcher("proxypath", [](std::string_view Str) -> bool { return !Str.empty(); });
+
m_Router.RegisterRoute(
"status",
[this](HttpRouterRequest& Req) {
CbObjectWriter Obj;
Obj.BeginArray("modules");
- m_Hub.EnumerateModules([&Obj](StorageServerInstance& Instance) {
+ m_Hub.EnumerateModules([&Obj](std::string_view ModuleId, const Hub::InstanceInfo& Info) {
Obj.BeginObject();
- Obj << "moduleId" << Instance.GetModuleId();
- Obj << "provisioned" << Instance.IsProvisioned();
+ {
+ Obj << "moduleId" << ModuleId;
+ Obj << "state" << ToString(Info.State);
+ Obj << "port" << Info.Port;
+ if (Info.StateChangeTime != std::chrono::system_clock::time_point::min())
+ {
+ Obj << "state_change_time" << ToDateTime(Info.StateChangeTime);
+ }
+ Obj.BeginObject("process_metrics");
+ {
+ Obj << "MemoryBytes" << Info.Metrics.MemoryBytes;
+ Obj << "KernelTimeMs" << Info.Metrics.KernelTimeMs;
+ Obj << "UserTimeMs" << Info.Metrics.UserTimeMs;
+ Obj << "WorkingSetSize" << Info.Metrics.WorkingSetSize;
+ Obj << "PeakWorkingSetSize" << Info.Metrics.PeakWorkingSetSize;
+ Obj << "PagefileUsage" << Info.Metrics.PagefileUsage;
+ Obj << "PeakPagefileUsage" << Info.Metrics.PeakPagefileUsage;
+ }
+ Obj.EndObject();
+ }
Obj.EndObject();
});
Obj.EndArray();
@@ -69,89 +141,143 @@ HttpHubService::HttpHubService(Hub& Hub) : m_Hub(Hub)
[this](HttpRouterRequest& Req) {
std::string_view ModuleId = Req.GetCapture(1);
- std::string FailureReason = "unknown";
- HttpResponseCode ResponseCode = HttpResponseCode::OK;
-
try
{
HubProvisionedInstanceInfo Info;
- if (m_Hub.Provision(ModuleId, /* out */ Info, /* out */ FailureReason))
- {
- CbObjectWriter Obj;
- Obj << "moduleId" << ModuleId;
- Obj << "baseUri" << Info.BaseUri;
- Obj << "port" << Info.Port;
- Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ Hub::Response Resp = m_Hub.Provision(ModuleId, Info);
- return;
- }
- else
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
{
- ResponseCode = HttpResponseCode::BadRequest;
+ return;
}
+
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
+ CbObjectWriter Obj;
+ Obj << "moduleId" << ModuleId;
+ Obj << "baseUri" << Info.BaseUri;
+ Obj << "port" << Info.Port;
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while provisioning module '{}': {}", ModuleId, Ex.what());
-
- FailureReason = Ex.what();
- ResponseCode = HttpResponseCode::InternalServerError;
+ throw;
}
-
- Req.ServerRequest().WriteResponse(ResponseCode, HttpContentType::kText, FailureReason);
},
HttpVerb::kPost);
m_Router.RegisterRoute(
"modules/{moduleid}/deprovision",
[this](HttpRouterRequest& Req) {
- std::string_view ModuleId = Req.GetCapture(1);
- std::string FailureReason = "unknown";
+ std::string_view ModuleId = Req.GetCapture(1);
try
{
- if (!m_Hub.Deprovision(std::string(ModuleId), /* out */ FailureReason))
+ Hub::Response Resp = m_Hub.Deprovision(std::string(ModuleId));
+
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
{
- if (FailureReason.empty())
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
- }
- else
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, FailureReason);
- }
+ return;
}
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
CbObjectWriter Obj;
Obj << "moduleId" << ModuleId;
-
- return Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while deprovisioning module '{}': {}", ModuleId, Ex.what());
+ throw;
+ }
+ },
+ HttpVerb::kPost);
- FailureReason = Ex.what();
+ m_Router.RegisterRoute(
+ "modules/{moduleid}/hibernate",
+ [this](HttpRouterRequest& Req) {
+ std::string_view ModuleId = Req.GetCapture(1);
+
+ try
+ {
+ Hub::Response Resp = m_Hub.Hibernate(std::string(ModuleId));
+
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
+ {
+ return;
+ }
+
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
+ CbObjectWriter Obj;
+ Obj << "moduleId" << ModuleId;
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Exception while hibernating module '{}': {}", ModuleId, Ex.what());
+ throw;
+ }
+ },
+ HttpVerb::kPost);
+
+ m_Router.RegisterRoute(
+ "modules/{moduleid}/wake",
+ [this](HttpRouterRequest& Req) {
+ std::string_view ModuleId = Req.GetCapture(1);
+
+ try
+ {
+ Hub::Response Resp = m_Hub.Wake(std::string(ModuleId));
+
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
+ {
+ return;
+ }
- Req.ServerRequest().WriteResponse(HttpResponseCode::InternalServerError, HttpContentType::kText, FailureReason);
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
+ CbObjectWriter Obj;
+ Obj << "moduleId" << ModuleId;
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Exception while waking module '{}': {}", ModuleId, Ex.what());
+ throw;
+ }
},
HttpVerb::kPost);
m_Router.RegisterRoute(
- "stats",
+ "proxy/{port}/{proxypath}",
[this](HttpRouterRequest& Req) {
- CbObjectWriter Obj;
- Obj << "currentInstanceCount" << m_Hub.GetInstanceCount();
- Obj << "maxInstanceCount" << m_Hub.GetMaxInstanceCount();
- Obj << "instanceLimit" << m_Hub.GetConfig().InstanceLimit;
- Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ std::string_view PortStr = Req.GetCapture(1);
+
+ // Use RelativeUriWithExtension to preserve the file extension that the
+ // router's URI parser strips (e.g. ".css", ".js") - the upstream server
+ // needs the full path including the extension.
+ std::string_view FullUri = Req.ServerRequest().RelativeUriWithExtension();
+ std::string_view Prefix = "proxy/";
+
+ // FullUri is "proxy/{port}/{path...}" - skip past "proxy/{port}/"
+ size_t PathStart = Prefix.size() + PortStr.size() + 1;
+ std::string_view PathTail = (PathStart < FullUri.size()) ? FullUri.substr(PathStart) : std::string_view{};
+
+ m_Proxy.HandleProxyRequest(Req.ServerRequest(), PortStr, PathTail);
},
- HttpVerb::kGet);
+ HttpVerb::kGet | HttpVerb::kPost | HttpVerb::kPut | HttpVerb::kDelete | HttpVerb::kHead);
+
+ m_StatsService.RegisterHandler("hub", *this);
+ m_StatusService.RegisterHandler("hub", *this);
}
HttpHubService::~HttpHubService()
{
+ m_StatusService.UnregisterHandler("hub", *this);
+ m_StatsService.UnregisterHandler("hub", *this);
}
const char*
@@ -168,46 +294,158 @@ HttpHubService::SetNotificationEndpoint(std::string_view UpstreamNotificationEnd
}
void
-HttpHubService::HandleRequest(zen::HttpServerRequest& Request)
+HttpHubService::HandleRequest(HttpServerRequest& Request)
+{
+ using namespace std::literals;
+
+ metrics::OperationTiming::Scope $(m_HttpRequests);
+ if (m_Router.HandleRequest(Request) == false)
+ {
+ ZEN_WARN("No route found for {0}", Request.RelativeUri());
+ return Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, "Not found"sv);
+ }
+}
+
+void
+HttpHubService::HandleStatusRequest(HttpServerRequest& Request)
{
- m_Router.HandleRequest(Request);
+ CbObjectWriter Cbo;
+ Cbo << "ok" << true;
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+void
+HttpHubService::HandleStatsRequest(HttpServerRequest& Request)
+{
+ CbObjectWriter Cbo;
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+
+ Cbo << "currentInstanceCount" << m_Hub.GetInstanceCount();
+ Cbo << "maxInstanceCount" << m_Hub.GetMaxInstanceCount();
+ Cbo << "instanceLimit" << m_Hub.GetConfig().InstanceLimit;
+
+ SystemMetrics SysMetrics;
+ DiskSpace Disk;
+ m_Hub.GetMachineMetrics(SysMetrics, Disk);
+ Cbo.BeginObject("machine");
+ {
+ Cbo << "disk_free_bytes" << Disk.Free;
+ Cbo << "disk_total_bytes" << Disk.Total;
+ Cbo << "memory_avail_mib" << SysMetrics.AvailSystemMemoryMiB;
+ Cbo << "memory_total_mib" << SysMetrics.SystemMemoryMiB;
+ Cbo << "virtual_memory_avail_mib" << SysMetrics.AvailVirtualMemoryMiB;
+ Cbo << "virtual_memory_total_mib" << SysMetrics.VirtualMemoryMiB;
+ }
+ Cbo.EndObject();
+
+ const ResourceMetrics& Limits = m_Hub.GetConfig().ResourceLimits;
+ Cbo.BeginObject("resource_limits");
+ {
+ Cbo << "disk_bytes" << Limits.DiskUsageBytes;
+ Cbo << "memory_bytes" << Limits.MemoryUsageBytes;
+ }
+ Cbo.EndObject();
+
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+CbObject
+HttpHubService::CollectStats()
+{
+ CbObjectWriter Cbo;
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+
+ Cbo << "currentInstanceCount" << m_Hub.GetInstanceCount();
+ Cbo << "maxInstanceCount" << m_Hub.GetMaxInstanceCount();
+ Cbo << "instanceLimit" << m_Hub.GetConfig().InstanceLimit;
+
+ return Cbo.Save();
+}
+
+uint64_t
+HttpHubService::GetActivityCounter()
+{
+ return m_HttpRequests.Count();
}
void
HttpHubService::HandleModuleGet(HttpServerRequest& Request, std::string_view ModuleId)
{
- StorageServerInstance* Instance = nullptr;
- if (!m_Hub.Find(ModuleId, &Instance))
+ Hub::InstanceInfo InstanceInfo;
+ if (!m_Hub.Find(ModuleId, &InstanceInfo))
{
Request.WriteResponse(HttpResponseCode::NotFound);
return;
}
- // TODO: A separate http request for the modules/{moduleid}/deprovision endpoint can be called and deprovision the instance leaving us
- // with a dangling pointer...
-
CbObjectWriter Obj;
- Obj << "moduleId" << Instance->GetModuleId();
- Obj << "provisioned" << Instance->IsProvisioned();
+ Obj << "moduleId" << ModuleId;
+ Obj << "state" << ToString(InstanceInfo.State);
Request.WriteResponse(HttpResponseCode::OK, Obj.Save());
}
void
HttpHubService::HandleModuleDelete(HttpServerRequest& Request, std::string_view ModuleId)
{
- StorageServerInstance* Instance = nullptr;
- if (!m_Hub.Find(ModuleId, &Instance))
+ Hub::InstanceInfo InstanceInfo;
+ if (!m_Hub.Find(ModuleId, &InstanceInfo))
{
Request.WriteResponse(HttpResponseCode::NotFound);
return;
}
- // TODO: deprovision and nuke all related storage
+ if (InstanceInfo.State == HubInstanceState::Provisioned || InstanceInfo.State == HubInstanceState::Hibernated ||
+ InstanceInfo.State == HubInstanceState::Crashed)
+ {
+ try
+ {
+ Hub::Response Resp = m_Hub.Deprovision(std::string(ModuleId));
+
+ if (HandleFailureResults(Request, Resp))
+ {
+ return;
+ }
+
+ // TODO: nuke all related storage
+
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
+ CbObjectWriter Obj;
+ Obj << "moduleId" << ModuleId;
+ return Request.WriteResponse(HttpCode, Obj.Save());
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Exception while deprovisioning module '{}': {}", ModuleId, Ex.what());
+ throw;
+ }
+ }
+
+ // TODO: nuke all related storage
CbObjectWriter Obj;
- Obj << "moduleId" << Instance->GetModuleId();
- Obj << "provisioned" << Instance->IsProvisioned();
+ Obj << "moduleId" << ModuleId;
Request.WriteResponse(HttpResponseCode::OK, Obj.Save());
}
+void
+HttpHubService::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
+{
+ m_Proxy.OnWebSocketOpen(std::move(Connection), RelativeUri);
+}
+
+void
+HttpHubService::OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg)
+{
+ m_Proxy.OnWebSocketMessage(Conn, Msg);
+}
+
+void
+HttpHubService::OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason)
+{
+ m_Proxy.OnWebSocketClose(Conn, Code, Reason);
+}
+
} // namespace zen
diff --git a/src/zenserver/hub/httphubservice.h b/src/zenserver/hub/httphubservice.h
index d08eeea2a..ff2cb0029 100644
--- a/src/zenserver/hub/httphubservice.h
+++ b/src/zenserver/hub/httphubservice.h
@@ -2,10 +2,17 @@
#pragma once
+#include <zencore/thread.h>
#include <zenhttp/httpserver.h>
+#include <zenhttp/httpstatus.h>
+#include <zenhttp/websocket.h>
+
+#include <memory>
namespace zen {
+class HttpProxyHandler;
+class HttpStatsService;
class Hub;
/** ZenServer Hub Service
@@ -14,27 +21,42 @@ class Hub;
* use in UEFN content worker style scenarios.
*
*/
-class HttpHubService : public zen::HttpService
+class HttpHubService : public HttpService, public IHttpStatusProvider, public IHttpStatsProvider, public IWebSocketHandler
{
public:
- HttpHubService(Hub& Hub);
+ HttpHubService(Hub& Hub, HttpProxyHandler& Proxy, HttpStatsService& StatsService, HttpStatusService& StatusService);
~HttpHubService();
HttpHubService(const HttpHubService&) = delete;
HttpHubService& operator=(const HttpHubService&) = delete;
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
+
+ // IWebSocketHandler
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override;
+ void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg) override;
+ void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason) override;
void SetNotificationEndpoint(std::string_view UpstreamNotificationEndpoint, std::string_view InstanceId);
private:
- HttpRequestRouter m_Router;
-
Hub& m_Hub;
+ HttpRequestRouter m_Router;
+ metrics::OperationTiming m_HttpRequests;
+
+ HttpStatsService& m_StatsService;
+ HttpStatusService& m_StatusService;
+
void HandleModuleGet(HttpServerRequest& Request, std::string_view ModuleId);
void HandleModuleDelete(HttpServerRequest& Request, std::string_view ModuleId);
+
+ HttpProxyHandler& m_Proxy;
};
} // namespace zen
diff --git a/src/zenserver/hub/httpproxyhandler.cpp b/src/zenserver/hub/httpproxyhandler.cpp
new file mode 100644
index 000000000..25842623a
--- /dev/null
+++ b/src/zenserver/hub/httpproxyhandler.cpp
@@ -0,0 +1,504 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "httpproxyhandler.h"
+
+#include <zencore/fmtutils.h>
+#include <zencore/logging.h>
+#include <zencore/string.h>
+#include <zenhttp/httpclient.h>
+#include <zenhttp/httpwsclient.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <fmt/format.h>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+#include <charconv>
+
+#if ZEN_WITH_TESTS
+# include <zencore/testing.h>
+#endif // ZEN_WITH_TESTS
+
+namespace zen {
+
+namespace {
+
+ std::string InjectProxyScript(std::string_view Html, uint16_t Port)
+ {
+ ExtendableStringBuilder<2048> Script;
+ Script.Append("<script>\n(function(){\n var P = \"/hub/proxy/");
+ Script.Append(fmt::format("{}", Port));
+ Script.Append(
+ "\";\n"
+ " var OF = window.fetch;\n"
+ " window.fetch = function(u, o) {\n"
+ " if (typeof u === \"string\") {\n"
+ " try {\n"
+ " var p = new URL(u, location.origin);\n"
+ " if (p.origin === location.origin && !p.pathname.startsWith(P))\n"
+ " { p.pathname = P + p.pathname; u = p.toString(); }\n"
+ " } catch(e) {\n"
+ " if (u.startsWith(\"/\") && !u.startsWith(P)) u = P + u;\n"
+ " }\n"
+ " }\n"
+ " return OF.call(this, u, o);\n"
+ " };\n"
+ " var OW = window.WebSocket;\n"
+ " window.WebSocket = function(u, pr) {\n"
+ " try {\n"
+ " var p = new URL(u);\n"
+ " if (p.hostname === location.hostname\n"
+ " && String(p.port || (p.protocol === \"wss:\" ? \"443\" : \"80\"))\n"
+ " === String(location.port || (location.protocol === \"https:\" ? \"443\" : \"80\"))\n"
+ " && !p.pathname.startsWith(P))\n"
+ " { p.pathname = P + p.pathname; u = p.toString(); }\n"
+ " } catch(e) {}\n"
+ " return pr !== undefined ? new OW(u, pr) : new OW(u);\n"
+ " };\n"
+ " window.WebSocket.prototype = OW.prototype;\n"
+ " window.WebSocket.CONNECTING = OW.CONNECTING;\n"
+ " window.WebSocket.OPEN = OW.OPEN;\n"
+ " window.WebSocket.CLOSING = OW.CLOSING;\n"
+ " window.WebSocket.CLOSED = OW.CLOSED;\n"
+ " var OO = window.open;\n"
+ " window.open = function(u, t, f) {\n"
+ " if (typeof u === \"string\") {\n"
+ " try {\n"
+ " var p = new URL(u, location.origin);\n"
+ " if (p.origin === location.origin && !p.pathname.startsWith(P))\n"
+ " { p.pathname = P + p.pathname; u = p.toString(); }\n"
+ " } catch(e) {}\n"
+ " }\n"
+ " return OO.call(this, u, t, f);\n"
+ " };\n"
+ " document.addEventListener(\"click\", function(e) {\n"
+ " var t = e.composedPath ? e.composedPath()[0] : e.target;\n"
+ " while (t && t.tagName !== \"A\") t = t.parentNode || t.host;\n"
+ " if (!t || !t.href) return;\n"
+ " try {\n"
+ " var h = new URL(t.href);\n"
+ " if (h.origin === location.origin && !h.pathname.startsWith(P))\n"
+ " { h.pathname = P + h.pathname; e.preventDefault(); window.location.href = h.toString(); }\n"
+ " } catch(x) {}\n"
+ " }, true);\n"
+ "})();\n</script>");
+
+ std::string ScriptStr = Script.ToString();
+
+ size_t HeadClose = Html.find("</head>");
+ if (HeadClose != std::string_view::npos)
+ {
+ std::string Result;
+ Result.reserve(Html.size() + ScriptStr.size());
+ Result.append(Html.substr(0, HeadClose));
+ Result.append(ScriptStr);
+ Result.append(Html.substr(HeadClose));
+ return Result;
+ }
+
+ std::string Result;
+ Result.reserve(Html.size() + ScriptStr.size());
+ Result.append(ScriptStr);
+ Result.append(Html);
+ return Result;
+ }
+
+} // namespace
+
+struct HttpProxyHandler::WsBridge : public RefCounted, public IWsClientHandler
+{
+ Ref<WebSocketConnection> ClientConn;
+ std::unique_ptr<HttpWsClient> UpstreamClient;
+ uint16_t Port = 0;
+
+ void OnWsOpen() override {}
+
+ void OnWsMessage(const WebSocketMessage& Msg) override
+ {
+ if (!ClientConn->IsOpen())
+ {
+ return;
+ }
+ switch (Msg.Opcode)
+ {
+ case WebSocketOpcode::kText:
+ ClientConn->SendText(std::string_view(static_cast<const char*>(Msg.Payload.GetData()), Msg.Payload.GetSize()));
+ break;
+ case WebSocketOpcode::kBinary:
+ ClientConn->SendBinary(std::span<const uint8_t>(static_cast<const uint8_t*>(Msg.Payload.GetData()), Msg.Payload.GetSize()));
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnWsClose(uint16_t Code, std::string_view Reason) override
+ {
+ if (ClientConn->IsOpen())
+ {
+ ClientConn->Close(Code, Reason);
+ }
+ }
+};
+
+HttpProxyHandler::HttpProxyHandler()
+{
+}
+
+HttpProxyHandler::HttpProxyHandler(PortValidator ValidatePort) : m_ValidatePort(std::move(ValidatePort))
+{
+}
+
+void
+HttpProxyHandler::SetPortValidator(PortValidator ValidatePort)
+{
+ m_ValidatePort = std::move(ValidatePort);
+}
+
+HttpProxyHandler::~HttpProxyHandler()
+{
+ try
+ {
+ Shutdown();
+ }
+ catch (...)
+ {
+ }
+}
+
+HttpClient&
+HttpProxyHandler::GetOrCreateProxyClient(uint16_t Port)
+{
+ HttpClient* Result = nullptr;
+ m_ProxyClientsLock.WithExclusiveLock([&] {
+ auto It = m_ProxyClients.find(Port);
+ if (It == m_ProxyClients.end())
+ {
+ HttpClientSettings Settings;
+ Settings.LogCategory = "hub-proxy";
+ Settings.ConnectTimeout = std::chrono::milliseconds(5000);
+ Settings.Timeout = std::chrono::milliseconds(30000);
+ auto Client = std::make_unique<HttpClient>(fmt::format("http://127.0.0.1:{}", Port), Settings);
+ Result = Client.get();
+ m_ProxyClients.emplace(Port, std::move(Client));
+ }
+ else
+ {
+ Result = It->second.get();
+ }
+ });
+ return *Result;
+}
+
+void
+HttpProxyHandler::HandleProxyRequest(HttpServerRequest& Request, std::string_view PortStr, std::string_view PathTail)
+{
+ uint16_t Port = 0;
+ auto [Ptr, Ec] = std::from_chars(PortStr.data(), PortStr.data() + PortStr.size(), Port);
+ if (Ec != std::errc{} || Ptr != PortStr.data() + PortStr.size())
+ {
+ Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "invalid proxy URL");
+ return;
+ }
+
+ if (!m_ValidatePort(Port))
+ {
+ Request.WriteResponse(HttpResponseCode::BadGateway, HttpContentType::kText, "target instance not available");
+ return;
+ }
+
+ HttpClient& Client = GetOrCreateProxyClient(Port);
+
+ std::string RequestPath;
+ RequestPath.reserve(1 + PathTail.size());
+ RequestPath.push_back('/');
+ RequestPath.append(PathTail);
+
+ std::string_view QueryString = Request.QueryString();
+ if (!QueryString.empty())
+ {
+ RequestPath.push_back('?');
+ RequestPath.append(QueryString);
+ }
+
+ HttpClient::KeyValueMap ForwardHeaders;
+ HttpContentType AcceptType = Request.AcceptContentType();
+ if (AcceptType != HttpContentType::kUnknownContentType)
+ {
+ ForwardHeaders->emplace("Accept", std::string(MapContentTypeToString(AcceptType)));
+ }
+
+ std::string_view Auth = Request.GetAuthorizationHeader();
+ if (!Auth.empty())
+ {
+ ForwardHeaders->emplace("Authorization", std::string(Auth));
+ }
+
+ HttpContentType ReqContentType = Request.RequestContentType();
+ if (ReqContentType != HttpContentType::kUnknownContentType)
+ {
+ ForwardHeaders->emplace("Content-Type", std::string(MapContentTypeToString(ReqContentType)));
+ }
+
+ HttpClient::Response Response;
+
+ switch (Request.RequestVerb())
+ {
+ case HttpVerb::kGet:
+ Response = Client.Get(RequestPath, ForwardHeaders);
+ break;
+ case HttpVerb::kPost:
+ {
+ IoBuffer Payload = Request.ReadPayload();
+ Response = Client.Post(RequestPath, Payload, ForwardHeaders);
+ break;
+ }
+ case HttpVerb::kPut:
+ {
+ IoBuffer Payload = Request.ReadPayload();
+ Response = Client.Put(RequestPath, Payload, ForwardHeaders);
+ break;
+ }
+ case HttpVerb::kDelete:
+ Response = Client.Delete(RequestPath, ForwardHeaders);
+ break;
+ case HttpVerb::kHead:
+ Response = Client.Head(RequestPath, ForwardHeaders);
+ break;
+ default:
+ Request.WriteResponse(HttpResponseCode::MethodNotAllowed, HttpContentType::kText, "method not supported");
+ return;
+ }
+
+ if (Response.Error)
+ {
+ ZEN_WARN("proxy request to port {} failed: {}", Port, Response.Error->ErrorMessage);
+ Request.WriteResponse(HttpResponseCode::BadGateway, HttpContentType::kText, "upstream request failed");
+ return;
+ }
+
+ HttpContentType ContentType = Response.ResponsePayload.GetContentType();
+
+ if (ContentType == HttpContentType::kHTML)
+ {
+ std::string_view Html(static_cast<const char*>(Response.ResponsePayload.GetData()), Response.ResponsePayload.GetSize());
+ std::string Injected = InjectProxyScript(Html, Port);
+ Request.WriteResponse(Response.StatusCode, HttpContentType::kHTML, std::string_view(Injected));
+ }
+ else
+ {
+ Request.WriteResponse(Response.StatusCode, ContentType, std::move(Response.ResponsePayload));
+ }
+}
+
+void
+HttpProxyHandler::PrunePort(uint16_t Port)
+{
+ m_ProxyClientsLock.WithExclusiveLock([&] { m_ProxyClients.erase(Port); });
+
+ std::vector<Ref<WsBridge>> Stale;
+ m_WsBridgesLock.WithExclusiveLock([&] {
+ for (auto It = m_WsBridges.begin(); It != m_WsBridges.end();)
+ {
+ if (It->second->Port == Port)
+ {
+ Stale.push_back(std::move(It->second));
+ It = m_WsBridges.erase(It);
+ }
+ else
+ {
+ ++It;
+ }
+ }
+ });
+
+ for (auto& Bridge : Stale)
+ {
+ if (Bridge->UpstreamClient)
+ {
+ Bridge->UpstreamClient->Close(1001, "instance shutting down");
+ }
+ if (Bridge->ClientConn->IsOpen())
+ {
+ Bridge->ClientConn->Close(1001, "instance shutting down");
+ }
+ }
+}
+
+void
+HttpProxyHandler::Shutdown()
+{
+ m_WsBridgesLock.WithExclusiveLock([&] { m_WsBridges.clear(); });
+ m_ProxyClientsLock.WithExclusiveLock([&] { m_ProxyClients.clear(); });
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// WebSocket proxy
+//
+
+void
+HttpProxyHandler::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
+{
+ const std::string_view ProxyPrefix = "proxy/";
+ if (!RelativeUri.starts_with(ProxyPrefix))
+ {
+ Connection->Close(1008, "unsupported WebSocket endpoint");
+ return;
+ }
+
+ std::string_view ProxyTail = RelativeUri.substr(ProxyPrefix.size());
+
+ size_t SlashPos = ProxyTail.find('/');
+ std::string_view PortStr = (SlashPos != std::string_view::npos) ? ProxyTail.substr(0, SlashPos) : ProxyTail;
+ std::string_view Path = (SlashPos != std::string_view::npos) ? ProxyTail.substr(SlashPos) : "/";
+
+ uint16_t Port = 0;
+ auto [Ptr, Ec] = std::from_chars(PortStr.data(), PortStr.data() + PortStr.size(), Port);
+ if (Ec != std::errc{} || Ptr != PortStr.data() + PortStr.size())
+ {
+ Connection->Close(1008, "invalid proxy URL");
+ return;
+ }
+
+ if (!m_ValidatePort(Port))
+ {
+ Connection->Close(1008, "target instance not available");
+ return;
+ }
+
+ std::string WsUrl = HttpToWsUrl(fmt::format("http://127.0.0.1:{}", Port), Path);
+
+ Ref<WsBridge> Bridge(new WsBridge());
+ Bridge->ClientConn = Connection;
+ Bridge->Port = Port;
+
+ Bridge->UpstreamClient = std::make_unique<HttpWsClient>(WsUrl, *Bridge);
+
+ try
+ {
+ Bridge->UpstreamClient->Connect();
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("proxy WebSocket connect to {} failed: {}", WsUrl, Ex.what());
+ Connection->Close(1011, "upstream connect failed");
+ return;
+ }
+
+ WebSocketConnection* Key = Connection.Get();
+ m_WsBridgesLock.WithExclusiveLock([&] { m_WsBridges.emplace(Key, std::move(Bridge)); });
+}
+
+void
+HttpProxyHandler::OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg)
+{
+ Ref<WsBridge> Bridge;
+ m_WsBridgesLock.WithSharedLock([&] {
+ auto It = m_WsBridges.find(&Conn);
+ if (It != m_WsBridges.end())
+ {
+ Bridge = It->second;
+ }
+ });
+
+ if (!Bridge || !Bridge->UpstreamClient)
+ {
+ return;
+ }
+
+ switch (Msg.Opcode)
+ {
+ case WebSocketOpcode::kText:
+ Bridge->UpstreamClient->SendText(std::string_view(static_cast<const char*>(Msg.Payload.GetData()), Msg.Payload.GetSize()));
+ break;
+ case WebSocketOpcode::kBinary:
+ Bridge->UpstreamClient->SendBinary(
+ std::span<const uint8_t>(static_cast<const uint8_t*>(Msg.Payload.GetData()), Msg.Payload.GetSize()));
+ break;
+ case WebSocketOpcode::kClose:
+ Bridge->UpstreamClient->Close(Msg.CloseCode, {});
+ break;
+ default:
+ break;
+ }
+}
+
+void
+HttpProxyHandler::OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason)
+{
+ Ref<WsBridge> Bridge = m_WsBridgesLock.WithExclusiveLock([this, &Conn]() -> Ref<WsBridge> {
+ auto It = m_WsBridges.find(&Conn);
+ if (It != m_WsBridges.end())
+ {
+ Ref<WsBridge> Bridge = std::move(It->second);
+ m_WsBridges.erase(It);
+ return Bridge;
+ }
+ return {};
+ });
+
+ if (Bridge && Bridge->UpstreamClient)
+ {
+ Bridge->UpstreamClient->Close(Code, Reason);
+ }
+}
+
+#if ZEN_WITH_TESTS
+
+TEST_SUITE_BEGIN("server.httpproxyhandler");
+
+TEST_CASE("server.httpproxyhandler.html_injection")
+{
+ SUBCASE("injects before </head>")
+ {
+ std::string Result = InjectProxyScript("<html><head></head><body></body></html>", 21005);
+ CHECK(Result.find("<script>") != std::string::npos);
+ CHECK(Result.find("/hub/proxy/21005") != std::string::npos);
+ size_t ScriptEnd = Result.find("</script>");
+ size_t HeadClose = Result.find("</head>");
+ REQUIRE(ScriptEnd != std::string::npos);
+ REQUIRE(HeadClose != std::string::npos);
+ CHECK(ScriptEnd < HeadClose);
+ }
+
+ SUBCASE("prepends when no </head>")
+ {
+ std::string Result = InjectProxyScript("<body>content</body>", 21005);
+ CHECK(Result.find("<script>") == 0);
+ CHECK(Result.find("<body>content</body>") != std::string::npos);
+ }
+
+ SUBCASE("empty html")
+ {
+ std::string Result = InjectProxyScript("", 21005);
+ CHECK(Result.find("<script>") != std::string::npos);
+ CHECK(Result.find("/hub/proxy/21005") != std::string::npos);
+ }
+
+ SUBCASE("preserves original content")
+ {
+ std::string_view Html = "<html><head><title>Test</title></head><body><h1>Dashboard</h1></body></html>";
+ std::string Result = InjectProxyScript(Html, 21005);
+ CHECK(Result.find("<title>Test</title>") != std::string::npos);
+ CHECK(Result.find("<h1>Dashboard</h1>") != std::string::npos);
+ }
+}
+
+TEST_CASE("server.httpproxyhandler.port_embedding")
+{
+ std::string Result = InjectProxyScript("<head></head>", 80);
+ CHECK(Result.find("/hub/proxy/80") != std::string::npos);
+
+ Result = InjectProxyScript("<head></head>", 65535);
+ CHECK(Result.find("/hub/proxy/65535") != std::string::npos);
+}
+
+TEST_SUITE_END();
+
+void
+httpproxyhandler_forcelink()
+{
+}
+#endif // ZEN_WITH_TESTS
+
+} // namespace zen
diff --git a/src/zenserver/hub/httpproxyhandler.h b/src/zenserver/hub/httpproxyhandler.h
new file mode 100644
index 000000000..8667c0ca1
--- /dev/null
+++ b/src/zenserver/hub/httpproxyhandler.h
@@ -0,0 +1,52 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/thread.h>
+#include <zenhttp/httpserver.h>
+#include <zenhttp/websocket.h>
+
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+namespace zen {
+
+class HttpClient;
+
+class HttpProxyHandler
+{
+public:
+ using PortValidator = std::function<bool(uint16_t)>;
+
+ HttpProxyHandler();
+ explicit HttpProxyHandler(PortValidator ValidatePort);
+ ~HttpProxyHandler();
+
+ void SetPortValidator(PortValidator ValidatePort);
+
+ HttpProxyHandler(const HttpProxyHandler&) = delete;
+ HttpProxyHandler& operator=(const HttpProxyHandler&) = delete;
+
+ void HandleProxyRequest(HttpServerRequest& Request, std::string_view PortStr, std::string_view PathTail);
+ void PrunePort(uint16_t Port);
+ void Shutdown();
+
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri);
+ void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg);
+ void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason);
+
+private:
+ PortValidator m_ValidatePort;
+
+ HttpClient& GetOrCreateProxyClient(uint16_t Port);
+
+ RwLock m_ProxyClientsLock;
+ std::unordered_map<uint16_t, std::unique_ptr<HttpClient>> m_ProxyClients;
+
+ struct WsBridge;
+ RwLock m_WsBridgesLock;
+ std::unordered_map<WebSocketConnection*, Ref<WsBridge>> m_WsBridges;
+};
+
+} // namespace zen
diff --git a/src/zenserver/hub/hub.cpp b/src/zenserver/hub/hub.cpp
index 2f3873884..82f4a00ba 100644
--- a/src/zenserver/hub/hub.cpp
+++ b/src/zenserver/hub/hub.cpp
@@ -9,6 +9,9 @@
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zencore/scopeguard.h>
+#include <zencore/timer.h>
+#include <zencore/workthreadpool.h>
+#include <zenhttp/httpclient.h>
ZEN_THIRD_PARTY_INCLUDES_START
#include <EASTL/fixed_vector.h>
@@ -16,11 +19,8 @@ ZEN_THIRD_PARTY_INCLUDES_START
ZEN_THIRD_PARTY_INCLUDES_END
#if ZEN_WITH_TESTS
-# include <zencore/filesystem.h>
# include <zencore/testing.h>
# include <zencore/testutils.h>
-# include <zencore/workthreadpool.h>
-# include <zenhttp/httpclient.h>
#endif
#include <numeric>
@@ -121,29 +121,89 @@ private:
//////////////////////////////////////////////////////////////////////////
-Hub::Hub(const Configuration& Config,
- ZenServerEnvironment&& RunEnvironment,
- ProvisionModuleCallbackFunc&& ProvisionedModuleCallback,
- ProvisionModuleCallbackFunc&& DeprovisionedModuleCallback)
+ProcessMetrics
+Hub::AtomicProcessMetrics::Load() const
+{
+ return {
+ .MemoryBytes = MemoryBytes.load(),
+ .KernelTimeMs = KernelTimeMs.load(),
+ .UserTimeMs = UserTimeMs.load(),
+ .WorkingSetSize = WorkingSetSize.load(),
+ .PeakWorkingSetSize = PeakWorkingSetSize.load(),
+ .PagefileUsage = PagefileUsage.load(),
+ .PeakPagefileUsage = PeakPagefileUsage.load(),
+ };
+}
+
+void
+Hub::AtomicProcessMetrics::Store(const ProcessMetrics& Metrics)
+{
+ MemoryBytes.store(Metrics.MemoryBytes);
+ KernelTimeMs.store(Metrics.KernelTimeMs);
+ UserTimeMs.store(Metrics.UserTimeMs);
+ WorkingSetSize.store(Metrics.WorkingSetSize);
+ PeakWorkingSetSize.store(Metrics.PeakWorkingSetSize);
+ PagefileUsage.store(Metrics.PagefileUsage);
+ PeakPagefileUsage.store(Metrics.PeakPagefileUsage);
+}
+
+void
+Hub::AtomicProcessMetrics::Reset()
+{
+ MemoryBytes.store(0);
+ KernelTimeMs.store(0);
+ UserTimeMs.store(0);
+ WorkingSetSize.store(0);
+ PeakWorkingSetSize.store(0);
+ PagefileUsage.store(0);
+ PeakPagefileUsage.store(0);
+}
+
+void
+Hub::GetMachineMetrics(SystemMetrics& OutSystemMetrict, DiskSpace& OutDiskSpace) const
+{
+ m_Lock.WithSharedLock([&]() {
+ OutSystemMetrict = m_SystemMetrics;
+ OutDiskSpace = m_DiskSpace;
+ });
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+Hub::Hub(const Configuration& Config,
+ ZenServerEnvironment&& RunEnvironment,
+ WorkerThreadPool* OptionalWorkerPool,
+ AsyncModuleStateChangeCallbackFunc&& ModuleStateChangeCallback)
: m_Config(Config)
, m_RunEnvironment(std::move(RunEnvironment))
-, m_ProvisionedModuleCallback(std::move(ProvisionedModuleCallback))
-, m_DeprovisionedModuleCallback(std::move(DeprovisionedModuleCallback))
+, m_WorkerPool(OptionalWorkerPool)
+, m_BackgroundWorkLatch(1)
+, m_ModuleStateChangeCallback(std::move(ModuleStateChangeCallback))
+, m_ActiveInstances(Config.InstanceLimit)
+, m_FreeActiveInstanceIndexes(Config.InstanceLimit)
{
- m_HostMetrics = GetSystemMetrics();
- m_ResourceLimits.DiskUsageBytes = 1000ull * 1024 * 1024 * 1024;
- m_ResourceLimits.MemoryUsageBytes = 16ull * 1024 * 1024 * 1024;
-
- m_FileHydrationPath = m_RunEnvironment.CreateChildDir("hydration_storage");
- ZEN_INFO("using file hydration path: '{}'", m_FileHydrationPath);
+ if (!m_Config.HydrationTargetSpecification.empty())
+ {
+ m_HydrationTargetSpecification = m_Config.HydrationTargetSpecification;
+ }
+ else if (!m_Config.HydrationOptions)
+ {
+ std::filesystem::path FileHydrationPath = m_RunEnvironment.CreateChildDir("hydration_storage");
+ ZEN_INFO("using file hydration path: '{}'", FileHydrationPath);
+ m_HydrationTargetSpecification = fmt::format("file://{}", WideToUtf8(FileHydrationPath.native()));
+ }
+ else
+ {
+ m_HydrationOptions = m_Config.HydrationOptions;
+ }
m_HydrationTempPath = m_RunEnvironment.CreateChildDir("hydration_temp");
ZEN_INFO("using hydration temp path: '{}'", m_HydrationTempPath);
ZEN_ASSERT(uint64_t(Config.BasePortNumber) + Config.InstanceLimit <= std::numeric_limits<uint16_t>::max());
- m_FreePorts.resize(Config.InstanceLimit);
- std::iota(m_FreePorts.begin(), m_FreePorts.end(), Config.BasePortNumber);
+ m_InstanceLookup.reserve(Config.InstanceLimit);
+ std::iota(m_FreeActiveInstanceIndexes.begin(), m_FreeActiveInstanceIndexes.end(), 0);
#if ZEN_PLATFORM_WINDOWS
if (m_Config.UseJobObject)
@@ -159,314 +219,1311 @@ Hub::Hub(const Configuration& Config,
}
}
#endif
+
+ UpdateMachineMetrics();
+
+ m_WatchDog = std::thread([this]() { WatchDog(); });
}
Hub::~Hub()
{
try
{
- ZEN_INFO("Hub service shutting down, deprovisioning any current instances");
+ // Safety call - should normally be properly Shutdown by owner
+ if (!m_ShutdownFlag.load())
+ {
+ Shutdown();
+ }
+ }
+ catch (const std::exception& e)
+ {
+ ZEN_WARN("Exception during hub service shutdown: {}", e.what());
+ }
+}
+
+void
+Hub::Shutdown()
+{
+ ZEN_INFO("Hub service shutting down, deprovisioning any current instances");
+
+ bool Expected = false;
+ bool WaitForBackgroundWork = m_ShutdownFlag.compare_exchange_strong(Expected, true);
+
+ m_WatchDogEvent.Set();
+ if (m_WatchDog.joinable())
+ {
+ m_WatchDog.join();
+ }
+
+ m_WatchDog = {};
+
+ if (WaitForBackgroundWork && m_WorkerPool)
+ {
+ m_BackgroundWorkLatch.CountDown();
+ m_BackgroundWorkLatch.Wait();
+ // Shutdown flag is set and all background work is drained, safe to shut down remaining instances
+
+ m_BackgroundWorkLatch.Reset(1);
+ }
+
+ EnumerateModules([&](std::string_view ModuleId, const InstanceInfo& Info) {
+ ZEN_UNUSED(Info);
+ try
+ {
+ const Response DepResp = InternalDeprovision(std::string(ModuleId), [](ActiveInstance& Instance) {
+ ZEN_UNUSED(Instance);
+ return true;
+ });
+ if (DepResp.ResponseCode != EResponseCode::Completed && DepResp.ResponseCode != EResponseCode::Accepted)
+ {
+ ZEN_WARN("Deprovision instance for module '{}' during hub shutdown rejected: {}", ModuleId, DepResp.Message);
+ }
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("Failed to deprovision instance for module '{}' during hub shutdown: {}", ModuleId, Ex.what());
+ }
+ });
+
+ if (WaitForBackgroundWork && m_WorkerPool)
+ {
+ m_BackgroundWorkLatch.CountDown();
+ m_BackgroundWorkLatch.Wait();
+ }
+}
+
+Hub::Response
+Hub::Provision(std::string_view ModuleId, HubProvisionedInstanceInfo& OutInfo)
+{
+ ZEN_ASSERT(!m_ShutdownFlag.load());
+ StorageServerInstance::ExclusiveLockedPtr Instance;
+ bool IsNewInstance = false;
+ size_t ActiveInstanceIndex = (size_t)-1;
+ HubInstanceState OldState = HubInstanceState::Unprovisioned;
+ {
+ RwLock::ExclusiveLockScope _(m_Lock);
+
+ if (auto It = m_InstanceLookup.find(std::string(ModuleId)); It == m_InstanceLookup.end())
+ {
+ std::string Reason;
+ if (!CanProvisionInstanceLocked(ModuleId, /* out */ Reason))
+ {
+ ZEN_WARN("Cannot provision new storage server instance for module '{}': {}", ModuleId, Reason);
+
+ return Response{EResponseCode::Rejected, Reason};
+ }
- m_Lock.WithExclusiveLock([this] {
- for (auto& [ModuleId, Instance] : m_Instances)
+ IsNewInstance = true;
+
+ ActiveInstanceIndex = m_FreeActiveInstanceIndexes.front();
+ m_FreeActiveInstanceIndexes.pop_front();
+ ZEN_ASSERT(m_ActiveInstances.size() > ActiveInstanceIndex);
+
+ try
{
- uint16_t BasePort = Instance->GetBasePort();
- std::string BaseUri; // TODO?
+ auto NewInstance = std::make_unique<StorageServerInstance>(
+ m_RunEnvironment,
+ StorageServerInstance::Configuration{.BasePort = GetInstanceIndexAssignedPort(ActiveInstanceIndex),
+ .HydrationTempPath = m_HydrationTempPath,
+ .HydrationTargetSpecification = m_HydrationTargetSpecification,
+ .HydrationOptions = m_HydrationOptions,
+ .HttpThreadCount = m_Config.InstanceHttpThreadCount,
+ .CoreLimit = m_Config.InstanceCoreLimit,
+ .ConfigPath = m_Config.InstanceConfigPath},
+ ModuleId);
- if (m_DeprovisionedModuleCallback)
+#if ZEN_PLATFORM_WINDOWS
+ if (m_JobObject.IsValid())
{
+ NewInstance->SetJobObject(&m_JobObject);
+ }
+#endif
+
+ Instance = NewInstance->LockExclusive(/*Wait*/ true);
+
+ m_ActiveInstances[ActiveInstanceIndex].Instance = std::move(NewInstance);
+ m_ActiveInstances[ActiveInstanceIndex].ProcessMetrics.Reset();
+ m_InstanceLookup.insert_or_assign(std::string(ModuleId), ActiveInstanceIndex);
+ // Set Provisioning while both hub lock and instance lock are held so that any
+ // concurrent Deprovision sees the in-flight state, not Unprovisioned.
+ OldState = UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Provisioning);
+ }
+ catch (const std::exception&)
+ {
+ Instance = {};
+ m_ActiveInstances[ActiveInstanceIndex].Instance.reset();
+ m_ActiveInstances[ActiveInstanceIndex].State.store(HubInstanceState::Unprovisioned);
+ m_InstanceLookup.erase(std::string(ModuleId));
+ m_FreeActiveInstanceIndexes.push_back(ActiveInstanceIndex);
+ throw;
+ }
+
+ OutInfo.Port = GetInstanceIndexAssignedPort(ActiveInstanceIndex);
+
+ ZEN_INFO("Created new storage server instance for module '{}'", ModuleId);
+
+ const int CurrentInstanceCount = gsl::narrow_cast<int>(m_InstanceLookup.size());
+ int CurrentMaxCount = m_MaxInstanceCount.load();
+ const int NewMax = Max(CurrentMaxCount, CurrentInstanceCount);
+
+ m_MaxInstanceCount.compare_exchange_weak(CurrentMaxCount, NewMax);
+ }
+ else
+ {
+ ActiveInstanceIndex = It->second;
+ ZEN_ASSERT(m_ActiveInstances.size() > ActiveInstanceIndex);
+
+ HubInstanceState CurrentState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+
+ std::unique_ptr<StorageServerInstance>& InstanceRaw = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(InstanceRaw);
+
+ OutInfo.Port = InstanceRaw->GetBasePort();
+
+ switch (CurrentState)
+ {
+ case HubInstanceState::Provisioning:
+ return Response{EResponseCode::Accepted};
+ case HubInstanceState::Crashed:
+ case HubInstanceState::Unprovisioned:
+ break;
+ case HubInstanceState::Provisioned:
+ return Response{EResponseCode::Completed};
+ case HubInstanceState::Hibernated:
+ _.ReleaseNow();
+ return Wake(std::string(ModuleId));
+ default:
+ return Response{EResponseCode::Rejected,
+ fmt::format("Module '{}' is currently in state '{}'", ModuleId, ToString(CurrentState))};
+ }
+
+ Instance = InstanceRaw->LockExclusive(/*Wait*/ true);
+
+ // Re-validate state after acquiring the instance lock: a concurrent Provision may have
+ // completed between our hub-lock read and LockExclusive, transitioning the state away
+ // from Crashed/Unprovisioned.
+ HubInstanceState ActualState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+ if (ActualState != HubInstanceState::Crashed && ActualState != HubInstanceState::Unprovisioned)
+ {
+ Instance = {};
+ if (ActualState == HubInstanceState::Provisioned)
+ {
+ return Response{EResponseCode::Completed};
+ }
+ if (ActualState == HubInstanceState::Provisioning)
+ {
+ return Response{EResponseCode::Accepted};
+ }
+ return Response{
+ EResponseCode::Rejected,
+ fmt::format("Module '{}' state changed to '{}' before provision could proceed", ModuleId, ToString(ActualState))};
+ }
+ // Set Provisioning while both hub lock and instance lock are held so that any
+ // concurrent Deprovision sees the in-flight state, not Crashed/Unprovisioned.
+ OldState = UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Provisioning);
+ }
+ }
+
+ // NOTE: done while not holding the hub lock, to avoid blocking other operations.
+ // Both hub-lock paths above set OldState and updated the state to Provisioning before
+ // releasing the hub lock, so concurrent operations already see the in-flight state.
+
+ ZEN_ASSERT(Instance);
+ ZEN_ASSERT(ActiveInstanceIndex != (size_t)-1);
+
+ NotifyStateUpdate(ModuleId, OldState, HubInstanceState::Provisioning, OutInfo.Port, {});
+
+ if (m_WorkerPool)
+ {
+ m_BackgroundWorkLatch.AddCount(1);
+ try
+ {
+ m_WorkerPool->ScheduleWork(
+ [this,
+ ModuleId = std::string(ModuleId),
+ ActiveInstanceIndex,
+ OldState,
+ IsNewInstance,
+ Instance = std::make_shared<StorageServerInstance::ExclusiveLockedPtr>(std::move(Instance))]() {
+ auto _ = MakeGuard([this]() { m_BackgroundWorkLatch.CountDown(); });
try
{
- m_DeprovisionedModuleCallback(ModuleId, HubProvisionedInstanceInfo{.BaseUri = BaseUri, .Port = BasePort});
+ CompleteProvision(*Instance, ActiveInstanceIndex, OldState, IsNewInstance);
}
catch (const std::exception& Ex)
{
- ZEN_ERROR("Deprovision callback for module {} failed. Reason: '{}'", ModuleId, Ex.what());
+ ZEN_ERROR("Failed async provision of module '{}': {}", ModuleId, Ex.what());
}
+ },
+ WorkerThreadPool::EMode::EnableBacklog);
+ }
+ catch (const std::exception& DispatchEx)
+ {
+ // Dispatch failed: undo latch increment and roll back state.
+ ZEN_ERROR("Failed async dispatch provision of module '{}': {}", ModuleId, DispatchEx.what());
+ m_BackgroundWorkLatch.CountDown();
+
+ // dispatch failed before the lambda ran, so ActiveInstance::State is still Provisioning
+ NotifyStateUpdate(ModuleId, HubInstanceState::Provisioning, OldState, OutInfo.Port, {});
+
+ std::unique_ptr<StorageServerInstance> DestroyInstance;
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId)) != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId))->second == ActiveInstanceIndex);
+ if (IsNewInstance)
+ {
+ DestroyInstance = std::move(m_ActiveInstances[ActiveInstanceIndex].Instance);
+ m_FreeActiveInstanceIndexes.push_back(ActiveInstanceIndex);
+ m_InstanceLookup.erase(std::string(ModuleId));
}
- Instance->Deprovision();
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, OldState);
}
- m_Instances.clear();
- });
+ DestroyInstance.reset();
+
+ throw;
+ }
}
- catch (const std::exception& e)
+ else
{
- ZEN_WARN("Exception during hub service shutdown: {}", e.what());
+ CompleteProvision(Instance, ActiveInstanceIndex, OldState, IsNewInstance);
}
+
+ return Response{m_WorkerPool ? EResponseCode::Accepted : EResponseCode::Completed};
}
-bool
-Hub::Provision(std::string_view ModuleId, HubProvisionedInstanceInfo& OutInfo, std::string& OutReason)
+void
+Hub::CompleteProvision(StorageServerInstance::ExclusiveLockedPtr& Instance,
+ size_t ActiveInstanceIndex,
+ HubInstanceState OldState,
+ bool IsNewInstance)
{
- StorageServerInstance* Instance = nullptr;
- bool IsNewInstance = false;
+ const std::string ModuleId(Instance.GetModuleId());
+ const uint16_t Port = Instance.GetBasePort();
+ std::string BaseUri; // TODO?
+
+ if (m_ShutdownFlag.load() == false)
+ {
+ try
+ {
+ switch (OldState)
+ {
+ case HubInstanceState::Crashed:
+ case HubInstanceState::Unprovisioned:
+ Instance.Provision();
+ break;
+ case HubInstanceState::Hibernated:
+ ZEN_ASSERT(false); // unreachable: Provision redirects Hibernated->Wake before setting Provisioning
+ break;
+ default:
+ ZEN_ASSERT(false);
+ }
+ UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Provisioned);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Provisioning, HubInstanceState::Provisioned, Port, BaseUri);
+ Instance = {};
+ return;
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed to provision storage server instance for module '{}': {}", ModuleId, Ex.what());
+ // Instance will be notified and removed below.
+ }
+ }
+
+ if (IsNewInstance)
+ {
+ NotifyStateUpdate(ModuleId, HubInstanceState::Provisioning, HubInstanceState::Unprovisioned, Port, {});
+ Instance = {};
+ std::unique_ptr<StorageServerInstance> DestroyInstance;
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId)) != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId))->second == ActiveInstanceIndex);
+ DestroyInstance = std::move(m_ActiveInstances[ActiveInstanceIndex].Instance);
+ m_FreeActiveInstanceIndexes.push_back(ActiveInstanceIndex);
+ m_InstanceLookup.erase(std::string(ModuleId));
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, HubInstanceState::Unprovisioned);
+ }
+ DestroyInstance.reset();
+ }
+ else
+ {
+ // OldState = Crashed: restore without cleanup (instance stays in lookup)
+ NotifyStateUpdate(ModuleId, HubInstanceState::Provisioning, OldState, Port, {});
+ UpdateInstanceState(Instance, ActiveInstanceIndex, OldState);
+ Instance = {};
+ }
+}
+
+Hub::Response
+Hub::Deprovision(const std::string& ModuleId)
+{
+ ZEN_ASSERT(!m_ShutdownFlag.load());
+ return InternalDeprovision(ModuleId, [](ActiveInstance& Instance) {
+ ZEN_UNUSED(Instance);
+ return true;
+ });
+}
+
+Hub::Response
+Hub::InternalDeprovision(const std::string& ModuleId, std::function<bool(ActiveInstance& Instance)>&& DeprovisionGate)
+{
+ StorageServerInstance::ExclusiveLockedPtr Instance;
+ size_t ActiveInstanceIndex = (size_t)-1;
{
RwLock::ExclusiveLockScope _(m_Lock);
- uint16_t AllocatedPort = 0;
- auto RestoreAllocatedPort = MakeGuard([this, &AllocatedPort]() {
- if (AllocatedPort != 0)
- {
- m_FreePorts.push_back(AllocatedPort);
- AllocatedPort = 0;
- }
- });
- if (auto It = m_Instances.find(std::string(ModuleId)); It == m_Instances.end())
+ if (auto It = m_InstanceLookup.find(ModuleId); It == m_InstanceLookup.end())
{
- std::string Reason;
- if (!CanProvisionInstance(ModuleId, /* out */ Reason))
- {
- ZEN_WARN("Cannot provision new storage server instance for module '{}': {}", ModuleId, Reason);
+ ZEN_WARN("Attempted to deprovision non-existent module '{}'", ModuleId);
- OutReason = Reason;
+ return Response{EResponseCode::NotFound};
+ }
+ else
+ {
+ ActiveInstanceIndex = It->second;
+ ZEN_ASSERT(ActiveInstanceIndex < m_ActiveInstances.size());
- return false;
+ if (!DeprovisionGate(m_ActiveInstances[ActiveInstanceIndex]))
+ {
+ return Response{EResponseCode::Rejected, fmt::format("Module '{}' deprovision denied by gate", ModuleId)};
}
- AllocatedPort = m_FreePorts.front();
- m_FreePorts.pop_front();
-
- IsNewInstance = true;
- auto NewInstance = std::make_unique<StorageServerInstance>(
- m_RunEnvironment,
- StorageServerInstance::Configuration{.BasePort = AllocatedPort,
- .HydrationTempPath = m_HydrationTempPath,
- .FileHydrationPath = m_FileHydrationPath,
- .HttpThreadCount = m_Config.InstanceHttpThreadCount,
- .CoreLimit = m_Config.InstanceCoreLimit,
- .ConfigPath = m_Config.InstanceConfigPath},
- ModuleId);
-#if ZEN_PLATFORM_WINDOWS
- if (m_JobObject.IsValid())
+ HubInstanceState CurrentState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+
+ switch (CurrentState)
{
- NewInstance->SetJobObject(&m_JobObject);
+ case HubInstanceState::Deprovisioning:
+ return Response{EResponseCode::Accepted};
+ case HubInstanceState::Crashed:
+ case HubInstanceState::Hibernated:
+ case HubInstanceState::Provisioned:
+ break;
+ case HubInstanceState::Unprovisioned:
+ return Response{EResponseCode::Completed};
+ case HubInstanceState::Recovering:
+ // Recovering is watchdog-managed; reject to avoid interfering with the in-progress
+ // recovery. The watchdog will transition to Provisioned or Unprovisioned, after
+ // which deprovision can be retried.
+ return Response{EResponseCode::Rejected, fmt::format("Module '{}' is currently recovering from a crash", ModuleId)};
+ default:
+ return Response{EResponseCode::Rejected,
+ fmt::format("Module '{}' is currently in state '{}'", ModuleId, ToString(CurrentState))};
}
-#endif
- Instance = NewInstance.get();
- m_Instances.emplace(std::string(ModuleId), std::move(NewInstance));
- AllocatedPort = 0;
- ZEN_INFO("Created new storage server instance for module '{}'", ModuleId);
+ std::unique_ptr<StorageServerInstance>& RawInstance = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(RawInstance != nullptr);
+
+ Instance = RawInstance->LockExclusive(/*Wait*/ true);
}
- else
+ }
+
+ // NOTE: done while not holding the hub lock, to avoid blocking other operations.
+ // The exclusive instance lock acquired above prevents concurrent LockExclusive callers
+ // from modifying instance state. The state transition to Deprovisioning happens below,
+ // after the hub lock is released.
+
+ ZEN_ASSERT(Instance);
+ ZEN_ASSERT(ActiveInstanceIndex != (size_t)-1);
+
+ HubInstanceState OldState = UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Deprovisioning);
+ const uint16_t Port = Instance.GetBasePort();
+ NotifyStateUpdate(ModuleId, OldState, HubInstanceState::Deprovisioning, Port, {});
+
+ if (m_WorkerPool)
+ {
+ std::shared_ptr<StorageServerInstance::ExclusiveLockedPtr> SharedInstancePtr =
+ std::make_shared<StorageServerInstance::ExclusiveLockedPtr>(std::move(Instance));
+
+ m_BackgroundWorkLatch.AddCount(1);
+ try
{
- Instance = It->second.get();
+ m_WorkerPool->ScheduleWork(
+ [this, ModuleId = std::string(ModuleId), ActiveInstanceIndex, Instance = std::move(SharedInstancePtr)]() mutable {
+ auto _ = MakeGuard([this]() { m_BackgroundWorkLatch.CountDown(); });
+ try
+ {
+ CompleteDeprovision(*Instance, ActiveInstanceIndex);
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed async deprovision of module '{}': {}", ModuleId, Ex.what());
+ }
+ },
+ WorkerThreadPool::EMode::EnableBacklog);
}
+ catch (const std::exception& DispatchEx)
+ {
+ // Dispatch failed: undo latch increment and roll back state.
+ ZEN_ERROR("Failed async dispatch deprovision of module '{}': {}", ModuleId, DispatchEx.what());
+ m_BackgroundWorkLatch.CountDown();
- m_ProvisioningModules.emplace(std::string(ModuleId));
- }
-
- ZEN_ASSERT(Instance != nullptr);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Deprovisioning, OldState, Port, {});
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId)) != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId))->second == ActiveInstanceIndex);
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, OldState);
+ }
- auto RemoveProvisioningModule = MakeGuard([&] {
- RwLock::ExclusiveLockScope _(m_Lock);
- m_ProvisioningModules.erase(std::string(ModuleId));
- });
+ throw;
+ }
+ }
+ else
+ {
+ CompleteDeprovision(Instance, ActiveInstanceIndex);
+ }
- // NOTE: this is done while not holding the lock, as provisioning may take time
- // and we don't want to block other operations. We track which modules are being
- // provisioned using m_ProvisioningModules, and reject attempts to provision/deprovision
- // those modules while in this state.
+ return Response{m_WorkerPool ? EResponseCode::Accepted : EResponseCode::Completed};
+}
- UpdateStats();
+void
+Hub::CompleteDeprovision(StorageServerInstance::ExclusiveLockedPtr& Instance, size_t ActiveInstanceIndex)
+{
+ const std::string ModuleId(Instance.GetModuleId());
+ const uint16_t Port = Instance.GetBasePort();
try
{
- Instance->Provision();
+ Instance.Deprovision();
}
catch (const std::exception& Ex)
{
- ZEN_ERROR("Failed to provision storage server instance for module '{}': {}", ModuleId, Ex.what());
- if (IsNewInstance)
+ ZEN_ERROR("Failed to deprovision storage server instance for module '{}': {}", ModuleId, Ex.what());
+ // Effectively unreachable: Shutdown() never throws and Dehydrate() failures are swallowed
+ // by DeprovisionLocked. Kept as a safety net; if somehow reached, transition to Crashed
+ // so the watchdog can attempt recovery.
+ Instance = {};
{
- // Clean up
- RwLock::ExclusiveLockScope _(m_Lock);
- if (auto It = m_Instances.find(std::string(ModuleId)); It != m_Instances.end())
- {
- ZEN_ASSERT(It->second != nullptr);
- uint16_t BasePort = It->second->GetBasePort();
- m_FreePorts.push_back(BasePort);
- m_Instances.erase(It);
- }
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, HubInstanceState::Crashed);
}
- return false;
+ NotifyStateUpdate(ModuleId, HubInstanceState::Deprovisioning, HubInstanceState::Crashed, Port, {});
+ throw;
}
- OutInfo.Port = Instance->GetBasePort();
- // TODO: base URI? Would need to know what host name / IP to use
+ NotifyStateUpdate(ModuleId, HubInstanceState::Deprovisioning, HubInstanceState::Unprovisioned, Port, {});
+ Instance = {};
+
+ std::unique_ptr<StorageServerInstance> DeleteInstance;
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ auto It = m_InstanceLookup.find(std::string(ModuleId));
+ ZEN_ASSERT_SLOW(It != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(It->second == ActiveInstanceIndex);
+ DeleteInstance = std::move(m_ActiveInstances[ActiveInstanceIndex].Instance);
+ m_FreeActiveInstanceIndexes.push_back(ActiveInstanceIndex);
+ m_InstanceLookup.erase(It);
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, HubInstanceState::Unprovisioned);
+ }
+ DeleteInstance.reset();
+}
+
+Hub::Response
+Hub::Hibernate(const std::string& ModuleId)
+{
+ ZEN_ASSERT(!m_ShutdownFlag.load());
+
+ StorageServerInstance::ExclusiveLockedPtr Instance;
+ size_t ActiveInstanceIndex = (size_t)-1;
- if (m_ProvisionedModuleCallback)
{
+ RwLock::ExclusiveLockScope _(m_Lock);
+
+ auto It = m_InstanceLookup.find(ModuleId);
+ if (It == m_InstanceLookup.end())
+ {
+ return Response{EResponseCode::NotFound};
+ }
+
+ ActiveInstanceIndex = It->second;
+ ZEN_ASSERT(ActiveInstanceIndex < m_ActiveInstances.size());
+
+ HubInstanceState CurrentState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+
+ switch (CurrentState)
+ {
+ case HubInstanceState::Hibernating:
+ return Response{EResponseCode::Accepted};
+ case HubInstanceState::Provisioned:
+ break;
+ case HubInstanceState::Hibernated:
+ return Response{EResponseCode::Completed};
+ default:
+ return Response{EResponseCode::Rejected,
+ fmt::format("Module '{}' is currently in state '{}'", ModuleId, ToString(CurrentState))};
+ }
+
+ std::unique_ptr<StorageServerInstance>& InstanceRaw = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(InstanceRaw);
+
+ Instance = InstanceRaw->LockExclusive(/*Wait*/ true);
+
+ // Re-validate state after acquiring the instance lock: WatchDog may have transitioned
+ // Provisioned -> Crashed between our hub-lock read and the LockExclusive call above.
+
+ HubInstanceState ActualState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+ if (ActualState != HubInstanceState::Provisioned)
+ {
+ Instance = {};
+ return Response{
+ EResponseCode::Rejected,
+ fmt::format("Module '{}' state changed to '{}' before hibernate could proceed", ModuleId, ToString(ActualState))};
+ }
+ }
+
+ // NOTE: done while not holding the hub lock, to avoid blocking other operations.
+ // Any concurrent caller that acquired the hub lock and saw Provisioned will now block on
+ // LockExclusive(Wait=true); by the time it acquires the lock, UpdateInstanceState below
+ // will have already changed the state and the re-validate above will reject it.
+
+ ZEN_ASSERT(Instance);
+ ZEN_ASSERT(ActiveInstanceIndex != (size_t)-1);
+
+ HubInstanceState OldState = UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Hibernating);
+ const uint16_t Port = Instance.GetBasePort();
+ NotifyStateUpdate(ModuleId, OldState, HubInstanceState::Hibernating, Port, {});
+
+ if (m_WorkerPool)
+ {
+ m_BackgroundWorkLatch.AddCount(1);
try
{
- m_ProvisionedModuleCallback(ModuleId, OutInfo);
+ m_WorkerPool->ScheduleWork(
+ [this,
+ ModuleId = std::string(ModuleId),
+ ActiveInstanceIndex,
+ OldState,
+ Instance = std::make_shared<StorageServerInstance::ExclusiveLockedPtr>(std::move(Instance))]() {
+ auto _ = MakeGuard([this]() { m_BackgroundWorkLatch.CountDown(); });
+ try
+ {
+ CompleteHibernate(*Instance, ActiveInstanceIndex, OldState);
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed async hibernate of module '{}': {}", ModuleId, Ex.what());
+ }
+ },
+ WorkerThreadPool::EMode::EnableBacklog);
}
- catch (const std::exception& Ex)
+ catch (const std::exception& DispatchEx)
{
- ZEN_ERROR("Provision callback for module {} failed. Reason: '{}'", ModuleId, Ex.what());
+ // Dispatch failed: undo latch increment and roll back state.
+ ZEN_ERROR("Failed async dispatch hibernate of module '{}': {}", ModuleId, DispatchEx.what());
+ m_BackgroundWorkLatch.CountDown();
+
+ NotifyStateUpdate(ModuleId, HubInstanceState::Hibernating, OldState, Port, {});
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId)) != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId))->second == ActiveInstanceIndex);
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, OldState);
+ }
+
+ throw;
}
}
+ else
+ {
+ CompleteHibernate(Instance, ActiveInstanceIndex, OldState);
+ }
- return true;
+ return Response{m_WorkerPool ? EResponseCode::Accepted : EResponseCode::Completed};
}
-bool
-Hub::Deprovision(const std::string& ModuleId, std::string& OutReason)
+void
+Hub::CompleteHibernate(StorageServerInstance::ExclusiveLockedPtr& Instance, size_t ActiveInstanceIndex, HubInstanceState OldState)
{
- std::unique_ptr<StorageServerInstance> Instance;
+ const std::string ModuleId(Instance.GetModuleId());
+ const uint16_t Port = Instance.GetBasePort();
+
+ try
+ {
+ Instance.Hibernate();
+ UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Hibernated);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Hibernating, HubInstanceState::Hibernated, Port, {});
+ Instance = {};
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed to hibernate storage server instance for module '{}': {}", ModuleId, Ex.what());
+ UpdateInstanceState(Instance, ActiveInstanceIndex, OldState);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Hibernating, OldState, Port, {});
+ Instance = {};
+ throw;
+ }
+}
+
+Hub::Response
+Hub::Wake(const std::string& ModuleId)
+{
+ ZEN_ASSERT(!m_ShutdownFlag.load());
+
+ StorageServerInstance::ExclusiveLockedPtr Instance;
+ size_t ActiveInstanceIndex = (size_t)-1;
{
RwLock::ExclusiveLockScope _(m_Lock);
- if (auto It = m_ProvisioningModules.find(ModuleId); It != m_ProvisioningModules.end())
+ auto It = m_InstanceLookup.find(ModuleId);
+ if (It == m_InstanceLookup.end())
{
- OutReason = fmt::format("Module '{}' is currently being provisioned", ModuleId);
+ return Response{EResponseCode::NotFound};
+ }
- ZEN_WARN("Attempted to deprovision module '{}' which is currently being provisioned", ModuleId);
+ ActiveInstanceIndex = It->second;
+ ZEN_ASSERT(ActiveInstanceIndex < m_ActiveInstances.size());
- return false;
- }
+ HubInstanceState CurrentState = m_ActiveInstances[ActiveInstanceIndex].State.load();
- if (auto It = m_Instances.find(ModuleId); It == m_Instances.end())
+ switch (CurrentState)
{
- ZEN_WARN("Attempted to deprovision non-existent module '{}'", ModuleId);
-
- // Not found, OutReason should be empty
- return false;
+ case HubInstanceState::Waking:
+ return Response{EResponseCode::Accepted};
+ case HubInstanceState::Hibernated:
+ break;
+ case HubInstanceState::Provisioned:
+ return Response{EResponseCode::Completed};
+ default:
+ return Response{EResponseCode::Rejected,
+ fmt::format("Module '{}' is currently in state '{}'", ModuleId, ToString(CurrentState))};
}
- else
+
+ std::unique_ptr<StorageServerInstance>& InstanceRaw = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(InstanceRaw);
+
+ Instance = InstanceRaw->LockExclusive(/*Wait*/ true);
+
+ // Re-validate state after acquiring the instance lock: a concurrent Wake or Deprovision may
+ // have transitioned Hibernated -> something else between our hub-lock read and LockExclusive.
+ HubInstanceState ActualState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+ if (ActualState != HubInstanceState::Hibernated)
{
- Instance = std::move(It->second);
- m_Instances.erase(It);
- m_DeprovisioningModules.emplace(ModuleId);
+ Instance = {};
+ return Response{EResponseCode::Rejected,
+ fmt::format("Module '{}' state changed to '{}' before wake could proceed", ModuleId, ToString(ActualState))};
}
}
- uint16_t BasePort = Instance->GetBasePort();
- std::string BaseUri; // TODO?
+ // NOTE: done while not holding the hub lock, to avoid blocking other operations.
+ // Any concurrent caller that acquired the hub lock and saw Hibernated will now block on
+ // LockExclusive(Wait=true); by the time it acquires the lock, UpdateInstanceState below
+ // will have already changed the state and the re-validate above will reject it.
+
+ ZEN_ASSERT(Instance);
+ ZEN_ASSERT(ActiveInstanceIndex != (size_t)-1);
- if (m_DeprovisionedModuleCallback)
+ HubInstanceState OldState = UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Waking);
+ const uint16_t Port = Instance.GetBasePort();
+ NotifyStateUpdate(ModuleId, OldState, HubInstanceState::Waking, Port, {});
+
+ if (m_WorkerPool)
{
+ m_BackgroundWorkLatch.AddCount(1);
try
{
- m_DeprovisionedModuleCallback(ModuleId, HubProvisionedInstanceInfo{.BaseUri = BaseUri, .Port = BasePort});
+ m_WorkerPool->ScheduleWork(
+ [this,
+ ModuleId = std::string(ModuleId),
+ ActiveInstanceIndex,
+ OldState,
+ Instance = std::make_shared<StorageServerInstance::ExclusiveLockedPtr>(std::move(Instance))]() {
+ auto _ = MakeGuard([this]() { m_BackgroundWorkLatch.CountDown(); });
+ try
+ {
+ CompleteWake(*Instance, ActiveInstanceIndex, OldState);
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed async wake of module '{}': {}", ModuleId, Ex.what());
+ }
+ },
+ WorkerThreadPool::EMode::EnableBacklog);
}
- catch (const std::exception& Ex)
+ catch (const std::exception& DispatchEx)
{
- ZEN_ERROR("Deprovision callback for module {} failed. Reason: '{}'", ModuleId, Ex.what());
+ // Dispatch failed: undo latch increment and roll back state.
+ ZEN_ERROR("Failed async dispatch wake of module '{}': {}", ModuleId, DispatchEx.what());
+ m_BackgroundWorkLatch.CountDown();
+
+ NotifyStateUpdate(ModuleId, HubInstanceState::Waking, OldState, Port, {});
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId)) != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(m_InstanceLookup.find(std::string(ModuleId))->second == ActiveInstanceIndex);
+ UpdateInstanceState(HubLock, ActiveInstanceIndex, OldState);
+ }
+
+ throw;
}
}
+ else
+ {
+ CompleteWake(Instance, ActiveInstanceIndex, OldState);
+ }
- // The module is deprovisioned outside the lock to avoid blocking other operations.
- //
- // To ensure that no new provisioning can occur while we're deprovisioning,
- // we add the module ID to m_DeprovisioningModules and remove it once
- // deprovisioning is complete.
-
- auto _ = MakeGuard([&] {
- RwLock::ExclusiveLockScope _(m_Lock);
- m_DeprovisioningModules.erase(ModuleId);
- m_FreePorts.push_back(BasePort);
- });
+ return Response{m_WorkerPool ? EResponseCode::Accepted : EResponseCode::Completed};
+}
- Instance->Deprovision();
+void
+Hub::CompleteWake(StorageServerInstance::ExclusiveLockedPtr& Instance, size_t ActiveInstanceIndex, HubInstanceState OldState)
+{
+ const std::string ModuleId(Instance.GetModuleId());
+ const uint16_t Port = Instance.GetBasePort();
- return true;
+ try
+ {
+ Instance.Wake();
+ UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Provisioned);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Waking, HubInstanceState::Provisioned, Port, {});
+ Instance = {};
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed to wake storage server instance for module '{}': {}", ModuleId, Ex.what());
+ UpdateInstanceState(Instance, ActiveInstanceIndex, OldState);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Waking, OldState, Port, {});
+ Instance = {};
+ throw;
+ }
}
bool
-Hub::Find(std::string_view ModuleId, StorageServerInstance** OutInstance)
+Hub::Find(std::string_view ModuleId, InstanceInfo* OutInstanceInfo)
{
RwLock::SharedLockScope _(m_Lock);
- if (auto It = m_Instances.find(std::string(ModuleId)); It != m_Instances.end())
+ if (auto It = m_InstanceLookup.find(std::string(ModuleId)); It != m_InstanceLookup.end())
{
- if (OutInstance)
+ if (OutInstanceInfo)
{
- *OutInstance = It->second.get();
+ const size_t ActiveInstanceIndex = It->second;
+ ZEN_ASSERT(ActiveInstanceIndex < m_ActiveInstances.size());
+ const std::unique_ptr<StorageServerInstance>& Instance = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(Instance);
+ InstanceInfo Info{m_ActiveInstances[ActiveInstanceIndex].State.load(),
+ m_ActiveInstances[ActiveInstanceIndex].StateChangeTime.load()};
+ Info.Metrics = m_ActiveInstances[ActiveInstanceIndex].ProcessMetrics.Load();
+ Info.Port = Instance->GetBasePort();
+
+ *OutInstanceInfo = Info;
}
return true;
}
- else if (OutInstance)
- {
- *OutInstance = nullptr;
- }
return false;
}
void
-Hub::EnumerateModules(std::function<void(StorageServerInstance&)> Callback)
+Hub::EnumerateModules(std::function<void(std::string_view ModuleId, const InstanceInfo&)> Callback)
{
- RwLock::SharedLockScope _(m_Lock);
- for (auto& It : m_Instances)
+ std::vector<std::pair<std::string, InstanceInfo>> Infos;
+ {
+ RwLock::SharedLockScope _(m_Lock);
+ for (auto& [ModuleId, ActiveInstanceIndex] : m_InstanceLookup)
+ {
+ const std::unique_ptr<StorageServerInstance>& Instance = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(Instance);
+ InstanceInfo Info{m_ActiveInstances[ActiveInstanceIndex].State.load(),
+ m_ActiveInstances[ActiveInstanceIndex].StateChangeTime.load()};
+ Info.Metrics = m_ActiveInstances[ActiveInstanceIndex].ProcessMetrics.Load();
+ Info.Port = Instance->GetBasePort();
+
+ Infos.push_back(std::make_pair(std::string(Instance->GetModuleId()), Info));
+ }
+ }
+
+ for (const std::pair<std::string, InstanceInfo>& Info : Infos)
{
- Callback(*It.second);
+ Callback(Info.first, Info.second);
}
}
int
Hub::GetInstanceCount()
{
- RwLock::SharedLockScope _(m_Lock);
- return gsl::narrow_cast<int>(m_Instances.size());
+ return m_Lock.WithSharedLock([this]() { return gsl::narrow_cast<int>(m_InstanceLookup.size()); });
}
-void
-Hub::UpdateCapacityMetrics()
+bool
+Hub::CanProvisionInstanceLocked(std::string_view ModuleId, std::string& OutReason)
{
- m_HostMetrics = GetSystemMetrics();
+ ZEN_UNUSED(ModuleId);
+ if (m_FreeActiveInstanceIndexes.empty())
+ {
+ OutReason = fmt::format("instance limit ({}) exceeded", m_Config.InstanceLimit);
+
+ return false;
+ }
+
+ const uint64_t DiskUsedBytes = m_DiskSpace.Free <= m_DiskSpace.Total ? m_DiskSpace.Total - m_DiskSpace.Free : 0;
+ if (m_Config.ResourceLimits.DiskUsageBytes > 0 && DiskUsedBytes > m_Config.ResourceLimits.DiskUsageBytes)
+ {
+ OutReason =
+ fmt::format("disk usage ({}) exceeds ({})", NiceBytes(DiskUsedBytes), NiceBytes(m_Config.ResourceLimits.DiskUsageBytes));
+ return false;
+ }
- // Update per-instance metrics
+ const uint64_t RamUsedMiB = m_SystemMetrics.AvailSystemMemoryMiB <= m_SystemMetrics.SystemMemoryMiB
+ ? m_SystemMetrics.SystemMemoryMiB - m_SystemMetrics.AvailSystemMemoryMiB
+ : 0;
+ const uint64_t RamUsedBytes = RamUsedMiB * 1024 * 1024;
+ if (m_Config.ResourceLimits.MemoryUsageBytes > 0 && RamUsedBytes > m_Config.ResourceLimits.MemoryUsageBytes)
+ {
+ OutReason =
+ fmt::format("ram usage ({}) exceeds ({})", NiceBytes(RamUsedBytes), NiceBytes(m_Config.ResourceLimits.MemoryUsageBytes));
+ return false;
+ }
+
+ return true;
}
-void
-Hub::UpdateStats()
+uint16_t
+Hub::GetInstanceIndexAssignedPort(size_t ActiveInstanceIndex) const
{
- m_Lock.WithSharedLock([this] { m_MaxInstanceCount = Max(m_MaxInstanceCount, gsl::narrow_cast<int>(m_Instances.size())); });
+ return gsl::narrow<uint16_t>(m_Config.BasePortNumber + ActiveInstanceIndex);
}
bool
-Hub::CanProvisionInstance(std::string_view ModuleId, std::string& OutReason)
+Hub::IsInstancePort(uint16_t Port) const
{
- if (m_DeprovisioningModules.find(std::string(ModuleId)) != m_DeprovisioningModules.end())
+ if (Port < m_Config.BasePortNumber)
{
- OutReason = fmt::format("module '{}' is currently being deprovisioned", ModuleId);
+ return false;
+ }
+ size_t Index = Port - m_Config.BasePortNumber;
+ if (Index >= m_ActiveInstances.size())
+ {
+ return false;
+ }
+ return m_ActiveInstances[Index].State.load(std::memory_order_relaxed) != HubInstanceState::Unprovisioned;
+}
+HubInstanceState
+Hub::UpdateInstanceStateLocked(size_t ActiveInstanceIndex, HubInstanceState NewState)
+{
+ ZEN_ASSERT(ActiveInstanceIndex < m_ActiveInstances.size());
+ ZEN_ASSERT_SLOW([](HubInstanceState From, HubInstanceState To) {
+ switch (From)
+ {
+ case HubInstanceState::Unprovisioned:
+ return To == HubInstanceState::Provisioning;
+ case HubInstanceState::Provisioned:
+ return To == HubInstanceState::Hibernating || To == HubInstanceState::Deprovisioning || To == HubInstanceState::Crashed;
+ case HubInstanceState::Hibernated:
+ return To == HubInstanceState::Waking || To == HubInstanceState::Deprovisioning;
+ case HubInstanceState::Crashed:
+ return To == HubInstanceState::Provisioning || To == HubInstanceState::Deprovisioning || To == HubInstanceState::Recovering;
+ case HubInstanceState::Provisioning:
+ return To == HubInstanceState::Provisioned || To == HubInstanceState::Unprovisioned || To == HubInstanceState::Crashed;
+ case HubInstanceState::Hibernating:
+ return To == HubInstanceState::Hibernated || To == HubInstanceState::Provisioned;
+ case HubInstanceState::Waking:
+ return To == HubInstanceState::Provisioned || To == HubInstanceState::Hibernated;
+ case HubInstanceState::Deprovisioning:
+ return To == HubInstanceState::Unprovisioned || To == HubInstanceState::Provisioned || To == HubInstanceState::Hibernated ||
+ To == HubInstanceState::Crashed;
+ case HubInstanceState::Recovering:
+ return To == HubInstanceState::Provisioned || To == HubInstanceState::Unprovisioned;
+ }
return false;
+ }(m_ActiveInstances[ActiveInstanceIndex].State.load(), NewState));
+ const std::chrono::system_clock::time_point Now = std::chrono::system_clock::now();
+ m_ActiveInstances[ActiveInstanceIndex].LastKnownActivitySum.store(0);
+ m_ActiveInstances[ActiveInstanceIndex].LastActivityTime.store(Now);
+ m_ActiveInstances[ActiveInstanceIndex].StateChangeTime.store(Now);
+ return m_ActiveInstances[ActiveInstanceIndex].State.exchange(NewState);
+}
+
+void
+Hub::AttemptRecoverInstance(std::string_view ModuleId)
+{
+ StorageServerInstance::ExclusiveLockedPtr Instance;
+ size_t ActiveInstanceIndex = (size_t)-1;
+
+ {
+ RwLock::ExclusiveLockScope _(m_Lock);
+
+ auto It = m_InstanceLookup.find(std::string(ModuleId));
+ if (It == m_InstanceLookup.end())
+ {
+ return;
+ }
+
+ ActiveInstanceIndex = It->second;
+ ZEN_ASSERT(ActiveInstanceIndex < m_ActiveInstances.size());
+ std::unique_ptr<StorageServerInstance>& InstanceRaw = m_ActiveInstances[ActiveInstanceIndex].Instance;
+ ZEN_ASSERT(InstanceRaw);
+ HubInstanceState CurrentState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+ if (CurrentState != HubInstanceState::Crashed)
+ {
+ return;
+ }
+
+ Instance = m_ActiveInstances[ActiveInstanceIndex].Instance->LockExclusive(/*Wait*/ false);
+ if (!Instance)
+ {
+ // Instance lock is held by another operation; the watchdog will retry on the next cycle if the state is still Crashed.
+ return;
+ }
+
+ ZEN_ASSERT(!Instance.IsRunning());
+
+ (void)UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Recovering);
}
- if (m_ProvisioningModules.find(std::string(ModuleId)) != m_ProvisioningModules.end())
+ ZEN_ASSERT(Instance);
+ ZEN_ASSERT(ActiveInstanceIndex != (size_t)-1);
+ ZEN_ASSERT_SLOW(m_ActiveInstances[ActiveInstanceIndex].State.load() == HubInstanceState::Recovering);
+
+ NotifyStateUpdate(ModuleId, HubInstanceState::Crashed, HubInstanceState::Recovering, Instance.GetBasePort(), /*BaseUri*/ {});
+
+ // Dehydrate before trying to recover so any salvageable data is preserved.
+ try
{
- OutReason = fmt::format("module '{}' is currently being provisioned", ModuleId);
+ Instance.Deprovision();
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed to deprovision instance for module '{}' during crash recovery cleanup: {}", ModuleId, Ex.what());
+ NotifyStateUpdate(ModuleId, HubInstanceState::Recovering, HubInstanceState::Unprovisioned, Instance.GetBasePort(), /*BaseUri*/ {});
+ Instance = {};
+ std::unique_ptr<StorageServerInstance> DestroyInstance;
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ auto It = m_InstanceLookup.find(std::string(ModuleId));
+ ZEN_ASSERT_SLOW(It != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(ActiveInstanceIndex == It->second);
+
+ DestroyInstance = std::move(m_ActiveInstances[ActiveInstanceIndex].Instance);
+ m_FreeActiveInstanceIndexes.push_back(ActiveInstanceIndex);
+ m_InstanceLookup.erase(It);
+ (void)UpdateInstanceState(HubLock, ActiveInstanceIndex, HubInstanceState::Unprovisioned);
+ }
+ DestroyInstance.reset();
+ return;
+ }
- return false;
+ try
+ {
+ Instance.Provision();
+ UpdateInstanceState(Instance, ActiveInstanceIndex, HubInstanceState::Provisioned);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Recovering, HubInstanceState::Provisioned, Instance.GetBasePort(), /*BaseUri*/ {});
+ Instance = {};
}
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Failed to reprovision instance for module '{}' during crash recovery reprovision: {}", ModuleId, Ex.what());
+ NotifyStateUpdate(ModuleId, HubInstanceState::Recovering, HubInstanceState::Unprovisioned, Instance.GetBasePort(), /*BaseUri*/ {});
+ Instance = {};
+ std::unique_ptr<StorageServerInstance> DestroyInstance;
+ {
+ RwLock::ExclusiveLockScope HubLock(m_Lock);
+ auto It = m_InstanceLookup.find(std::string(ModuleId));
+ ZEN_ASSERT_SLOW(It != m_InstanceLookup.end());
+ ZEN_ASSERT_SLOW(ActiveInstanceIndex == It->second);
+
+ DestroyInstance = std::move(m_ActiveInstances[ActiveInstanceIndex].Instance);
+ m_FreeActiveInstanceIndexes.push_back(ActiveInstanceIndex);
+ m_InstanceLookup.erase(It);
+ (void)UpdateInstanceState(HubLock, ActiveInstanceIndex, HubInstanceState::Unprovisioned);
+ }
+ DestroyInstance.reset();
+ return;
+ }
+}
+
+bool
+Hub::CheckInstanceStatus(HttpClient& ActivityCheckClient,
+ StorageServerInstance::SharedLockedPtr&& LockedInstance,
+ size_t ActiveInstanceIndex)
+{
+ const std::string ModuleId(LockedInstance.GetModuleId());
- if (gsl::narrow_cast<int>(m_Instances.size()) >= m_Config.InstanceLimit)
+ HubInstanceState InstanceState = m_ActiveInstances[ActiveInstanceIndex].State.load();
+ if (LockedInstance.IsRunning())
{
- OutReason = fmt::format("instance limit ({}) exceeded", m_Config.InstanceLimit);
+ m_ActiveInstances[ActiveInstanceIndex].ProcessMetrics.Store(LockedInstance.GetProcessMetrics());
+ if (InstanceState == HubInstanceState::Provisioned)
+ {
+ const uint16_t Port = LockedInstance.GetBasePort();
+ const uint64_t PreviousActivitySum = m_ActiveInstances[ActiveInstanceIndex].LastKnownActivitySum.load();
+ const std::chrono::system_clock::time_point LastActivityTime = m_ActiveInstances[ActiveInstanceIndex].LastActivityTime.load();
+
+ const std::chrono::system_clock::time_point Now = std::chrono::system_clock::now();
+
+ // We do the activity check without holding a lock to the instance
+ LockedInstance = {};
+
+ uint64_t ActivitySum = PreviousActivitySum;
+
+ std::chrono::system_clock::time_point NextCheckTime =
+ LastActivityTime + m_Config.WatchDog.ProvisionedInactivityTimeout - m_Config.WatchDog.InactivityCheckMargin;
+ if (Now >= NextCheckTime)
+ {
+ ActivityCheckClient.SetBaseUri(fmt::format("http://localhost:{}", Port));
+ HttpClient::Response Result =
+ ActivityCheckClient.Get("/stats/activity_counters", HttpClient::Accept(HttpContentType::kCbObject));
+ if (Result.IsSuccess())
+ {
+ CbObject Response = Result.AsObject();
+ if (Response)
+ {
+ ActivitySum = Response["sum"].AsUInt64();
+ }
+ }
+ }
+
+ if (ActivitySum != PreviousActivitySum)
+ {
+ m_Lock.WithSharedLock([this, InstanceState, PreviousActivitySum, &LastActivityTime, ActivitySum, Now, ModuleId]() {
+ if (auto It = m_InstanceLookup.find(ModuleId); It != m_InstanceLookup.end())
+ {
+ const uint64_t ActiveInstanceIndex = It->second;
+ ActiveInstance& Instance = m_ActiveInstances[ActiveInstanceIndex];
+
+ HubInstanceState CurrentState = Instance.State.load();
+ if (CurrentState == InstanceState)
+ {
+ if (Instance.LastActivityTime.load() == LastActivityTime &&
+ Instance.LastKnownActivitySum.load() == PreviousActivitySum)
+ {
+ Instance.LastActivityTime.store(Now);
+ Instance.LastKnownActivitySum.store(ActivitySum);
+ }
+ }
+ }
+ });
+ }
+ else if (LastActivityTime + m_Config.WatchDog.ProvisionedInactivityTimeout < Now)
+ {
+ ZEN_INFO("Instance {} has not been active for {}, attempting deprovision...",
+ ModuleId,
+ NiceTimeSpanMs(std::chrono::duration_cast<std::chrono::milliseconds>(Now - LastActivityTime).count()));
+ (void)InternalDeprovision(
+ ModuleId,
+ [ModuleId, InstanceState, LastActivityTime, PreviousActivitySum](ActiveInstance& Instance) -> bool {
+ HubInstanceState CurrentState = Instance.State.load();
+ if (CurrentState != InstanceState)
+ {
+ ZEN_INFO("Instance {} idle deprovision aborted - state changed to {}", ModuleId, ToString(CurrentState));
+ return false;
+ }
+ if (Instance.LastActivityTime.load() != LastActivityTime ||
+ Instance.LastKnownActivitySum.load() != PreviousActivitySum)
+ {
+ ZEN_INFO("Instance {} idle deprovision aborted due to activity", ModuleId);
+ return false;
+ }
+ return true;
+ });
+ }
+ }
+
+ return true;
+ }
+ else if (InstanceState == HubInstanceState::Provisioned)
+ {
+ // Process is not running but state says it should be - instance died unexpectedly.
+ const uint16_t Port = LockedInstance.GetBasePort();
+ UpdateInstanceState(LockedInstance, ActiveInstanceIndex, HubInstanceState::Crashed);
+ NotifyStateUpdate(ModuleId, HubInstanceState::Provisioned, HubInstanceState::Crashed, Port, {});
+ LockedInstance = {};
return false;
}
+ else if (InstanceState == HubInstanceState::Hibernated)
+ {
+ // Process is not running - no HTTP activity check is possible.
+ // Use a pure time-based check; the margin window does not apply here.
+ const std::chrono::system_clock::time_point LastActivityTime = m_ActiveInstances[ActiveInstanceIndex].LastActivityTime.load();
+ const uint64_t PreviousActivitySum = m_ActiveInstances[ActiveInstanceIndex].LastKnownActivitySum.load();
+ const std::chrono::system_clock::time_point Now = std::chrono::system_clock::now();
+ LockedInstance = {};
+
+ if (LastActivityTime + m_Config.WatchDog.HibernatedInactivityTimeout < Now)
+ {
+ ZEN_INFO("Hibernated instance {} has not been active for {}, attempting deprovision...",
+ ModuleId,
+ NiceTimeSpanMs(std::chrono::duration_cast<std::chrono::milliseconds>(Now - LastActivityTime).count()));
+ (void)InternalDeprovision(
+ ModuleId,
+ [ModuleId, InstanceState, LastActivityTime, PreviousActivitySum](ActiveInstance& Instance) -> bool {
+ HubInstanceState CurrentState = Instance.State.load();
+ if (CurrentState != InstanceState)
+ {
+ ZEN_INFO("Hibernated instance {} idle deprovision aborted - state changed to {}", ModuleId, ToString(CurrentState));
+ return false;
+ }
+ if (Instance.LastActivityTime.load() != LastActivityTime || Instance.LastKnownActivitySum.load() != PreviousActivitySum)
+ {
+ ZEN_INFO("Hibernated instance {} idle deprovision aborted due to activity", ModuleId);
+ return false;
+ }
+ return true;
+ });
+ }
+ return true;
+ }
+ else
+ {
+ // transitional state (Provisioning, Deprovisioning, Hibernating, Waking, Recovering) - expected, skip.
+ // Crashed is handled above via AttemptRecoverInstance; it appears here only when the instance
+ // lock was busy on a previous cycle and recovery is already pending.
+ return true;
+ }
+}
- // Since deprovisioning happens outside the lock and we don't add the port back until the instance is full shut down we might be under
- // the instance limit but all ports may be in use
- if (m_FreePorts.empty())
+void
+Hub::UpdateMachineMetrics()
+{
+ try
{
- OutReason = fmt::format("no free ports available, deprovisioning of instances might be in flight ({})",
- m_Config.InstanceLimit - m_Instances.size());
+ bool DiskSpaceOk = false;
+ DiskSpace Disk;
- return false;
+ std::filesystem::path ChildDir = m_RunEnvironment.GetChildBaseDir();
+ if (!ChildDir.empty())
+ {
+ if (DiskSpaceInfo(ChildDir, Disk))
+ {
+ DiskSpaceOk = true;
+ }
+ else
+ {
+ ZEN_WARN("Failed to query disk space for '{}'; disk-based provisioning limits will not be enforced", ChildDir);
+ }
+ }
+
+ SystemMetrics Metrics = GetSystemMetrics();
+
+ m_Lock.WithExclusiveLock([&]() {
+ if (DiskSpaceOk)
+ {
+ m_DiskSpace = Disk;
+ }
+ m_SystemMetrics = Metrics;
+ });
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("Failed to update machine metrics. Reason: {}", Ex.what());
}
+}
- // TODO: handle additional resource metrics
+void
+Hub::WatchDog()
+{
+ const uint64_t CycleIntervalMs = std::chrono::duration_cast<std::chrono::milliseconds>(m_Config.WatchDog.CycleInterval).count();
+ const uint64_t CycleProcessingBudgetMs =
+ std::chrono::duration_cast<std::chrono::milliseconds>(m_Config.WatchDog.CycleProcessingBudget).count();
+ const uint64_t InstanceCheckThrottleMs =
+ std::chrono::duration_cast<std::chrono::milliseconds>(m_Config.WatchDog.InstanceCheckThrottle).count();
+
+ HttpClient ActivityCheckClient("http://localhost",
+ HttpClientSettings{.ConnectTimeout = m_Config.WatchDog.ActivityCheckConnectTimeout,
+ .Timeout = m_Config.WatchDog.ActivityCheckRequestTimeout},
+ [&]() -> bool { return m_WatchDogEvent.Wait(0); });
+
+ size_t CheckInstanceIndex = SIZE_MAX; // first increment wraps to 0
+ while (!m_ShutdownFlag.load() && !m_WatchDogEvent.Wait(gsl::narrow<int>(CycleIntervalMs)))
+ {
+ try
+ {
+ UpdateMachineMetrics();
- return true;
+ // Snapshot slot count. We iterate all slots (including freed nulls) so
+ // round-robin coverage is not skewed by deprovisioned entries.
+ size_t SlotsRemaining = m_Lock.WithSharedLock([this]() { return m_ActiveInstances.size(); });
+
+ Stopwatch Timer;
+ bool ShuttingDown = m_ShutdownFlag.load();
+ while (SlotsRemaining > 0 && Timer.GetElapsedTimeMs() < CycleProcessingBudgetMs && !ShuttingDown)
+ {
+ StorageServerInstance::SharedLockedPtr LockedInstance;
+ m_Lock.WithSharedLock([this, &CheckInstanceIndex, &LockedInstance, &SlotsRemaining]() {
+ // Advance through null (freed) slots under a single lock acquisition.
+ while (SlotsRemaining > 0)
+ {
+ SlotsRemaining--;
+ CheckInstanceIndex++;
+ if (CheckInstanceIndex >= m_ActiveInstances.size())
+ {
+ CheckInstanceIndex = 0;
+ }
+ StorageServerInstance* Instance = m_ActiveInstances[CheckInstanceIndex].Instance.get();
+ if (Instance)
+ {
+ LockedInstance = Instance->LockShared(/*Wait*/ false);
+ break; // Found a live slot (locked or busy); stop scanning this batch.
+ }
+ }
+ });
+
+ if (!LockedInstance)
+ {
+ // Either all remaining slots were null, or the live slot's lock was busy -- move on.
+ continue;
+ }
+
+ std::string ModuleId(LockedInstance.GetModuleId());
+
+ try
+ {
+ bool InstanceIsOk = CheckInstanceStatus(ActivityCheckClient, std::move(LockedInstance), CheckInstanceIndex);
+ if (InstanceIsOk)
+ {
+ ShuttingDown = m_WatchDogEvent.Wait(gsl::narrow<int>(InstanceCheckThrottleMs));
+ }
+ else
+ {
+ ZEN_WARN("Instance for module '{}' is not running, attempting recovery", ModuleId);
+ AttemptRecoverInstance(ModuleId);
+ }
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("Failed to check status of module {}. Reason: {}", ModuleId, Ex.what());
+ }
+ ShuttingDown |= m_ShutdownFlag.load();
+ }
+ }
+ catch (const std::exception& Ex)
+ {
+ // TODO: Catch specific errors such as asserts, OOM, OOD, system_error etc
+ ZEN_ERROR("Hub watchdog threw exception: {}", Ex.what());
+ }
+ }
+}
+
+void
+Hub::NotifyStateUpdate(std::string_view ModuleId,
+ HubInstanceState OldState,
+ HubInstanceState NewState,
+ uint16_t BasePort,
+ std::string_view BaseUri)
+{
+ if (m_ModuleStateChangeCallback && OldState != NewState)
+ {
+ try
+ {
+ m_ModuleStateChangeCallback(ModuleId,
+ HubProvisionedInstanceInfo{.BaseUri = std::string(BaseUri), .Port = BasePort},
+ OldState,
+ NewState);
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_ERROR("Module state change callback for module '{}' failed. Reason: '{}'", ModuleId, Ex.what());
+ }
+ }
}
#if ZEN_WITH_TESTS
TEST_SUITE_BEGIN("server.hub");
+static const HttpClientSettings kFastTimeout{.ConnectTimeout = std::chrono::milliseconds(200)};
+
namespace hub_testutils {
ZenServerEnvironment MakeHubEnvironment(const std::filesystem::path& BaseDir)
@@ -474,12 +1531,79 @@ namespace hub_testutils {
return ZenServerEnvironment(ZenServerEnvironment::Hub, GetRunningExecutablePath().parent_path(), BaseDir);
}
- std::unique_ptr<Hub> MakeHub(const std::filesystem::path& BaseDir,
- Hub::Configuration Config = {},
- Hub::ProvisionModuleCallbackFunc ProvisionCallback = {},
- Hub::ProvisionModuleCallbackFunc DeprovisionCallback = {})
+ std::unique_ptr<Hub> MakeHub(const std::filesystem::path& BaseDir,
+ Hub::Configuration Config = {},
+ Hub::AsyncModuleStateChangeCallbackFunc StateChangeCallback = {},
+ WorkerThreadPool* WorkerPool = nullptr)
{
- return std::make_unique<Hub>(Config, MakeHubEnvironment(BaseDir), std::move(ProvisionCallback), std::move(DeprovisionCallback));
+ return std::make_unique<Hub>(Config, MakeHubEnvironment(BaseDir), WorkerPool, std::move(StateChangeCallback));
+ }
+
+ struct CallbackRecord
+ {
+ std::string ModuleId;
+ uint16_t Port;
+ };
+
+ struct StateChangeCapture
+ {
+ RwLock CallbackMutex;
+ std::vector<CallbackRecord> ProvisionCallbacks;
+ std::vector<CallbackRecord> DeprovisionCallbacks;
+
+ auto CaptureFunc()
+ {
+ return [this](std::string_view ModuleId,
+ const HubProvisionedInstanceInfo& Info,
+ HubInstanceState PreviousState,
+ HubInstanceState NewState) {
+ ZEN_UNUSED(PreviousState);
+ if (NewState == HubInstanceState::Provisioned)
+ {
+ CallbackMutex.WithExclusiveLock([&]() { ProvisionCallbacks.push_back({std::string(ModuleId), Info.Port}); });
+ }
+ else if (NewState == HubInstanceState::Unprovisioned)
+ {
+ CallbackMutex.WithExclusiveLock([&]() { DeprovisionCallbacks.push_back({std::string(ModuleId), Info.Port}); });
+ }
+ };
+ }
+ };
+
+ // Poll until Find() returns false for the given module (i.e. async deprovision completes).
+ static bool WaitForInstanceGone(Hub& HubInstance,
+ std::string_view ModuleId,
+ std::chrono::milliseconds PollInterval = std::chrono::milliseconds(50),
+ std::chrono::seconds Timeout = std::chrono::seconds(30))
+ {
+ const auto Deadline = std::chrono::steady_clock::now() + Timeout;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ if (!HubInstance.Find(ModuleId))
+ {
+ return true;
+ }
+ std::this_thread::sleep_for(PollInterval);
+ }
+ return !HubInstance.Find(ModuleId);
+ }
+
+ // Poll until GetInstanceCount() reaches ExpectedCount (i.e. all async deprovisions complete).
+ static bool WaitForInstanceCount(Hub& HubInstance,
+ int ExpectedCount,
+ std::chrono::milliseconds PollInterval = std::chrono::milliseconds(50),
+ std::chrono::seconds Timeout = std::chrono::seconds(30))
+ {
+ const auto Deadline = std::chrono::steady_clock::now() + Timeout;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ if (HubInstance.GetInstanceCount() == ExpectedCount)
+ {
+ return true;
+ }
+ std::this_thread::sleep_for(PollInterval);
+ }
+ return HubInstance.GetInstanceCount() == ExpectedCount;
}
} // namespace hub_testutils
@@ -493,17 +1617,30 @@ TEST_CASE("hub.provision_basic")
CHECK_FALSE(HubInstance->Find("module_a"));
HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool ProvisionResult = HubInstance->Provision("module_a", Info, Reason);
- REQUIRE_MESSAGE(ProvisionResult, Reason);
+ const Hub::Response ProvisionResult = HubInstance->Provision("module_a", Info);
+ REQUIRE_MESSAGE(ProvisionResult.ResponseCode == Hub::EResponseCode::Completed, ProvisionResult.Message);
CHECK_NE(Info.Port, 0);
CHECK_EQ(HubInstance->GetInstanceCount(), 1);
- CHECK(HubInstance->Find("module_a"));
+ Hub::InstanceInfo InstanceInfo;
+ REQUIRE(HubInstance->Find("module_a", &InstanceInfo));
+ CHECK_EQ(InstanceInfo.State, HubInstanceState::Provisioned);
+ CHECK_NE(InstanceInfo.StateChangeTime, std::chrono::system_clock::time_point::min());
+ CHECK_LE(InstanceInfo.StateChangeTime, std::chrono::system_clock::now());
+
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
- const bool DeprovisionResult = HubInstance->Deprovision("module_a", Reason);
- CHECK(DeprovisionResult);
+ const Hub::Response DeprovisionResult = HubInstance->Deprovision("module_a");
+ CHECK(DeprovisionResult.ResponseCode == Hub::EResponseCode::Completed);
CHECK_EQ(HubInstance->GetInstanceCount(), 0);
CHECK_FALSE(HubInstance->Find("module_a"));
+
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
}
TEST_CASE("hub.provision_config")
@@ -527,72 +1664,121 @@ TEST_CASE("hub.provision_config")
CHECK_FALSE(HubInstance->Find("module_a"));
HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool ProvisionResult = HubInstance->Provision("module_a", Info, Reason);
- REQUIRE_MESSAGE(ProvisionResult, Reason);
+ const Hub::Response ProvisionResult = HubInstance->Provision("module_a", Info);
+ REQUIRE_MESSAGE(ProvisionResult.ResponseCode == Hub::EResponseCode::Completed, ProvisionResult.Message);
CHECK_NE(Info.Port, 0);
CHECK_EQ(HubInstance->GetInstanceCount(), 1);
- CHECK(HubInstance->Find("module_a"));
+ Hub::InstanceInfo InstanceInfo;
+ REQUIRE(HubInstance->Find("module_a", &InstanceInfo));
+ CHECK_EQ(InstanceInfo.State, HubInstanceState::Provisioned);
HttpClient Client(fmt::format("http://127.0.0.1:{}{}", Info.Port, Info.BaseUri));
HttpClient::Response TestResponse = Client.Get("/status/builds");
CHECK(TestResponse.IsSuccess());
CHECK(TestResponse.AsObject()["ok"].AsBool());
- const bool DeprovisionResult = HubInstance->Deprovision("module_a", Reason);
- CHECK(DeprovisionResult);
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
+
+ const Hub::Response DeprovisionResult = HubInstance->Deprovision("module_a");
+ CHECK(DeprovisionResult.ResponseCode == Hub::EResponseCode::Completed);
CHECK_EQ(HubInstance->GetInstanceCount(), 0);
CHECK_FALSE(HubInstance->Find("module_a"));
+
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
}
TEST_CASE("hub.provision_callbacks")
{
ScopedTemporaryDirectory TempDir;
- struct CallbackRecord
- {
- std::string ModuleId;
- uint16_t Port;
- };
- RwLock CallbackMutex;
- std::vector<CallbackRecord> ProvisionRecords;
- std::vector<CallbackRecord> DeprovisionRecords;
-
- auto ProvisionCb = [&](std::string_view ModuleId, const HubProvisionedInstanceInfo& Info) {
- CallbackMutex.WithExclusiveLock([&]() { ProvisionRecords.push_back({std::string(ModuleId), Info.Port}); });
- };
- auto DeprovisionCb = [&](std::string_view ModuleId, const HubProvisionedInstanceInfo& Info) {
- CallbackMutex.WithExclusiveLock([&]() { DeprovisionRecords.push_back({std::string(ModuleId), Info.Port}); });
- };
+ hub_testutils::StateChangeCapture CaptureInstance;
- std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), {}, std::move(ProvisionCb), std::move(DeprovisionCb));
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), {}, CaptureInstance.CaptureFunc());
HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool ProvisionResult = HubInstance->Provision("cb_module", Info, Reason);
- REQUIRE_MESSAGE(ProvisionResult, Reason);
+ const Hub::Response ProvisionResult = HubInstance->Provision("cb_module", Info);
+ REQUIRE_MESSAGE(ProvisionResult.ResponseCode == Hub::EResponseCode::Completed, ProvisionResult.Message);
+
+ {
+ RwLock::SharedLockScope _(CaptureInstance.CallbackMutex);
+ REQUIRE_EQ(CaptureInstance.ProvisionCallbacks.size(), 1u);
+ CHECK_EQ(CaptureInstance.ProvisionCallbacks[0].ModuleId, "cb_module");
+ CHECK_EQ(CaptureInstance.ProvisionCallbacks[0].Port, Info.Port);
+ CHECK_NE(CaptureInstance.ProvisionCallbacks[0].Port, 0);
+ }
{
- RwLock::SharedLockScope _(CallbackMutex);
- REQUIRE_EQ(ProvisionRecords.size(), 1u);
- CHECK_EQ(ProvisionRecords[0].ModuleId, "cb_module");
- CHECK_EQ(ProvisionRecords[0].Port, Info.Port);
- CHECK_NE(ProvisionRecords[0].Port, 0);
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
}
- const bool DeprovisionResult = HubInstance->Deprovision("cb_module", Reason);
- CHECK(DeprovisionResult);
+ const Hub::Response DeprovisionResult = HubInstance->Deprovision("cb_module");
+ CHECK(DeprovisionResult.ResponseCode == Hub::EResponseCode::Completed);
+
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
{
- RwLock::SharedLockScope _(CallbackMutex);
- REQUIRE_EQ(DeprovisionRecords.size(), 1u);
- CHECK_EQ(DeprovisionRecords[0].ModuleId, "cb_module");
- CHECK_NE(DeprovisionRecords[0].Port, 0);
- CHECK_EQ(ProvisionRecords.size(), 1u);
+ RwLock::SharedLockScope _(CaptureInstance.CallbackMutex);
+ REQUIRE_EQ(CaptureInstance.DeprovisionCallbacks.size(), 1u);
+ CHECK_EQ(CaptureInstance.DeprovisionCallbacks[0].ModuleId, "cb_module");
+ CHECK_EQ(CaptureInstance.DeprovisionCallbacks[0].Port, Info.Port);
+ CHECK_EQ(CaptureInstance.DeprovisionCallbacks.size(), 1u);
}
}
+TEST_CASE("hub.provision_callback_sequence")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ struct TransitionRecord
+ {
+ HubInstanceState OldState;
+ HubInstanceState NewState;
+ };
+ RwLock CaptureMutex;
+ std::vector<TransitionRecord> Transitions;
+
+ auto CaptureFunc =
+ [&](std::string_view ModuleId, const HubProvisionedInstanceInfo& Info, HubInstanceState OldState, HubInstanceState NewState) {
+ ZEN_UNUSED(ModuleId);
+ ZEN_UNUSED(Info);
+ CaptureMutex.WithExclusiveLock([&]() { Transitions.push_back({OldState, NewState}); });
+ };
+
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), {}, std::move(CaptureFunc));
+
+ HubProvisionedInstanceInfo Info;
+ {
+ const Hub::Response R = HubInstance->Provision("seq_module", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+ {
+ const Hub::Response R = HubInstance->Deprovision("seq_module");
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ RwLock::SharedLockScope _(CaptureMutex);
+ REQUIRE_EQ(Transitions.size(), 4u);
+ CHECK_EQ(Transitions[0].OldState, HubInstanceState::Unprovisioned);
+ CHECK_EQ(Transitions[0].NewState, HubInstanceState::Provisioning);
+ CHECK_EQ(Transitions[1].OldState, HubInstanceState::Provisioning);
+ CHECK_EQ(Transitions[1].NewState, HubInstanceState::Provisioned);
+ CHECK_EQ(Transitions[2].OldState, HubInstanceState::Provisioned);
+ CHECK_EQ(Transitions[2].NewState, HubInstanceState::Deprovisioning);
+ CHECK_EQ(Transitions[3].OldState, HubInstanceState::Deprovisioning);
+ CHECK_EQ(Transitions[3].NewState, HubInstanceState::Unprovisioned);
+}
+
TEST_CASE("hub.instance_limit")
{
ScopedTemporaryDirectory TempDir;
@@ -603,66 +1789,72 @@ TEST_CASE("hub.instance_limit")
std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool FirstResult = HubInstance->Provision("limit_a", Info, Reason);
- REQUIRE_MESSAGE(FirstResult, Reason);
+ const Hub::Response FirstResult = HubInstance->Provision("limit_a", Info);
+ REQUIRE_MESSAGE(FirstResult.ResponseCode == Hub::EResponseCode::Completed, FirstResult.Message);
- const bool SecondResult = HubInstance->Provision("limit_b", Info, Reason);
- REQUIRE_MESSAGE(SecondResult, Reason);
+ const Hub::Response SecondResult = HubInstance->Provision("limit_b", Info);
+ REQUIRE_MESSAGE(SecondResult.ResponseCode == Hub::EResponseCode::Completed, SecondResult.Message);
CHECK_EQ(HubInstance->GetInstanceCount(), 2);
- Reason.clear();
- const bool ThirdResult = HubInstance->Provision("limit_c", Info, Reason);
- CHECK_FALSE(ThirdResult);
+ const Hub::Response ThirdResult = HubInstance->Provision("limit_c", Info);
+ CHECK(ThirdResult.ResponseCode == Hub::EResponseCode::Rejected);
CHECK_EQ(HubInstance->GetInstanceCount(), 2);
- CHECK_NE(Reason.find("instance limit"), std::string::npos);
+ CHECK_NE(ThirdResult.Message.find("instance limit"), std::string::npos);
- HubInstance->Deprovision("limit_a", Reason);
+ HubInstance->Deprovision("limit_a");
CHECK_EQ(HubInstance->GetInstanceCount(), 1);
- Reason.clear();
- const bool FourthResult = HubInstance->Provision("limit_d", Info, Reason);
- CHECK_MESSAGE(FourthResult, Reason);
+ const Hub::Response FourthResult = HubInstance->Provision("limit_d", Info);
+ CHECK_MESSAGE(FourthResult.ResponseCode == Hub::EResponseCode::Completed, FourthResult.Message);
CHECK_EQ(HubInstance->GetInstanceCount(), 2);
}
-TEST_CASE("hub.deprovision_nonexistent")
-{
- ScopedTemporaryDirectory TempDir;
- std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path());
-
- std::string Reason;
- const bool Result = HubInstance->Deprovision("never_provisioned", Reason);
- CHECK_FALSE(Result);
- CHECK(Reason.empty());
- CHECK_EQ(HubInstance->GetInstanceCount(), 0);
-}
-
TEST_CASE("hub.enumerate_modules")
{
ScopedTemporaryDirectory TempDir;
std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path());
HubProvisionedInstanceInfo Info;
- std::string Reason;
- REQUIRE_MESSAGE(HubInstance->Provision("enum_a", Info, Reason), Reason);
- REQUIRE_MESSAGE(HubInstance->Provision("enum_b", Info, Reason), Reason);
+ {
+ const Hub::Response R = HubInstance->Provision("enum_a", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+ {
+ const Hub::Response R = HubInstance->Provision("enum_b", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
std::vector<std::string> Ids;
- HubInstance->EnumerateModules([&](StorageServerInstance& Instance) { Ids.push_back(std::string(Instance.GetModuleId())); });
+ int ProvisionedCount = 0;
+ HubInstance->EnumerateModules([&](std::string_view ModuleId, const Hub::InstanceInfo& InstanceInfo) {
+ Ids.push_back(std::string(ModuleId));
+ if (InstanceInfo.State == HubInstanceState::Provisioned)
+ {
+ ProvisionedCount++;
+ }
+ });
CHECK_EQ(Ids.size(), 2u);
+ CHECK_EQ(ProvisionedCount, 2);
const bool FoundA = std::find(Ids.begin(), Ids.end(), "enum_a") != Ids.end();
const bool FoundB = std::find(Ids.begin(), Ids.end(), "enum_b") != Ids.end();
CHECK(FoundA);
CHECK(FoundB);
- HubInstance->Deprovision("enum_a", Reason);
+ HubInstance->Deprovision("enum_a");
Ids.clear();
- HubInstance->EnumerateModules([&](StorageServerInstance& Instance) { Ids.push_back(std::string(Instance.GetModuleId())); });
+ ProvisionedCount = 0;
+ HubInstance->EnumerateModules([&](std::string_view ModuleId, const Hub::InstanceInfo& InstanceInfo) {
+ Ids.push_back(std::string(ModuleId));
+ if (InstanceInfo.State == HubInstanceState::Provisioned)
+ {
+ ProvisionedCount++;
+ }
+ });
REQUIRE_EQ(Ids.size(), 1u);
CHECK_EQ(Ids[0], "enum_b");
+ CHECK_EQ(ProvisionedCount, 1);
}
TEST_CASE("hub.max_instance_count")
@@ -673,99 +1865,26 @@ TEST_CASE("hub.max_instance_count")
CHECK_EQ(HubInstance->GetMaxInstanceCount(), 0);
HubProvisionedInstanceInfo Info;
- std::string Reason;
- REQUIRE_MESSAGE(HubInstance->Provision("max_a", Info, Reason), Reason);
+ {
+ const Hub::Response R = HubInstance->Provision("max_a", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
CHECK_GE(HubInstance->GetMaxInstanceCount(), 1);
- REQUIRE_MESSAGE(HubInstance->Provision("max_b", Info, Reason), Reason);
+ {
+ const Hub::Response R = HubInstance->Provision("max_b", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
CHECK_GE(HubInstance->GetMaxInstanceCount(), 2);
const int MaxAfterTwo = HubInstance->GetMaxInstanceCount();
- HubInstance->Deprovision("max_a", Reason);
+ HubInstance->Deprovision("max_a");
CHECK_EQ(HubInstance->GetInstanceCount(), 1);
CHECK_EQ(HubInstance->GetMaxInstanceCount(), MaxAfterTwo);
}
-TEST_CASE("hub.concurrent")
-{
- ScopedTemporaryDirectory TempDir;
- Hub::Configuration Config;
- Config.BasePortNumber = 22000;
- Config.InstanceLimit = 10;
-
- std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
-
- constexpr int kHalf = 3;
-
- // Serially pre-provision kHalf modules
- for (int I = 0; I < kHalf; ++I)
- {
- HubProvisionedInstanceInfo Info;
- std::string Reason;
- REQUIRE_MESSAGE(HubInstance->Provision(fmt::format("pre_{}", I), Info, Reason), Reason);
- }
- CHECK_EQ(HubInstance->GetInstanceCount(), kHalf);
-
- // Simultaneously:
- // Provisioner pool → provisions kHalf new modules ("new_0" .. "new_N")
- // Deprovisioner pool → deprovisions the kHalf pre-provisioned modules ("pre_0" .. "pre_N")
- // The two pools use distinct OS threads, so provisions and deprovisions are interleaved.
-
- // Use int rather than bool to avoid std::vector<bool> bitfield packing,
- // which would cause data races on concurrent per-index writes.
- std::vector<int> ProvisionResults(kHalf, 0);
- std::vector<std::string> ProvisionReasons(kHalf);
- std::vector<int> DeprovisionResults(kHalf, 0);
-
- {
- WorkerThreadPool Provisioners(kHalf, "hub_test_provisioners");
- WorkerThreadPool Deprovisioneers(kHalf, "hub_test_deprovisioneers");
-
- std::vector<std::future<void>> ProvisionFutures(kHalf);
- std::vector<std::future<void>> DeprovisionFutures(kHalf);
-
- for (int I = 0; I < kHalf; ++I)
- {
- ProvisionFutures[I] = Provisioners.EnqueueTask(std::packaged_task<void()>([&, I] {
- HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool Result =
- HubInstance->Provision(fmt::format("new_{}", I), Info, Reason);
- ProvisionResults[I] = Result ? 1 : 0;
- ProvisionReasons[I] = Reason;
- }),
- WorkerThreadPool::EMode::EnableBacklog);
-
- DeprovisionFutures[I] = Deprovisioneers.EnqueueTask(std::packaged_task<void()>([&, I] {
- std::string Reason;
- const bool Result =
- HubInstance->Deprovision(fmt::format("pre_{}", I), Reason);
- DeprovisionResults[I] = Result ? 1 : 0;
- }),
- WorkerThreadPool::EMode::EnableBacklog);
- }
-
- for (std::future<void>& F : ProvisionFutures)
- {
- F.get();
- }
- for (std::future<void>& F : DeprovisionFutures)
- {
- F.get();
- }
- }
-
- for (int I = 0; I < kHalf; ++I)
- {
- CHECK_MESSAGE(ProvisionResults[I] != 0, ProvisionReasons[I]);
- CHECK(DeprovisionResults[I] != 0);
- }
- // Only the newly provisioned modules should remain
- CHECK_EQ(HubInstance->GetInstanceCount(), kHalf);
-}
-
TEST_CASE("hub.concurrent_callbacks")
{
ScopedTemporaryDirectory TempDir;
@@ -773,23 +1892,9 @@ TEST_CASE("hub.concurrent_callbacks")
Config.BasePortNumber = 22300;
Config.InstanceLimit = 10;
- struct CallbackRecord
- {
- std::string ModuleId;
- uint16_t Port;
- };
- RwLock CallbackMutex;
- std::vector<CallbackRecord> ProvisionCallbacks;
- std::vector<CallbackRecord> DeprovisionCallbacks;
-
- auto ProvisionCb = [&](std::string_view ModuleId, const HubProvisionedInstanceInfo& Info) {
- CallbackMutex.WithExclusiveLock([&]() { ProvisionCallbacks.push_back({std::string(ModuleId), Info.Port}); });
- };
- auto DeprovisionCb = [&](std::string_view ModuleId, const HubProvisionedInstanceInfo& Info) {
- CallbackMutex.WithExclusiveLock([&]() { DeprovisionCallbacks.push_back({std::string(ModuleId), Info.Port}); });
- };
+ hub_testutils::StateChangeCapture CaptureInstance;
- std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, std::move(ProvisionCb), std::move(DeprovisionCb));
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, CaptureInstance.CaptureFunc());
constexpr int kHalf = 3;
@@ -798,15 +1903,15 @@ TEST_CASE("hub.concurrent_callbacks")
for (int I = 0; I < kHalf; ++I)
{
HubProvisionedInstanceInfo Info;
- std::string Reason;
- REQUIRE_MESSAGE(HubInstance->Provision(fmt::format("pre_{}", I), Info, Reason), Reason);
+ const Hub::Response ProvR = HubInstance->Provision(fmt::format("pre_{}", I), Info);
+ REQUIRE_MESSAGE(ProvR.ResponseCode == Hub::EResponseCode::Completed, ProvR.Message);
}
CHECK_EQ(HubInstance->GetInstanceCount(), kHalf);
{
- RwLock::ExclusiveLockScope _(CallbackMutex);
- REQUIRE_EQ(ProvisionCallbacks.size(), static_cast<size_t>(kHalf));
- ProvisionCallbacks.clear();
+ RwLock::ExclusiveLockScope _(CaptureInstance.CallbackMutex);
+ REQUIRE_EQ(CaptureInstance.ProvisionCallbacks.size(), static_cast<size_t>(kHalf));
+ CaptureInstance.ProvisionCallbacks.clear();
}
// Concurrently provision kHalf new modules while deprovisioning the pre-provisioned ones.
@@ -823,23 +1928,21 @@ TEST_CASE("hub.concurrent_callbacks")
for (int I = 0; I < kHalf; ++I)
{
- ProvisionFutures[I] = Provisioners.EnqueueTask(std::packaged_task<void()>([&, I] {
- HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool Result =
- HubInstance->Provision(fmt::format("new_{}", I), Info, Reason);
- ProvisionResults[I] = Result ? 1 : 0;
- ProvisionReasons[I] = Reason;
- }),
- WorkerThreadPool::EMode::EnableBacklog);
-
- DeprovisionFutures[I] = Deprovisioneers.EnqueueTask(std::packaged_task<void()>([&, I] {
- std::string Reason;
- const bool Result =
- HubInstance->Deprovision(fmt::format("pre_{}", I), Reason);
- DeprovisionResults[I] = Result ? 1 : 0;
- }),
- WorkerThreadPool::EMode::EnableBacklog);
+ ProvisionFutures[I] =
+ Provisioners.EnqueueTask(std::packaged_task<void()>([&, I] {
+ HubProvisionedInstanceInfo Info;
+ const Hub::Response Result = HubInstance->Provision(fmt::format("new_{}", I), Info);
+ ProvisionResults[I] = (Result.ResponseCode == Hub::EResponseCode::Completed) ? 1 : 0;
+ ProvisionReasons[I] = Result.Message;
+ }),
+ WorkerThreadPool::EMode::EnableBacklog);
+
+ DeprovisionFutures[I] =
+ Deprovisioneers.EnqueueTask(std::packaged_task<void()>([&, I] {
+ const Hub::Response Result = HubInstance->Deprovision(fmt::format("pre_{}", I));
+ DeprovisionResults[I] = (Result.ResponseCode == Hub::EResponseCode::Completed) ? 1 : 0;
+ }),
+ WorkerThreadPool::EMode::EnableBacklog);
}
for (std::future<void>& F : ProvisionFutures)
@@ -863,17 +1966,17 @@ TEST_CASE("hub.concurrent_callbacks")
// Each new_* module must have triggered exactly one provision callback with a non-zero port.
// Each pre_* module must have triggered exactly one deprovision callback with a non-zero port.
{
- RwLock::SharedLockScope _(CallbackMutex);
- REQUIRE_EQ(ProvisionCallbacks.size(), static_cast<size_t>(kHalf));
- REQUIRE_EQ(DeprovisionCallbacks.size(), static_cast<size_t>(kHalf));
+ RwLock::SharedLockScope _(CaptureInstance.CallbackMutex);
+ REQUIRE_EQ(CaptureInstance.ProvisionCallbacks.size(), static_cast<size_t>(kHalf));
+ REQUIRE_EQ(CaptureInstance.DeprovisionCallbacks.size(), static_cast<size_t>(kHalf));
- for (const CallbackRecord& Record : ProvisionCallbacks)
+ for (const hub_testutils::CallbackRecord& Record : CaptureInstance.ProvisionCallbacks)
{
CHECK_NE(Record.Port, 0);
const bool IsNewModule = Record.ModuleId.rfind("new_", 0) == 0;
CHECK_MESSAGE(IsNewModule, Record.ModuleId);
}
- for (const CallbackRecord& Record : DeprovisionCallbacks)
+ for (const hub_testutils::CallbackRecord& Record : CaptureInstance.DeprovisionCallbacks)
{
CHECK_NE(Record.Port, 0);
const bool IsPreModule = Record.ModuleId.rfind("pre_", 0) == 0;
@@ -894,14 +1997,13 @@ TEST_CASE("hub.job_object")
std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool ProvisionResult = HubInstance->Provision("jobobj_a", Info, Reason);
- REQUIRE_MESSAGE(ProvisionResult, Reason);
+ const Hub::Response ProvisionResult = HubInstance->Provision("jobobj_a", Info);
+ REQUIRE_MESSAGE(ProvisionResult.ResponseCode == Hub::EResponseCode::Completed, ProvisionResult.Message);
CHECK_NE(Info.Port, 0);
- const bool DeprovisionResult = HubInstance->Deprovision("jobobj_a", Reason);
- CHECK(DeprovisionResult);
+ const Hub::Response DeprovisionResult = HubInstance->Deprovision("jobobj_a");
+ CHECK(DeprovisionResult.ResponseCode == Hub::EResponseCode::Completed);
CHECK_EQ(HubInstance->GetInstanceCount(), 0);
}
@@ -914,22 +2016,660 @@ TEST_CASE("hub.job_object")
std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
HubProvisionedInstanceInfo Info;
- std::string Reason;
- const bool ProvisionResult = HubInstance->Provision("nojobobj_a", Info, Reason);
- REQUIRE_MESSAGE(ProvisionResult, Reason);
+ const Hub::Response ProvisionResult = HubInstance->Provision("nojobobj_a", Info);
+ REQUIRE_MESSAGE(ProvisionResult.ResponseCode == Hub::EResponseCode::Completed, ProvisionResult.Message);
CHECK_NE(Info.Port, 0);
- const bool DeprovisionResult = HubInstance->Deprovision("nojobobj_a", Reason);
- CHECK(DeprovisionResult);
+ const Hub::Response DeprovisionResult = HubInstance->Deprovision("nojobobj_a");
+ CHECK(DeprovisionResult.ResponseCode == Hub::EResponseCode::Completed);
CHECK_EQ(HubInstance->GetInstanceCount(), 0);
}
}
# endif // ZEN_PLATFORM_WINDOWS
+TEST_CASE("hub.hibernate_wake")
+{
+ ScopedTemporaryDirectory TempDir;
+ Hub::Configuration Config;
+ Config.BasePortNumber = 22600;
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
+
+ HubProvisionedInstanceInfo ProvInfo;
+ Hub::InstanceInfo Info;
+
+ // Provision
+ {
+ const Hub::Response R = HubInstance->Provision("hib_a", ProvInfo);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+ REQUIRE(HubInstance->Find("hib_a", &Info));
+ CHECK_EQ(Info.State, HubInstanceState::Provisioned);
+ const std::chrono::system_clock::time_point ProvisionedTime = Info.StateChangeTime;
+ CHECK_NE(ProvisionedTime, std::chrono::system_clock::time_point::min());
+ CHECK_LE(ProvisionedTime, std::chrono::system_clock::now());
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ProvInfo.Port), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
+
+ // Hibernate
+ const Hub::Response HibernateResult = HubInstance->Hibernate("hib_a");
+ REQUIRE_MESSAGE(HibernateResult.ResponseCode == Hub::EResponseCode::Completed, HibernateResult.Message);
+ REQUIRE(HubInstance->Find("hib_a", &Info));
+ CHECK_EQ(Info.State, HubInstanceState::Hibernated);
+ const std::chrono::system_clock::time_point HibernatedTime = Info.StateChangeTime;
+ CHECK_GE(HibernatedTime, ProvisionedTime);
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ProvInfo.Port), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
+
+ // Wake
+ const Hub::Response WakeResult = HubInstance->Wake("hib_a");
+ REQUIRE_MESSAGE(WakeResult.ResponseCode == Hub::EResponseCode::Completed, WakeResult.Message);
+ REQUIRE(HubInstance->Find("hib_a", &Info));
+ CHECK_EQ(Info.State, HubInstanceState::Provisioned);
+ CHECK_GE(Info.StateChangeTime, HibernatedTime);
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ProvInfo.Port), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
+
+ // Deprovision
+ const Hub::Response DeprovisionResult = HubInstance->Deprovision("hib_a");
+ CHECK(DeprovisionResult.ResponseCode == Hub::EResponseCode::Completed);
+ CHECK_FALSE(HubInstance->Find("hib_a"));
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ProvInfo.Port), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
+}
+
+TEST_CASE("hub.hibernate_wake_errors")
+{
+ ScopedTemporaryDirectory TempDir;
+ Hub::Configuration Config;
+ Config.BasePortNumber = 22700;
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
+
+ HubProvisionedInstanceInfo ProvInfo;
+
+ // Hibernate/wake on a non-existent module - returns NotFound (-> 404)
+ CHECK(HubInstance->Hibernate("never_provisioned").ResponseCode == Hub::EResponseCode::NotFound);
+ CHECK(HubInstance->Wake("never_provisioned").ResponseCode == Hub::EResponseCode::NotFound);
+
+ // Double-hibernate: second hibernate on already-hibernated module returns Completed (idempotent)
+ {
+ const Hub::Response R = HubInstance->Provision("err_b", ProvInfo);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+ {
+ const Hub::Response R = HubInstance->Hibernate("err_b");
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ {
+ const Hub::Response HibResp = HubInstance->Hibernate("err_b");
+ CHECK(HibResp.ResponseCode == Hub::EResponseCode::Completed);
+ }
+
+ // Wake on provisioned: succeeds (-> Provisioned), then wake again returns Completed (idempotent)
+ {
+ const Hub::Response R = HubInstance->Wake("err_b");
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ {
+ const Hub::Response WakeResp = HubInstance->Wake("err_b");
+ CHECK(WakeResp.ResponseCode == Hub::EResponseCode::Completed);
+ }
+
+ // Deprovision not-found - returns NotFound (-> 404)
+ CHECK(HubInstance->Deprovision("never_provisioned").ResponseCode == Hub::EResponseCode::NotFound);
+}
+
+TEST_CASE("hub.async_hibernate_wake")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ Hub::Configuration Config;
+ Config.BasePortNumber = 23000;
+
+ WorkerThreadPool WorkerPool(2, "hub_async_hib_wake");
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, {}, &WorkerPool);
+
+ HubProvisionedInstanceInfo ProvInfo;
+ Hub::InstanceInfo Info;
+
+ constexpr auto kPollInterval = std::chrono::milliseconds(50);
+ constexpr auto kTimeout = std::chrono::seconds(30);
+
+ // Provision and wait until Provisioned
+ {
+ const Hub::Response R = HubInstance->Provision("async_hib_a", ProvInfo);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Accepted, R.Message);
+ }
+ {
+ const auto Deadline = std::chrono::steady_clock::now() + kTimeout;
+ bool Ready = false;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ if (HubInstance->Find("async_hib_a", &Info) && Info.State == HubInstanceState::Provisioned)
+ {
+ Ready = true;
+ break;
+ }
+ std::this_thread::sleep_for(kPollInterval);
+ }
+ REQUIRE_MESSAGE(Ready, "Instance did not reach Provisioned state within timeout");
+ }
+
+ // Hibernate asynchronously and poll until Hibernated
+ {
+ const Hub::Response R = HubInstance->Hibernate("async_hib_a");
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Accepted, R.Message);
+ }
+ {
+ const auto Deadline = std::chrono::steady_clock::now() + kTimeout;
+ bool Hibernated = false;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ if (HubInstance->Find("async_hib_a", &Info) && Info.State == HubInstanceState::Hibernated)
+ {
+ Hibernated = true;
+ break;
+ }
+ std::this_thread::sleep_for(kPollInterval);
+ }
+ REQUIRE_MESSAGE(Hibernated, "Instance did not reach Hibernated state within timeout");
+ }
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ProvInfo.Port), kFastTimeout);
+ CHECK(!ModClient.Get("/health/"));
+ }
+
+ // Wake asynchronously and poll until Provisioned
+ {
+ const Hub::Response R = HubInstance->Wake("async_hib_a");
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Accepted, R.Message);
+ }
+ {
+ const auto Deadline = std::chrono::steady_clock::now() + kTimeout;
+ bool Woken = false;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ if (HubInstance->Find("async_hib_a", &Info) && Info.State == HubInstanceState::Provisioned)
+ {
+ Woken = true;
+ break;
+ }
+ std::this_thread::sleep_for(kPollInterval);
+ }
+ REQUIRE_MESSAGE(Woken, "Instance did not reach Provisioned state after wake within timeout");
+ }
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", ProvInfo.Port), kFastTimeout);
+ CHECK(ModClient.Get("/health/"));
+ }
+
+ // Deprovision asynchronously and poll until the instance is gone
+ {
+ const Hub::Response R = HubInstance->Deprovision("async_hib_a");
+ CHECK_MESSAGE(R.ResponseCode == Hub::EResponseCode::Accepted, R.Message);
+ }
+ REQUIRE_MESSAGE(hub_testutils::WaitForInstanceGone(*HubInstance, "async_hib_a"), "Instance did not deprovision within timeout");
+}
+
+TEST_CASE("hub.recover_process_crash")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ struct TransitionRecord
+ {
+ HubInstanceState OldState;
+ HubInstanceState NewState;
+ };
+ RwLock CaptureMutex;
+ std::vector<TransitionRecord> Transitions;
+ auto CaptureFunc = [&](std::string_view, const HubProvisionedInstanceInfo&, HubInstanceState OldState, HubInstanceState NewState) {
+ CaptureMutex.WithExclusiveLock([&]() { Transitions.push_back({OldState, NewState}); });
+ };
+
+ // Fast watchdog cycle so crash detection is near-instant instead of waiting up to the 3s default.
+ Hub::Configuration Config;
+ Config.WatchDog.CycleInterval = std::chrono::milliseconds(10);
+ Config.WatchDog.InstanceCheckThrottle = std::chrono::milliseconds(1);
+
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, std::move(CaptureFunc));
+
+ HubProvisionedInstanceInfo Info;
+ {
+ const Hub::Response R = HubInstance->Provision("module_a", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ // Kill the child process to simulate a crash, then poll until the watchdog detects it,
+ // recovers the instance, and the new process is serving requests.
+ HubInstance->TerminateModuleForTesting("module_a");
+
+ constexpr auto kPollIntervalMs = std::chrono::milliseconds(50);
+ constexpr auto kTimeoutMs = std::chrono::seconds(15);
+ const auto Deadline = std::chrono::steady_clock::now() + kTimeoutMs;
+
+ // A successful HTTP health check on the same port confirms the new process is up.
+ HttpClient ModClient(fmt::format("http://localhost:{}", Info.Port), kFastTimeout);
+ bool Recovered = false;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ std::this_thread::sleep_for(kPollIntervalMs);
+ Hub::InstanceInfo InstanceInfo;
+ if (HubInstance->Find("module_a", &InstanceInfo) && InstanceInfo.State == HubInstanceState::Provisioned &&
+ ModClient.Get("/health/"))
+ {
+ // Recovery must reuse the same port - the instance was never removed from the hub's
+ // port table during recovery, so AttemptRecoverInstance reuses m_Config.BasePort.
+ CHECK_EQ(InstanceInfo.Port, Info.Port);
+ Recovered = true;
+ break;
+ }
+ }
+ CHECK_MESSAGE(Recovered, "Instance did not recover within timeout");
+
+ // Verify the full crash/recovery callback sequence
+ {
+ RwLock::SharedLockScope _(CaptureMutex);
+ REQUIRE_GE(Transitions.size(), 3u);
+ // Find the Provisioned->Crashed transition
+ const auto CrashedIt = std::find_if(Transitions.begin(), Transitions.end(), [](const TransitionRecord& R) {
+ return R.OldState == HubInstanceState::Provisioned && R.NewState == HubInstanceState::Crashed;
+ });
+ REQUIRE_NE(CrashedIt, Transitions.end());
+ // Recovery sequence follows: Crashed->Recovering, Recovering->Provisioned
+ const auto RecoveringIt = CrashedIt + 1;
+ REQUIRE_NE(RecoveringIt, Transitions.end());
+ CHECK_EQ(RecoveringIt->OldState, HubInstanceState::Crashed);
+ CHECK_EQ(RecoveringIt->NewState, HubInstanceState::Recovering);
+ const auto RecoveredIt = RecoveringIt + 1;
+ REQUIRE_NE(RecoveredIt, Transitions.end());
+ CHECK_EQ(RecoveredIt->OldState, HubInstanceState::Recovering);
+ CHECK_EQ(RecoveredIt->NewState, HubInstanceState::Provisioned);
+ }
+}
+
+TEST_CASE("hub.recover_process_crash_then_deprovision")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ // Fast watchdog cycle so crash detection is near-instant instead of waiting up to the 3s default.
+ Hub::Configuration Config;
+ Config.WatchDog.CycleInterval = std::chrono::milliseconds(10);
+ Config.WatchDog.InstanceCheckThrottle = std::chrono::milliseconds(1);
+
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
+
+ HubProvisionedInstanceInfo Info;
+ {
+ const Hub::Response R = HubInstance->Provision("module_a", Info);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ // Kill the child process, wait for the watchdog to detect and recover the instance.
+ HubInstance->TerminateModuleForTesting("module_a");
+
+ constexpr auto kPollIntervalMs = std::chrono::milliseconds(50);
+ constexpr auto kTimeoutMs = std::chrono::seconds(15);
+ const auto Deadline = std::chrono::steady_clock::now() + kTimeoutMs;
+
+ bool Recovered = false;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ std::this_thread::sleep_for(kPollIntervalMs);
+ Hub::InstanceInfo InstanceInfo;
+ if (HubInstance->Find("module_a", &InstanceInfo) && InstanceInfo.State == HubInstanceState::Provisioned)
+ {
+ Recovered = true;
+ break;
+ }
+ }
+ REQUIRE_MESSAGE(Recovered, "Instance did not recover within timeout");
+
+ // After recovery, deprovision should succeed and a re-provision should work.
+ {
+ const Hub::Response R = HubInstance->Deprovision("module_a");
+ CHECK_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+ CHECK_EQ(HubInstance->GetInstanceCount(), 0);
+
+ HubProvisionedInstanceInfo NewInfo;
+ {
+ const Hub::Response R = HubInstance->Provision("module_a", NewInfo);
+ CHECK_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+ CHECK_NE(NewInfo.Port, 0);
+ HttpClient NewClient(fmt::format("http://localhost:{}", NewInfo.Port), kFastTimeout);
+ CHECK_MESSAGE(NewClient.Get("/health/"), "Re-provisioned instance is not serving requests");
+}
+
+TEST_CASE("hub.async_provision_concurrent")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ constexpr int kModuleCount = 8;
+
+ Hub::Configuration Config;
+ Config.BasePortNumber = 22800;
+ Config.InstanceLimit = kModuleCount;
+
+ WorkerThreadPool WorkerPool(4, "hub_async_concurrent");
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, {}, &WorkerPool);
+
+ std::vector<HubProvisionedInstanceInfo> Infos(kModuleCount);
+ std::vector<std::string> Reasons(kModuleCount);
+ std::vector<int> Results(kModuleCount, 0);
+
+ {
+ WorkerThreadPool Callers(kModuleCount, "hub_async_callers");
+ std::vector<std::future<void>> Futures(kModuleCount);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ Futures[I] = Callers.EnqueueTask(std::packaged_task<void()>([&, I] {
+ const Hub::Response Resp = HubInstance->Provision(fmt::format("async_c{}", I), Infos[I]);
+ Results[I] = (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? 1 : 0;
+ Reasons[I] = Resp.Message;
+ }),
+ WorkerThreadPool::EMode::EnableBacklog);
+ }
+ for (std::future<void>& F : Futures)
+ {
+ F.get();
+ }
+ }
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ REQUIRE_MESSAGE(Results[I] != 0, Reasons[I]);
+ CHECK_NE(Infos[I].Port, 0);
+ }
+
+ // Poll until all instances reach Provisioned state
+ constexpr auto kPollInterval = std::chrono::milliseconds(50);
+ constexpr auto kTimeout = std::chrono::seconds(30);
+ const auto Deadline = std::chrono::steady_clock::now() + kTimeout;
+
+ bool AllProvisioned = false;
+ while (std::chrono::steady_clock::now() < Deadline)
+ {
+ int ProvisionedCount = 0;
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ Hub::InstanceInfo InstanceInfo;
+ if (HubInstance->Find(fmt::format("async_c{}", I), &InstanceInfo) && InstanceInfo.State == HubInstanceState::Provisioned)
+ {
+ ++ProvisionedCount;
+ }
+ }
+ if (ProvisionedCount == kModuleCount)
+ {
+ AllProvisioned = true;
+ break;
+ }
+ std::this_thread::sleep_for(kPollInterval);
+ }
+ CHECK_MESSAGE(AllProvisioned, "Not all instances reached Provisioned state within timeout");
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Infos[I].Port), kFastTimeout);
+ CHECK_MESSAGE(ModClient.Get("/health/"), fmt::format("async_c{} not serving requests", I));
+ }
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ const Hub::Response DepResp = HubInstance->Deprovision(fmt::format("async_c{}", I));
+ CHECK_MESSAGE(DepResp.ResponseCode == Hub::EResponseCode::Accepted, DepResp.Message);
+ }
+ REQUIRE_MESSAGE(hub_testutils::WaitForInstanceCount(*HubInstance, 0), "Not all instances deprovisioned within timeout");
+}
+
+TEST_CASE("hub.async_provision_shutdown_waits")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ constexpr int kModuleCount = 8;
+
+ Hub::Configuration Config;
+ Config.InstanceLimit = kModuleCount;
+ Config.BasePortNumber = 22900;
+
+ WorkerThreadPool WorkerPool(2, "hub_async_shutdown");
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, {}, &WorkerPool);
+
+ std::vector<HubProvisionedInstanceInfo> Infos(kModuleCount);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ const Hub::Response ProvResult = HubInstance->Provision(fmt::format("async_c{}", I), Infos[I]);
+ REQUIRE_MESSAGE(ProvResult.ResponseCode == Hub::EResponseCode::Accepted, ProvResult.Message);
+ REQUIRE_NE(Infos[I].Port, 0);
+ }
+
+ // Shut down without polling for Provisioned; Shutdown() must drain the latch and clean up.
+ HubInstance->Shutdown();
+
+ CHECK_EQ(HubInstance->GetInstanceCount(), 0);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ HttpClient ModClient(fmt::format("http://localhost:{}", Infos[I].Port), kFastTimeout);
+ CHECK_FALSE(ModClient.Get("/health/"));
+ }
+}
+
+TEST_CASE("hub.async_provision_rejected")
+{
+ // Rejection from CanProvisionInstanceLocked fires synchronously even when a WorkerPool is present.
+ ScopedTemporaryDirectory TempDir;
+
+ Hub::Configuration Config;
+ Config.InstanceLimit = 1;
+ Config.BasePortNumber = 23100;
+
+ WorkerThreadPool WorkerPool(2, "hub_async_rejected");
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config, {}, &WorkerPool);
+
+ HubProvisionedInstanceInfo Info;
+
+ // First provision: dispatched to WorkerPool, returns Accepted
+ const Hub::Response FirstResult = HubInstance->Provision("async_r1", Info);
+ REQUIRE_MESSAGE(FirstResult.ResponseCode == Hub::EResponseCode::Accepted, FirstResult.Message);
+ REQUIRE_NE(Info.Port, 0);
+
+ // Second provision: CanProvisionInstanceLocked rejects synchronously (limit reached), returns Rejected
+ HubProvisionedInstanceInfo Info2;
+ const Hub::Response SecondResult = HubInstance->Provision("async_r2", Info2);
+ CHECK(SecondResult.ResponseCode == Hub::EResponseCode::Rejected);
+ CHECK_FALSE(SecondResult.Message.empty());
+ CHECK_NE(SecondResult.Message.find("instance limit"), std::string::npos);
+ CHECK_EQ(HubInstance->GetInstanceCount(), 1);
+}
+
+TEST_CASE("hub.instance.inactivity.deprovision")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ // Aggressive watchdog settings to keep test duration short.
+ // Provisioned timeout (2s) > Hibernated timeout (1s) - this is the key invariant under test.
+ // Margin (1s) means the HTTP activity check fires at LastActivityTime+1s for Provisioned instances.
+ // The Hibernated branch ignores the margin and uses a direct time-based check.
+ Hub::Configuration Config;
+ Config.BasePortNumber = 23200;
+ Config.InstanceLimit = 3;
+ Config.WatchDog.CycleInterval = std::chrono::milliseconds(10);
+ Config.WatchDog.InstanceCheckThrottle = std::chrono::milliseconds(1);
+ Config.WatchDog.ProvisionedInactivityTimeout = std::chrono::seconds(2);
+ Config.WatchDog.HibernatedInactivityTimeout = std::chrono::seconds(1);
+ Config.WatchDog.InactivityCheckMargin = std::chrono::seconds(1);
+ Config.WatchDog.ActivityCheckConnectTimeout = std::chrono::milliseconds(200);
+ Config.WatchDog.ActivityCheckRequestTimeout = std::chrono::milliseconds(500);
+
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
+
+ // Provision in order: idle first, idle_hib second (then hibernate), persistent last.
+ // idle_hib uses the shorter Hibernated timeout (1s) and expires before idle (2s provisioned).
+ // persistent gets real HTTP PUTs so its activity timer is reset; it must still be alive
+ // after both idle instances are gone.
+
+ HubProvisionedInstanceInfo IdleInfo;
+ {
+ const Hub::Response R = HubInstance->Provision("idle", IdleInfo);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ HubProvisionedInstanceInfo IdleHibInfo;
+ {
+ const Hub::Response R = HubInstance->Provision("idle_hib", IdleHibInfo);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ const Hub::Response H = HubInstance->Hibernate("idle_hib");
+ REQUIRE_MESSAGE(H.ResponseCode == Hub::EResponseCode::Completed, H.Message);
+ }
+
+ HubProvisionedInstanceInfo PersistentInfo;
+ {
+ const Hub::Response R = HubInstance->Provision("persistent", PersistentInfo);
+ REQUIRE_MESSAGE(R.ResponseCode == Hub::EResponseCode::Completed, R.Message);
+ }
+
+ auto PokeInstance = [&](uint16_t Port) {
+ // Make a real storage request to increment the instance's activity sum.
+ // The watchdog detects the changed sum on the next cycle and resets LastActivityTime.
+ {
+ HttpClient PersistentClient(fmt::format("http://localhost:{}", Port),
+ HttpClientSettings{.ConnectTimeout = std::chrono::milliseconds(200)});
+ uint64_t Tick = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() -
+ std::chrono::steady_clock::time_point::min())
+ .count();
+ IoHash Key = IoHash::HashBuffer(&Tick, sizeof(Tick));
+ const HttpClient::Response PutResult =
+ PersistentClient.Put(fmt::format("/z$/ns1/b/{}", Key),
+ IoBufferBuilder::MakeFromMemory(MakeMemoryView(std::string_view("keepalive"))));
+ CHECK(PutResult);
+ }
+ };
+
+ PokeInstance(IdleInfo.Port);
+ PokeInstance(PersistentInfo.Port);
+
+ Sleep(100);
+
+ // Phase 1: immediately after setup all three instances must still be alive.
+ // No timeout has elapsed yet (only 100ms have passed).
+ CHECK_MESSAGE(HubInstance->Find("idle"), "idle was deprovisioned within 100ms - its 2s provisioned timeout has not elapsed");
+
+ CHECK_MESSAGE(HubInstance->Find("idle_hib"), "idle_hib was deprovisioned within 100ms - its 1s hibernated timeout has not elapsed");
+
+ CHECK_MESSAGE(HubInstance->Find("persistent"),
+ "persistent was deprovisioned within 100ms - its 2s provisioned timeout has not elapsed");
+
+ // Phase 2: idle_hib must be deprovisioned by the watchdog within its 1s hibernated timeout.
+ // idle must remain alive - its 2s provisioned timeout has not elapsed yet.
+ CHECK_MESSAGE(hub_testutils::WaitForInstanceGone(*HubInstance, "idle_hib", std::chrono::milliseconds(100), std::chrono::seconds(3)),
+ "idle_hib was not deprovisioned within its 1s hibernated timeout");
+
+ CHECK_MESSAGE(!HubInstance->Find("idle_hib"), "idle_hib should be gone after its 1s hibernated timeout elapsed");
+
+ CHECK_MESSAGE(HubInstance->Find("idle"),
+ "idle was deprovisioned before its 2s provisioned timeout - only idle_hib's 1s hibernated timeout has elapsed");
+
+ CHECK_MESSAGE(HubInstance->Find("persistent"),
+ "persistent was incorrectly deprovisioned - its activity timer was reset by PokeInstance");
+
+ PokeInstance(PersistentInfo.Port);
+
+ // Phase 3: idle must be deprovisioned by the watchdog within its 2s provisioned timeout.
+ // persistent must remain alive - its activity timer was reset by PokeInstance.
+ CHECK_MESSAGE(hub_testutils::WaitForInstanceGone(*HubInstance, "idle", std::chrono::milliseconds(100), std::chrono::seconds(4)),
+ "idle was not deprovisioned within its 2s provisioned timeout");
+
+ CHECK_MESSAGE(!HubInstance->Find("idle_hib"), "idle_hib should still be gone - it was deprovisioned in phase 2");
+
+ CHECK_MESSAGE(!HubInstance->Find("idle"), "idle should be gone after its 3s provisioned timeout elapsed");
+
+ CHECK_MESSAGE(HubInstance->Find("persistent"),
+ "persistent was incorrectly deprovisioned - its activity timer was reset by PokeInstance");
+
+ HubInstance->Shutdown();
+}
+
+TEST_CASE("hub.machine_metrics")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), {});
+
+ // UpdateMachineMetrics() is called synchronously in the Hub constructor, so metrics
+ // are available immediately without waiting for a watchdog cycle.
+ SystemMetrics SysMetrics;
+ DiskSpace Disk;
+ HubInstance->GetMachineMetrics(SysMetrics, Disk);
+
+ CHECK_GT(Disk.Total, 0u);
+ CHECK_LE(Disk.Free, Disk.Total);
+
+ CHECK_GT(SysMetrics.SystemMemoryMiB, 0u);
+ CHECK_LE(SysMetrics.AvailSystemMemoryMiB, SysMetrics.SystemMemoryMiB);
+
+ CHECK_GT(SysMetrics.VirtualMemoryMiB, 0u);
+ CHECK_LE(SysMetrics.AvailVirtualMemoryMiB, SysMetrics.VirtualMemoryMiB);
+}
+
+TEST_CASE("hub.provision_rejected_resource_limits")
+{
+ // The Hub constructor calls UpdateMachineMetrics() synchronously, so CanProvisionInstanceLocked
+ // can enforce limits immediately without waiting for a watchdog cycle.
+ ScopedTemporaryDirectory TempDir;
+
+ {
+ Hub::Configuration Config;
+ Config.ResourceLimits.DiskUsageBytes = 1;
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
+ HubProvisionedInstanceInfo Info;
+ const Hub::Response Result = HubInstance->Provision("disk_limit", Info);
+ CHECK(Result.ResponseCode == Hub::EResponseCode::Rejected);
+ CHECK_NE(Result.Message.find("disk usage"), std::string::npos);
+ }
+
+ {
+ Hub::Configuration Config;
+ Config.ResourceLimits.MemoryUsageBytes = 1;
+ std::unique_ptr<Hub> HubInstance = hub_testutils::MakeHub(TempDir.Path(), Config);
+ HubProvisionedInstanceInfo Info;
+ const Hub::Response Result = HubInstance->Provision("mem_limit", Info);
+ CHECK(Result.ResponseCode == Hub::EResponseCode::Rejected);
+ CHECK_NE(Result.Message.find("ram usage"), std::string::npos);
+ }
+}
+
TEST_SUITE_END();
void
+Hub::TerminateModuleForTesting(const std::string& ModuleId)
+{
+ RwLock::SharedLockScope _(m_Lock);
+ auto It = m_InstanceLookup.find(ModuleId);
+ if (It == m_InstanceLookup.end())
+ {
+ return;
+ }
+ StorageServerInstance::SharedLockedPtr Locked = m_ActiveInstances[It->second].Instance->LockShared(/*Wait*/ true);
+ if (Locked)
+ {
+ Locked.TerminateForTesting();
+ }
+}
+
+void
hub_forcelink()
{
}
diff --git a/src/zenserver/hub/hub.h b/src/zenserver/hub/hub.h
index 78be3eda1..8ee9130f6 100644
--- a/src/zenserver/hub/hub.h
+++ b/src/zenserver/hub/hub.h
@@ -2,21 +2,27 @@
#pragma once
+#include "hubinstancestate.h"
#include "resourcemetrics.h"
+#include "storageserverinstance.h"
+#include <zencore/compactbinary.h>
+#include <zencore/filesystem.h>
#include <zencore/system.h>
#include <zenutil/zenserverprocess.h>
+#include <chrono>
#include <deque>
#include <filesystem>
#include <functional>
#include <memory>
+#include <thread>
#include <unordered_map>
-#include <unordered_set>
namespace zen {
-class StorageServerInstance;
+class HttpClient;
+class WorkerThreadPool;
/**
* Hub
@@ -33,104 +39,258 @@ struct HubProvisionedInstanceInfo
class Hub
{
public:
+ struct WatchDogConfiguration
+ {
+ std::chrono::milliseconds CycleInterval = std::chrono::seconds(3);
+ std::chrono::milliseconds CycleProcessingBudget = std::chrono::milliseconds(500);
+ std::chrono::milliseconds InstanceCheckThrottle = std::chrono::milliseconds(5);
+ std::chrono::seconds ProvisionedInactivityTimeout = std::chrono::minutes(10);
+ std::chrono::seconds HibernatedInactivityTimeout = std::chrono::minutes(30);
+ std::chrono::seconds InactivityCheckMargin = std::chrono::minutes(1);
+
+ std::chrono::milliseconds ActivityCheckConnectTimeout = std::chrono::milliseconds(100);
+ std::chrono::milliseconds ActivityCheckRequestTimeout = std::chrono::milliseconds(200);
+ };
+
struct Configuration
{
/** Enable or disable the use of a Windows Job Object for child process management.
* When enabled, all spawned child processes are assigned to a job object with
* JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, ensuring children are terminated if the hub
- * crashes or is force-killed. Must be called before Initialize(). No-op on non-Windows.
+ * crashes or is force-killed.
*/
bool UseJobObject = true;
uint16_t BasePortNumber = 21000;
int InstanceLimit = 1000;
- uint32_t InstanceHttpThreadCount = 0; // Deduce from core count
- int InstanceCoreLimit = 0; // Use hardware core count
+ uint32_t InstanceHttpThreadCount = 0; // Automatic
+ int InstanceCoreLimit = 0; // Automatic
std::filesystem::path InstanceConfigPath;
+ std::string HydrationTargetSpecification;
+ CbObject HydrationOptions;
+
+ WatchDogConfiguration WatchDog;
+
+ ResourceMetrics ResourceLimits;
};
- typedef std::function<void(std::string_view ModuleId, const HubProvisionedInstanceInfo& Info)> ProvisionModuleCallbackFunc;
+ typedef std::function<
+ void(std::string_view ModuleId, const HubProvisionedInstanceInfo& Info, HubInstanceState OldState, HubInstanceState NewState)>
+ AsyncModuleStateChangeCallbackFunc;
- Hub(const Configuration& Config,
- ZenServerEnvironment&& RunEnvironment,
- ProvisionModuleCallbackFunc&& ProvisionedModuleCallback = {},
- ProvisionModuleCallbackFunc&& DeprovisionedModuleCallback = {});
+ Hub(const Configuration& Config,
+ ZenServerEnvironment&& RunEnvironment,
+ WorkerThreadPool* OptionalWorkerPool = nullptr,
+ AsyncModuleStateChangeCallbackFunc&& ModuleStateChangeCallback = {});
~Hub();
Hub(const Hub&) = delete;
Hub& operator=(const Hub&) = delete;
+ struct InstanceInfo
+ {
+ HubInstanceState State = HubInstanceState::Unprovisioned;
+ std::chrono::system_clock::time_point StateChangeTime;
+ ProcessMetrics Metrics;
+ uint16_t Port = 0;
+ };
+
+ /**
+ * Deprovision all running instances
+ */
+ void Shutdown();
+
+ enum class EResponseCode
+ {
+ NotFound,
+ Rejected,
+ Accepted,
+ Completed
+ };
+
+ struct Response
+ {
+ EResponseCode ResponseCode = EResponseCode::Rejected;
+ std::string Message;
+ };
+
/**
* Provision a storage server instance for the given module ID.
*
* @param ModuleId The ID of the module to provision.
- * @param OutInfo If successful, information about the provisioned instance will be returned here.
- * @param OutReason If unsuccessful, the reason will be returned here.
+ * @param OutInfo On success, information about the provisioned instance is returned here.
*/
- bool Provision(std::string_view ModuleId, HubProvisionedInstanceInfo& OutInfo, std::string& OutReason);
+ Response Provision(std::string_view ModuleId, HubProvisionedInstanceInfo& OutInfo);
/**
* Deprovision a storage server instance for the given module ID.
*
* @param ModuleId The ID of the module to deprovision.
- * @param OutReason If unsuccessful, the reason will be returned here.
- * @return true if the instance was found and deprovisioned, false otherwise.
*/
- bool Deprovision(const std::string& ModuleId, std::string& OutReason);
+ Response Deprovision(const std::string& ModuleId);
+
+ /**
+ * Hibernate a storage server instance for the given module ID.
+ * The instance is shut down but its data is preserved; it can be woken later.
+ *
+ * @param ModuleId The ID of the module to hibernate.
+ */
+ Response Hibernate(const std::string& ModuleId);
/**
- * Find a storage server instance for the given module ID.
+ * Wake a hibernated storage server instance for the given module ID.
*
- * Beware that as this returns a raw pointer to the instance, the caller must ensure
- * that the instance is not deprovisioned while in use.
+ * @param ModuleId The ID of the module to wake.
+ */
+ Response Wake(const std::string& ModuleId);
+
+ /**
+ * Find info about storage server instance for the given module ID.
*
* @param ModuleId The ID of the module to find.
- * @param OutInstance If found, the instance will be returned here.
+ * @param OutInstanceInfo If found, the instance info will be returned here.
* @return true if the instance was found, false otherwise.
*/
- bool Find(std::string_view ModuleId, StorageServerInstance** OutInstance = nullptr);
+ bool Find(std::string_view ModuleId, InstanceInfo* OutInstanceInfo = nullptr);
/**
- * Enumerate all storage server instances.
+ * Enumerate a snapshot of all storage server instances.
*
- * @param Callback The callback to invoke for each instance. Note that you should
- * not do anything heavyweight in the callback as it is invoked while holding
- * a shared lock.
+ * @param Callback The callback to invoke for each instance.
*/
- void EnumerateModules(std::function<void(StorageServerInstance&)> Callback);
+ void EnumerateModules(std::function<void(std::string_view ModuleId, const InstanceInfo&)> Callback);
int GetInstanceCount();
- int GetMaxInstanceCount() const { return m_MaxInstanceCount; }
+ int GetMaxInstanceCount() const { return m_MaxInstanceCount.load(); }
+
+ void GetMachineMetrics(SystemMetrics& OutSystemMetrict, DiskSpace& OutDiskSpace) const;
+
+ bool IsInstancePort(uint16_t Port) const;
const Configuration& GetConfig() const { return m_Config; }
+#if ZEN_WITH_TESTS
+ void TerminateModuleForTesting(const std::string& ModuleId);
+#endif
+
private:
const Configuration m_Config;
ZenServerEnvironment m_RunEnvironment;
+ WorkerThreadPool* m_WorkerPool = nullptr;
+ Latch m_BackgroundWorkLatch;
+ std::atomic<bool> m_ShutdownFlag = false;
- ProvisionModuleCallbackFunc m_ProvisionedModuleCallback;
- ProvisionModuleCallbackFunc m_DeprovisionedModuleCallback;
+ AsyncModuleStateChangeCallbackFunc m_ModuleStateChangeCallback;
- std::filesystem::path m_FileHydrationPath;
+ std::string m_HydrationTargetSpecification;
+ CbObject m_HydrationOptions;
std::filesystem::path m_HydrationTempPath;
#if ZEN_PLATFORM_WINDOWS
JobObject m_JobObject;
#endif
- RwLock m_Lock;
- std::unordered_map<std::string, std::unique_ptr<StorageServerInstance>> m_Instances;
- std::unordered_set<std::string> m_DeprovisioningModules;
- std::unordered_set<std::string> m_ProvisioningModules;
- ResourceMetrics m_ResourceLimits;
- SystemMetrics m_HostMetrics;
- int m_MaxInstanceCount = 0;
- std::deque<uint16_t> m_FreePorts;
-
- void UpdateStats();
- void UpdateCapacityMetrics();
- bool CanProvisionInstance(std::string_view ModuleId, std::string& OutReason);
+ mutable RwLock m_Lock;
+ std::unordered_map<std::string, size_t> m_InstanceLookup;
+
+ // Mirrors ProcessMetrics with atomic fields, enabling lock-free reads alongside watchdog writes.
+ struct AtomicProcessMetrics
+ {
+ std::atomic<uint64_t> MemoryBytes = 0;
+ std::atomic<uint64_t> KernelTimeMs = 0;
+ std::atomic<uint64_t> UserTimeMs = 0;
+ std::atomic<uint64_t> WorkingSetSize = 0;
+ std::atomic<uint64_t> PeakWorkingSetSize = 0;
+ std::atomic<uint64_t> PagefileUsage = 0;
+ std::atomic<uint64_t> PeakPagefileUsage = 0;
+
+ ProcessMetrics Load() const;
+ void Store(const ProcessMetrics& Metrics);
+ void Reset();
+ };
+
+ struct ActiveInstance
+ {
+ // Invariant: Instance == nullptr if and only if State == Unprovisioned.
+ // Both fields are only created/destroyed under the hub's exclusive lock.
+ // State is an atomic because the watchdog reads it under a shared instance lock
+ // without holding the hub lock.
+ std::unique_ptr<StorageServerInstance> Instance;
+ std::atomic<HubInstanceState> State = HubInstanceState::Unprovisioned;
+
+ // Process metrics - written by WatchDog (inside instance shared lock), read lock-free.
+ AtomicProcessMetrics ProcessMetrics;
+
+ // Activity tracking - written by WatchDog, reset on every state transition.
+ std::atomic<uint64_t> LastKnownActivitySum = 0;
+ std::atomic<std::chrono::system_clock::time_point> LastActivityTime = std::chrono::system_clock::time_point::min();
+
+ // Set in UpdateInstanceStateLocked on every state transition; read lock-free by Find/EnumerateModules.
+ std::atomic<std::chrono::system_clock::time_point> StateChangeTime = std::chrono::system_clock::time_point::min();
+ };
+
+ // UpdateInstanceState is overloaded to accept a locked instance pointer (exclusive or shared) or the hub exclusive
+ // lock scope as a proof token that the caller holds an appropriate lock before mutating ActiveInstance::State.
+ // State mutation and notification (NotifyStateUpdate) are intentionally decoupled - see NotifyStateUpdate below.
+
+ HubInstanceState UpdateInstanceState(const StorageServerInstance::ExclusiveLockedPtr& Instance,
+ size_t ActiveInstanceIndex,
+ HubInstanceState NewState)
+ {
+ ZEN_ASSERT(Instance);
+ return UpdateInstanceStateLocked(ActiveInstanceIndex, NewState);
+ }
+ HubInstanceState UpdateInstanceState(const StorageServerInstance::SharedLockedPtr& Instance,
+ size_t ActiveInstanceIndex,
+ HubInstanceState NewState)
+ {
+ ZEN_ASSERT(Instance);
+ return UpdateInstanceStateLocked(ActiveInstanceIndex, NewState);
+ }
+ HubInstanceState UpdateInstanceState(const RwLock::ExclusiveLockScope& HubLock, size_t ActiveInstanceIndex, HubInstanceState NewState)
+ {
+ ZEN_UNUSED(HubLock);
+ return UpdateInstanceStateLocked(ActiveInstanceIndex, NewState);
+ }
+ HubInstanceState UpdateInstanceStateLocked(size_t ActiveInstanceIndex, HubInstanceState NewState);
+
+ std::vector<ActiveInstance> m_ActiveInstances;
+ std::deque<size_t> m_FreeActiveInstanceIndexes;
+ SystemMetrics m_SystemMetrics;
+ DiskSpace m_DiskSpace;
+ std::atomic<int> m_MaxInstanceCount = 0;
+ std::thread m_WatchDog;
+
+ Event m_WatchDogEvent;
+ void WatchDog();
+ void UpdateMachineMetrics();
+ bool CheckInstanceStatus(HttpClient& ActivityHttpClient,
+ StorageServerInstance::SharedLockedPtr&& LockedInstance,
+ size_t ActiveInstanceIndex);
+ void AttemptRecoverInstance(std::string_view ModuleId);
+
+ bool CanProvisionInstanceLocked(std::string_view ModuleId, std::string& OutReason);
+ uint16_t GetInstanceIndexAssignedPort(size_t ActiveInstanceIndex) const;
+
+ Response InternalDeprovision(const std::string& ModuleId, std::function<bool(ActiveInstance& Instance)>&& DeprovisionGate);
+ void CompleteProvision(StorageServerInstance::ExclusiveLockedPtr& Instance,
+ size_t ActiveInstanceIndex,
+ HubInstanceState OldState,
+ bool IsNewInstance);
+ void CompleteDeprovision(StorageServerInstance::ExclusiveLockedPtr& Instance, size_t ActiveInstanceIndex);
+ void CompleteHibernate(StorageServerInstance::ExclusiveLockedPtr& Instance, size_t ActiveInstanceIndex, HubInstanceState OldState);
+ void CompleteWake(StorageServerInstance::ExclusiveLockedPtr& Instance, size_t ActiveInstanceIndex, HubInstanceState OldState);
+
+ // Notifications may fire slightly out of sync with the Hub's internal State flag.
+ // The guarantee is that notifications are sent in the correct order, but the State
+ // flag may be updated either before or after the notification fires depending on the
+ // code path. Callers must not assume a specific ordering between the two.
+ void NotifyStateUpdate(std::string_view ModuleId,
+ HubInstanceState OldState,
+ HubInstanceState NewState,
+ uint16_t BasePort,
+ std::string_view BaseUri);
};
#if ZEN_WITH_TESTS
diff --git a/src/zenserver/hub/hubinstancestate.cpp b/src/zenserver/hub/hubinstancestate.cpp
new file mode 100644
index 000000000..c47fdd294
--- /dev/null
+++ b/src/zenserver/hub/hubinstancestate.cpp
@@ -0,0 +1,37 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "hubinstancestate.h"
+
+#include <zencore/assertfmt.h>
+
+namespace zen {
+
+std::string_view
+ToString(HubInstanceState State)
+{
+ switch (State)
+ {
+ case HubInstanceState::Unprovisioned:
+ return "unprovisioned";
+ case HubInstanceState::Provisioning:
+ return "provisioning";
+ case HubInstanceState::Provisioned:
+ return "provisioned";
+ case HubInstanceState::Hibernating:
+ return "hibernating";
+ case HubInstanceState::Hibernated:
+ return "hibernated";
+ case HubInstanceState::Waking:
+ return "waking";
+ case HubInstanceState::Deprovisioning:
+ return "deprovisioning";
+ case HubInstanceState::Crashed:
+ return "crashed";
+ case HubInstanceState::Recovering:
+ return "recovering";
+ }
+ ZEN_ASSERT(false);
+ return "unknown";
+}
+
+} // namespace zen
diff --git a/src/zenserver/hub/hubinstancestate.h b/src/zenserver/hub/hubinstancestate.h
new file mode 100644
index 000000000..c895f75d1
--- /dev/null
+++ b/src/zenserver/hub/hubinstancestate.h
@@ -0,0 +1,28 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <cstdint>
+#include <string_view>
+
+namespace zen {
+
+enum class HubInstanceState : uint32_t
+{
+ // Stable states - possible to initiate state change to a different stable state via the transitioning states
+ Unprovisioned, // Initial state; process not running
+ Provisioned, // Process running and serving requests
+ Hibernated, // Process stopped, data preserved; can be woken
+ Crashed, // Process died unexpectedly while Provisioned; recovery pending
+
+ // Transitioning states - there is explicit ownership during this state and it may not be stolen
+ Provisioning, // Unprovisioned -> Provisioned (Hydrating and spawning process)
+ Hibernating, // Provisioned -> Hibernated (Shutting down process, preserving data on disk)
+ Waking, // Hibernated -> Provisioned (Starting process from preserved data)
+ Deprovisioning, // Provisioned/Hibernated/Crashed -> Unprovisioned (Shutting down process and cleaning up data)
+ Recovering, // Crashed -> Provisioned/Deprovisioned (Attempting in-place restart after a crash)
+};
+
+std::string_view ToString(HubInstanceState State);
+
+} // namespace zen
diff --git a/src/zenserver/hub/hydration.cpp b/src/zenserver/hub/hydration.cpp
index 0e78f8545..ed16bfe56 100644
--- a/src/zenserver/hub/hydration.cpp
+++ b/src/zenserver/hub/hydration.cpp
@@ -2,14 +2,67 @@
#include "hydration.h"
+#include <zencore/basicfile.h>
+#include <zencore/compactbinary.h>
+#include <zencore/compactbinarybuilder.h>
+#include <zencore/except_fmt.h>
#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
+#include <zencore/system.h>
+#include <zencore/timer.h>
+#include <zenutil/cloud/imdscredentials.h>
+#include <zenutil/cloud/s3client.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <json11.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+#if ZEN_WITH_TESTS
+# include <zencore/parallelwork.h>
+# include <zencore/testing.h>
+# include <zencore/testutils.h>
+# include <zencore/thread.h>
+# include <zencore/workthreadpool.h>
+# include <zenutil/cloud/minioprocess.h>
+# include <cstring>
+#endif // ZEN_WITH_TESTS
namespace zen {
+namespace {
+
+ /// UTC time decomposed to calendar fields with sub-second milliseconds.
+ struct UtcTime
+ {
+ std::tm Tm{};
+ int Ms = 0; // sub-second milliseconds [0, 999]
+
+ static UtcTime Now()
+ {
+ std::chrono::system_clock::time_point TimePoint = std::chrono::system_clock::now();
+ std::time_t TimeT = std::chrono::system_clock::to_time_t(TimePoint);
+ int SubSecMs =
+ static_cast<int>((std::chrono::duration_cast<std::chrono::milliseconds>(TimePoint.time_since_epoch()) % 1000).count());
+
+ UtcTime Result;
+ Result.Ms = SubSecMs;
+#if ZEN_PLATFORM_WINDOWS
+ gmtime_s(&Result.Tm, &TimeT);
+#else
+ gmtime_r(&TimeT, &Result.Tm);
+#endif
+ return Result;
+ }
+ };
+
+} // namespace
+
///////////////////////////////////////////////////////////////////////////
+constexpr std::string_view FileHydratorPrefix = "file://";
+constexpr std::string_view FileHydratorType = "file";
+
struct FileHydrator : public HydrationStrategyBase
{
virtual void Configure(const HydrationConfig& Config) override;
@@ -26,7 +79,22 @@ FileHydrator::Configure(const HydrationConfig& Config)
{
m_Config = Config;
- std::filesystem::path ConfigPath(Utf8ToWide(m_Config.TargetSpecification));
+ std::filesystem::path ConfigPath;
+ if (!m_Config.TargetSpecification.empty())
+ {
+ ConfigPath = Utf8ToWide(m_Config.TargetSpecification.substr(FileHydratorPrefix.length()));
+ }
+ else
+ {
+ CbObjectView Settings = m_Config.Options["settings"].AsObjectView();
+ std::string_view Path = Settings["path"].AsString();
+ if (Path.empty())
+ {
+ throw zen::runtime_error("Hydration config 'file' type requires 'settings.path'");
+ }
+ ConfigPath = Utf8ToWide(std::string(Path));
+ }
+ MakeSafeAbsolutePathInPlace(ConfigPath);
if (!std::filesystem::exists(ConfigPath))
{
@@ -43,6 +111,8 @@ FileHydrator::Hydrate()
{
ZEN_INFO("Hydrating state from '{}' to '{}'", m_StorageModuleRootDir, m_Config.ServerStateDir);
+ Stopwatch Timer;
+
// Ensure target is clean
ZEN_DEBUG("Wiping server state at '{}'", m_Config.ServerStateDir);
const bool ForceRemoveReadOnlyFiles = true;
@@ -68,8 +138,10 @@ FileHydrator::Hydrate()
ZEN_DEBUG("Cleaning server state '{}'", m_Config.ServerStateDir);
CleanDirectory(m_Config.ServerStateDir, ForceRemoveReadOnlyFiles);
}
-
- // Note that we leave the storage state intact until next dehydration replaces the content
+ else
+ {
+ ZEN_INFO("Hydration complete in {}", NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
+ }
}
void
@@ -77,6 +149,8 @@ FileHydrator::Dehydrate()
{
ZEN_INFO("Dehydrating state from '{}' to '{}'", m_Config.ServerStateDir, m_StorageModuleRootDir);
+ Stopwatch Timer;
+
const std::filesystem::path TargetDir = m_StorageModuleRootDir;
// Ensure target is clean. This could be replaced with an atomic copy at a later date
@@ -91,7 +165,23 @@ FileHydrator::Dehydrate()
try
{
ZEN_DEBUG("Copying '{}' to '{}'", m_Config.ServerStateDir, TargetDir);
- CopyTree(m_Config.ServerStateDir, TargetDir, {.EnableClone = true});
+ for (const std::filesystem::directory_entry& Entry : std::filesystem::directory_iterator(m_Config.ServerStateDir))
+ {
+ if (Entry.path().filename() == ".sentry-native")
+ {
+ continue;
+ }
+ std::filesystem::path Dest = TargetDir / Entry.path().filename();
+ if (Entry.is_directory())
+ {
+ CreateDirectories(Dest);
+ CopyTree(Entry.path(), Dest, {.EnableClone = true});
+ }
+ else
+ {
+ CopyFile(Entry.path(), Dest, {.EnableClone = true});
+ }
+ }
}
catch (std::exception& Ex)
{
@@ -109,12 +199,1216 @@ FileHydrator::Dehydrate()
ZEN_DEBUG("Wiping server state '{}'", m_Config.ServerStateDir);
CleanDirectory(m_Config.ServerStateDir, ForceRemoveReadOnlyFiles);
+
+ if (CopySuccess)
+ {
+ ZEN_INFO("Dehydration complete in {}", NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+constexpr std::string_view S3HydratorPrefix = "s3://";
+constexpr std::string_view S3HydratorType = "s3";
+
+struct S3Hydrator : public HydrationStrategyBase
+{
+ void Configure(const HydrationConfig& Config) override;
+ void Dehydrate() override;
+ void Hydrate() override;
+
+private:
+ S3Client CreateS3Client() const;
+ std::string BuildTimestampFolderName() const;
+ std::string MakeObjectKey(std::string_view FolderName, const std::filesystem::path& RelPath) const;
+
+ HydrationConfig m_Config;
+ std::string m_Bucket;
+ std::string m_KeyPrefix; // "<user-prefix>/<ModuleId>" or just "<ModuleId>" - no trailing slash
+ std::string m_Region;
+ SigV4Credentials m_Credentials;
+ Ref<ImdsCredentialProvider> m_CredentialProvider;
+
+ static constexpr uint64_t MultipartChunkSize = 8 * 1024 * 1024;
+};
+
+void
+S3Hydrator::Configure(const HydrationConfig& Config)
+{
+ m_Config = Config;
+
+ CbObjectView Settings = m_Config.Options["settings"].AsObjectView();
+ std::string_view Spec;
+ if (!m_Config.TargetSpecification.empty())
+ {
+ Spec = m_Config.TargetSpecification;
+ Spec.remove_prefix(S3HydratorPrefix.size());
+ }
+ else
+ {
+ std::string_view Uri = Settings["uri"].AsString();
+ if (Uri.empty())
+ {
+ throw zen::runtime_error("Hydration config 's3' type requires 'settings.uri'");
+ }
+ Spec = Uri;
+ Spec.remove_prefix(S3HydratorPrefix.size());
+ }
+
+ size_t SlashPos = Spec.find('/');
+ std::string UserPrefix = SlashPos != std::string_view::npos ? std::string(Spec.substr(SlashPos + 1)) : std::string{};
+ m_Bucket = std::string(SlashPos != std::string_view::npos ? Spec.substr(0, SlashPos) : Spec);
+ m_KeyPrefix = UserPrefix.empty() ? m_Config.ModuleId : UserPrefix + "/" + m_Config.ModuleId;
+
+ ZEN_ASSERT(!m_Bucket.empty());
+
+ std::string Region = std::string(Settings["region"].AsString());
+ if (Region.empty())
+ {
+ Region = GetEnvVariable("AWS_DEFAULT_REGION");
+ }
+ if (Region.empty())
+ {
+ Region = GetEnvVariable("AWS_REGION");
+ }
+ if (Region.empty())
+ {
+ Region = "us-east-1";
+ }
+ m_Region = std::move(Region);
+
+ std::string AccessKeyId = GetEnvVariable("AWS_ACCESS_KEY_ID");
+ if (AccessKeyId.empty())
+ {
+ m_CredentialProvider = Ref<ImdsCredentialProvider>(new ImdsCredentialProvider({}));
+ }
+ else
+ {
+ m_Credentials.AccessKeyId = std::move(AccessKeyId);
+ m_Credentials.SecretAccessKey = GetEnvVariable("AWS_SECRET_ACCESS_KEY");
+ m_Credentials.SessionToken = GetEnvVariable("AWS_SESSION_TOKEN");
+ }
+}
+
+S3Client
+S3Hydrator::CreateS3Client() const
+{
+ S3ClientOptions Options;
+ Options.BucketName = m_Bucket;
+ Options.Region = m_Region;
+
+ CbObjectView Settings = m_Config.Options["settings"].AsObjectView();
+ std::string_view Endpoint = Settings["endpoint"].AsString();
+ if (!Endpoint.empty())
+ {
+ Options.Endpoint = std::string(Endpoint);
+ Options.PathStyle = Settings["path-style"].AsBool();
+ }
+
+ if (m_CredentialProvider)
+ {
+ Options.CredentialProvider = m_CredentialProvider;
+ }
+ else
+ {
+ Options.Credentials = m_Credentials;
+ }
+
+ Options.HttpSettings.MaximumInMemoryDownloadSize = 16u * 1024u;
+
+ return S3Client(Options);
+}
+
+std::string
+S3Hydrator::BuildTimestampFolderName() const
+{
+ UtcTime Now = UtcTime::Now();
+ return fmt::format("{:04d}{:02d}{:02d}-{:02d}{:02d}{:02d}-{:03d}",
+ Now.Tm.tm_year + 1900,
+ Now.Tm.tm_mon + 1,
+ Now.Tm.tm_mday,
+ Now.Tm.tm_hour,
+ Now.Tm.tm_min,
+ Now.Tm.tm_sec,
+ Now.Ms);
+}
+
+std::string
+S3Hydrator::MakeObjectKey(std::string_view FolderName, const std::filesystem::path& RelPath) const
+{
+ return m_KeyPrefix + "/" + std::string(FolderName) + "/" + RelPath.generic_string();
+}
+
+void
+S3Hydrator::Dehydrate()
+{
+ ZEN_INFO("Dehydrating state from '{}' to s3://{}/{}", m_Config.ServerStateDir, m_Bucket, m_KeyPrefix);
+
+ try
+ {
+ S3Client Client = CreateS3Client();
+ std::string FolderName = BuildTimestampFolderName();
+ uint64_t TotalBytes = 0;
+ uint32_t FileCount = 0;
+ Stopwatch Timer;
+
+ DirectoryContent DirContent;
+ GetDirectoryContent(m_Config.ServerStateDir, DirectoryContentFlags::IncludeFiles | DirectoryContentFlags::Recursive, DirContent);
+
+ for (const std::filesystem::path& AbsPath : DirContent.Files)
+ {
+ std::filesystem::path RelPath = AbsPath.lexically_relative(m_Config.ServerStateDir);
+ if (RelPath.empty() || *RelPath.begin() == "..")
+ {
+ throw zen::runtime_error(
+ "lexically_relative produced a '..'-escape path for '{}' relative to '{}' - "
+ "path form mismatch (e.g. \\\\?\\ prefix on one but not the other)",
+ AbsPath.string(),
+ m_Config.ServerStateDir.string());
+ }
+ if (*RelPath.begin() == ".sentry-native")
+ {
+ continue;
+ }
+ std::string Key = MakeObjectKey(FolderName, RelPath);
+
+ BasicFile File(AbsPath, BasicFile::Mode::kRead);
+ uint64_t FileSize = File.FileSize();
+
+ S3Result UploadResult = Client.PutObjectMultipart(
+ Key,
+ FileSize,
+ [&File](uint64_t Offset, uint64_t Size) { return File.ReadRange(Offset, Size); },
+ MultipartChunkSize);
+ if (!UploadResult.IsSuccess())
+ {
+ throw zen::runtime_error("Failed to upload '{}' to S3: {}", Key, UploadResult.Error);
+ }
+
+ TotalBytes += FileSize;
+ ++FileCount;
+ }
+
+ // Write current-state.json
+ uint64_t UploadDurationMs = Timer.GetElapsedTimeMs();
+
+ UtcTime Now = UtcTime::Now();
+ std::string UploadTimeUtc = fmt::format("{:04d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}.{:03d}Z",
+ Now.Tm.tm_year + 1900,
+ Now.Tm.tm_mon + 1,
+ Now.Tm.tm_mday,
+ Now.Tm.tm_hour,
+ Now.Tm.tm_min,
+ Now.Tm.tm_sec,
+ Now.Ms);
+
+ CbObjectWriter Meta;
+ Meta << "FolderName" << FolderName;
+ Meta << "ModuleId" << m_Config.ModuleId;
+ Meta << "HostName" << GetMachineName();
+ Meta << "UploadTimeUtc" << UploadTimeUtc;
+ Meta << "UploadDurationMs" << UploadDurationMs;
+ Meta << "TotalSizeBytes" << TotalBytes;
+ Meta << "FileCount" << FileCount;
+
+ ExtendableStringBuilder<1024> JsonBuilder;
+ Meta.Save().ToJson(JsonBuilder);
+
+ std::string MetaKey = m_KeyPrefix + "/current-state.json";
+ std::string_view JsonText = JsonBuilder.ToView();
+ IoBuffer MetaBuf(IoBuffer::Clone, JsonText.data(), JsonText.size());
+ S3Result MetaUploadResult = Client.PutObject(MetaKey, std::move(MetaBuf));
+ if (!MetaUploadResult.IsSuccess())
+ {
+ throw zen::runtime_error("Failed to write current-state.json to '{}': {}", MetaKey, MetaUploadResult.Error);
+ }
+
+ ZEN_INFO("Dehydration complete: {} files, {}, {}", FileCount, NiceBytes(TotalBytes), NiceTimeSpanMs(UploadDurationMs));
+ }
+ catch (std::exception& Ex)
+ {
+ // Any in-progress multipart upload has already been aborted by PutObjectMultipart.
+ // current-state.json is only written on success, so the previous S3 state remains valid.
+ ZEN_WARN("S3 dehydration failed: {}. S3 state not updated.", Ex.what());
+ }
+}
+
+void
+S3Hydrator::Hydrate()
+{
+ ZEN_INFO("Hydrating state from s3://{}/{} to '{}'", m_Bucket, m_KeyPrefix, m_Config.ServerStateDir);
+
+ Stopwatch Timer;
+ const bool ForceRemoveReadOnlyFiles = true;
+
+ // Clean temp dir before starting in case of leftover state from a previous failed hydration
+ ZEN_DEBUG("Cleaning temp dir '{}'", m_Config.TempDir);
+ CleanDirectory(m_Config.TempDir, ForceRemoveReadOnlyFiles);
+
+ bool WipeServerState = false;
+
+ try
+ {
+ S3Client Client = CreateS3Client();
+ std::string MetaKey = m_KeyPrefix + "/current-state.json";
+
+ S3GetObjectResult MetaResult = Client.GetObject(MetaKey);
+ if (!MetaResult.IsSuccess())
+ {
+ if (MetaResult.Error == S3GetObjectResult::NotFoundErrorText)
+ {
+ ZEN_INFO("No state found in S3 at {}", MetaKey);
+
+ ZEN_DEBUG("Wiping server state '{}'", m_Config.ServerStateDir);
+ CleanDirectory(m_Config.ServerStateDir, ForceRemoveReadOnlyFiles);
+ return;
+ }
+ throw zen::runtime_error("Failed to read current-state.json from '{}': {}", MetaKey, MetaResult.Error);
+ }
+
+ std::string ParseError;
+ json11::Json MetaJson = json11::Json::parse(std::string(MetaResult.AsText()), ParseError);
+ if (!ParseError.empty())
+ {
+ throw zen::runtime_error("Failed to parse current-state.json from '{}': {}", MetaKey, ParseError);
+ }
+
+ std::string FolderName = MetaJson["FolderName"].string_value();
+ if (FolderName.empty())
+ {
+ throw zen::runtime_error("current-state.json from '{}' has missing or empty FolderName", MetaKey);
+ }
+
+ std::string FolderPrefix = m_KeyPrefix + "/" + FolderName + "/";
+ S3ListObjectsResult ListResult = Client.ListObjects(FolderPrefix);
+ if (!ListResult.IsSuccess())
+ {
+ throw zen::runtime_error("Failed to list S3 objects under '{}': {}", FolderPrefix, ListResult.Error);
+ }
+
+ for (const S3ObjectInfo& Obj : ListResult.Objects)
+ {
+ if (!Obj.Key.starts_with(FolderPrefix))
+ {
+ ZEN_WARN("Skipping unexpected S3 key '{}' (expected prefix '{}')", Obj.Key, FolderPrefix);
+ continue;
+ }
+
+ std::string RelKey = Obj.Key.substr(FolderPrefix.size());
+ if (RelKey.empty())
+ {
+ continue;
+ }
+ std::filesystem::path DestPath = MakeSafeAbsolutePath(m_Config.TempDir / std::filesystem::path(RelKey));
+ CreateDirectories(DestPath.parent_path());
+
+ if (Obj.Size > MultipartChunkSize)
+ {
+ BasicFile DestFile(DestPath, BasicFile::Mode::kTruncate);
+ DestFile.SetFileSize(Obj.Size);
+
+ BasicFileWriter Writer(DestFile, 64 * 1024);
+
+ uint64_t Offset = 0;
+ while (Offset < Obj.Size)
+ {
+ uint64_t ChunkSize = std::min<uint64_t>(MultipartChunkSize, Obj.Size - Offset);
+ S3GetObjectResult Chunk = Client.GetObjectRange(Obj.Key, Offset, ChunkSize);
+ if (!Chunk.IsSuccess())
+ {
+ throw zen::runtime_error("Failed to download '{}' bytes [{}-{}] from S3: {}",
+ Obj.Key,
+ Offset,
+ Offset + ChunkSize - 1,
+ Chunk.Error);
+ }
+
+ Writer.Write(Chunk.Content.GetData(), Chunk.Content.GetSize(), Offset);
+ Offset += ChunkSize;
+ }
+
+ Writer.Flush();
+ }
+ else
+ {
+ S3GetObjectResult Chunk = Client.GetObject(Obj.Key, m_Config.TempDir);
+ if (!Chunk.IsSuccess())
+ {
+ throw zen::runtime_error("Failed to download '{}' from S3: {}", Obj.Key, Chunk.Error);
+ }
+
+ if (IoBufferFileReference FileRef; Chunk.Content.GetFileReference(FileRef))
+ {
+ std::error_code Ec;
+ std::filesystem::path ChunkPath = PathFromHandle(FileRef.FileHandle, Ec);
+ if (Ec)
+ {
+ WriteFile(DestPath, Chunk.Content);
+ }
+ else
+ {
+ Chunk.Content.SetDeleteOnClose(false);
+ Chunk.Content = {};
+ RenameFile(ChunkPath, DestPath, Ec);
+ }
+ }
+ else
+ {
+ WriteFile(DestPath, Chunk.Content);
+ }
+ }
+ }
+
+ // Downloaded successfully - swap into ServerStateDir
+ ZEN_DEBUG("Wiping server state '{}'", m_Config.ServerStateDir);
+ CleanDirectory(m_Config.ServerStateDir, ForceRemoveReadOnlyFiles);
+
+ // If the two paths share at least one common component they are on the same drive/volume
+ // and atomic renames will succeed. Otherwise fall back to a full copy.
+ auto [ItTmp, ItState] =
+ std::mismatch(m_Config.TempDir.begin(), m_Config.TempDir.end(), m_Config.ServerStateDir.begin(), m_Config.ServerStateDir.end());
+ if (ItTmp != m_Config.TempDir.begin())
+ {
+ DirectoryContent DirContent;
+ GetDirectoryContent(m_Config.TempDir, DirectoryContentFlags::IncludeFiles | DirectoryContentFlags::IncludeDirs, DirContent);
+
+ for (const std::filesystem::path& AbsPath : DirContent.Directories)
+ {
+ std::filesystem::path Dest = MakeSafeAbsolutePath(m_Config.ServerStateDir / AbsPath.filename());
+ RenameDirectory(AbsPath, Dest);
+ }
+ for (const std::filesystem::path& AbsPath : DirContent.Files)
+ {
+ std::filesystem::path Dest = MakeSafeAbsolutePath(m_Config.ServerStateDir / AbsPath.filename());
+ RenameFile(AbsPath, Dest);
+ }
+
+ ZEN_DEBUG("Cleaning temp dir '{}'", m_Config.TempDir);
+ CleanDirectory(m_Config.TempDir, ForceRemoveReadOnlyFiles);
+ }
+ else
+ {
+ // Slow path: TempDir and ServerStateDir are on different filesystems, so rename
+ // would fail. Copy the tree instead and clean up the temp files afterwards.
+ ZEN_DEBUG("TempDir and ServerStateDir are on different filesystems - using CopyTree");
+ CopyTree(m_Config.TempDir, m_Config.ServerStateDir, {.EnableClone = true});
+ ZEN_DEBUG("Cleaning temp dir '{}'", m_Config.TempDir);
+ CleanDirectory(m_Config.TempDir, ForceRemoveReadOnlyFiles);
+ }
+
+ ZEN_INFO("Hydration complete from folder '{}' in {}", FolderName, NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
+ }
+ catch (std::exception& Ex)
+ {
+ ZEN_WARN("S3 hydration failed: {}. Will wipe any partially installed state.", Ex.what());
+
+ // We don't do the clean right here to avoid potentially running into double-throws
+ WipeServerState = true;
+ }
+
+ if (WipeServerState)
+ {
+ ZEN_DEBUG("Cleaning server state '{}'", m_Config.ServerStateDir);
+ CleanDirectory(m_Config.ServerStateDir, ForceRemoveReadOnlyFiles);
+ ZEN_DEBUG("Cleaning temp dir '{}'", m_Config.TempDir);
+ CleanDirectory(m_Config.TempDir, ForceRemoveReadOnlyFiles);
+ }
}
std::unique_ptr<HydrationStrategyBase>
-CreateFileHydrator()
+CreateHydrator(const HydrationConfig& Config)
{
- return std::make_unique<FileHydrator>();
+ if (!Config.TargetSpecification.empty())
+ {
+ if (StrCaseCompare(Config.TargetSpecification.substr(0, FileHydratorPrefix.length()), FileHydratorPrefix) == 0)
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = std::make_unique<FileHydrator>();
+ Hydrator->Configure(Config);
+ return Hydrator;
+ }
+ if (StrCaseCompare(Config.TargetSpecification.substr(0, S3HydratorPrefix.length()), S3HydratorPrefix) == 0)
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = std::make_unique<S3Hydrator>();
+ Hydrator->Configure(Config);
+ return Hydrator;
+ }
+ throw std::runtime_error(fmt::format("Unknown hydration strategy: {}", Config.TargetSpecification));
+ }
+
+ std::string_view Type = Config.Options["type"].AsString();
+ if (Type == FileHydratorType)
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = std::make_unique<FileHydrator>();
+ Hydrator->Configure(Config);
+ return Hydrator;
+ }
+ if (Type == S3HydratorType)
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = std::make_unique<S3Hydrator>();
+ Hydrator->Configure(Config);
+ return Hydrator;
+ }
+ if (!Type.empty())
+ {
+ throw zen::runtime_error("Unknown hydration target type '{}'", Type);
+ }
+ throw zen::runtime_error("No hydration target configured");
}
+#if ZEN_WITH_TESTS
+
+namespace {
+
+ /// Scoped RAII helper to set/restore a single environment variable within a test.
+ /// Used to configure AWS credentials for each S3 test's MinIO instance
+ /// without polluting the global environment.
+ struct ScopedEnvVar
+ {
+ std::string m_Name;
+ std::optional<std::string> m_OldValue; // nullopt = was not set; "" = was set to empty string
+
+ ScopedEnvVar(std::string_view Name, std::string_view Value) : m_Name(Name)
+ {
+# if ZEN_PLATFORM_WINDOWS
+ // Use the raw API so we can distinguish "not set" (ERROR_ENVVAR_NOT_FOUND)
+ // from "set to empty string" (returns 0 with no error).
+ char Buf[1];
+ DWORD Len = GetEnvironmentVariableA(m_Name.c_str(), Buf, sizeof(Buf));
+ if (Len == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+ {
+ m_OldValue = std::nullopt;
+ }
+ else
+ {
+ // Len == 0 with no error: variable exists but is empty.
+ // Len > sizeof(Buf): value is non-empty; Len is the required buffer size
+ // (including null terminator) - allocate and re-read.
+ std::string Old(Len == 0 ? 0 : Len - 1, '\0');
+ if (Len > sizeof(Buf))
+ {
+ GetEnvironmentVariableA(m_Name.c_str(), Old.data(), Len);
+ }
+ m_OldValue = std::move(Old);
+ }
+ SetEnvironmentVariableA(m_Name.c_str(), std::string(Value).c_str());
+# else
+ // getenv returns nullptr when not set, "" when set to empty string.
+ const char* Existing = getenv(m_Name.c_str());
+ m_OldValue = Existing ? std::optional<std::string>(Existing) : std::nullopt;
+ setenv(m_Name.c_str(), std::string(Value).c_str(), 1);
+# endif
+ }
+ ~ScopedEnvVar()
+ {
+# if ZEN_PLATFORM_WINDOWS
+ SetEnvironmentVariableA(m_Name.c_str(), m_OldValue.has_value() ? m_OldValue->c_str() : nullptr);
+# else
+ if (m_OldValue.has_value())
+ {
+ setenv(m_Name.c_str(), m_OldValue->c_str(), 1);
+ }
+ else
+ {
+ unsetenv(m_Name.c_str());
+ }
+# endif
+ }
+ };
+
+ /// Create a small file hierarchy under BaseDir:
+ /// file_a.bin
+ /// subdir/file_b.bin
+ /// subdir/nested/file_c.bin
+ /// Returns a vector of (relative path, content) pairs for later verification.
+ std::vector<std::pair<std::filesystem::path, IoBuffer>> CreateTestTree(const std::filesystem::path& BaseDir)
+ {
+ std::vector<std::pair<std::filesystem::path, IoBuffer>> Files;
+
+ auto AddFile = [&](std::filesystem::path RelPath, IoBuffer Content) {
+ std::filesystem::path FullPath = BaseDir / RelPath;
+ CreateDirectories(FullPath.parent_path());
+ WriteFile(FullPath, Content);
+ Files.emplace_back(std::move(RelPath), std::move(Content));
+ };
+
+ AddFile("file_a.bin", CreateSemiRandomBlob(1024));
+ AddFile("subdir/file_b.bin", CreateSemiRandomBlob(2048));
+ AddFile("subdir/nested/file_c.bin", CreateSemiRandomBlob(512));
+ AddFile("subdir/nested/file_d.bin", CreateSemiRandomBlob(512));
+ AddFile("subdir/nested/file_e.bin", CreateSemiRandomBlob(512));
+ AddFile("subdir/nested/file_f.bin", CreateSemiRandomBlob(512));
+ AddFile("subdir/nested/medium.bulk", CreateSemiRandomBlob(256u * 1024u));
+ AddFile("subdir/nested/big.bulk", CreateSemiRandomBlob(512u * 1024u));
+ AddFile("subdir/nested/huge.bulk", CreateSemiRandomBlob(9u * 1024u * 1024u));
+
+ return Files;
+ }
+
+ void VerifyTree(const std::filesystem::path& Dir, const std::vector<std::pair<std::filesystem::path, IoBuffer>>& Expected)
+ {
+ for (const auto& [RelPath, Content] : Expected)
+ {
+ std::filesystem::path FullPath = Dir / RelPath;
+ REQUIRE_MESSAGE(std::filesystem::exists(FullPath), FullPath.string());
+ BasicFile ReadBack(FullPath, BasicFile::Mode::kRead);
+ IoBuffer ReadContent = ReadBack.ReadRange(0, ReadBack.FileSize());
+ REQUIRE_EQ(ReadContent.GetSize(), Content.GetSize());
+ CHECK(std::memcmp(ReadContent.GetData(), Content.GetData(), Content.GetSize()) == 0);
+ }
+ }
+
+} // namespace
+
+TEST_SUITE_BEGIN("server.hydration");
+
+// ---------------------------------------------------------------------------
+// FileHydrator tests
+// ---------------------------------------------------------------------------
+
+TEST_CASE("hydration.file.dehydrate_hydrate")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationStore = TempDir.Path() / "hydration_store";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationStore);
+ CreateDirectories(HydrationTemp);
+
+ const std::string ModuleId = "testmodule";
+ auto TestFiles = CreateTestTree(ServerStateDir);
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = ModuleId;
+ Config.TargetSpecification = "file://" + HydrationStore.string();
+
+ // Dehydrate: copy server state to file store
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ // Verify the module folder exists in the store and ServerStateDir was wiped
+ CHECK(std::filesystem::exists(HydrationStore / ModuleId));
+ CHECK(std::filesystem::is_empty(ServerStateDir));
+
+ // Hydrate: restore server state from file store
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ }
+
+ // Verify restored contents match the original
+ VerifyTree(ServerStateDir, TestFiles);
+}
+
+TEST_CASE("hydration.file.dehydrate_cleans_server_state")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationStore = TempDir.Path() / "hydration_store";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationStore);
+ CreateDirectories(HydrationTemp);
+
+ CreateTestTree(ServerStateDir);
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = "testmodule";
+ Config.TargetSpecification = "file://" + HydrationStore.string();
+
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+
+ // FileHydrator::Dehydrate() must wipe ServerStateDir when done
+ CHECK(std::filesystem::is_empty(ServerStateDir));
+}
+
+TEST_CASE("hydration.file.hydrate_overwrites_existing_state")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationStore = TempDir.Path() / "hydration_store";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationStore);
+ CreateDirectories(HydrationTemp);
+
+ auto TestFiles = CreateTestTree(ServerStateDir);
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = "testmodule";
+ Config.TargetSpecification = "file://" + HydrationStore.string();
+
+ // Dehydrate the original state
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ // Put a stale file in ServerStateDir to simulate leftover state
+ WriteFile(ServerStateDir / "stale.bin", CreateSemiRandomBlob(256));
+
+ // Hydrate - must wipe stale file and restore original
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ }
+
+ CHECK_FALSE(std::filesystem::exists(ServerStateDir / "stale.bin"));
+ VerifyTree(ServerStateDir, TestFiles);
+}
+
+// ---------------------------------------------------------------------------
+// FileHydrator concurrent test
+// ---------------------------------------------------------------------------
+
+TEST_CASE("hydration.file.concurrent")
+{
+ // N modules dehydrate and hydrate concurrently via ParallelWork.
+ // Each module operates in its own directory - tests for global/static state races.
+ constexpr int kModuleCount = 4;
+
+ ScopedTemporaryDirectory TempDir;
+ std::filesystem::path HydrationStore = TempDir.Path() / "hydration_store";
+ CreateDirectories(HydrationStore);
+
+ struct ModuleData
+ {
+ HydrationConfig Config;
+ std::vector<std::pair<std::filesystem::path, IoBuffer>> Files;
+ };
+ std::vector<ModuleData> Modules(kModuleCount);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ std::string ModuleId = fmt::format("file_concurrent_{}", I);
+ std::filesystem::path StateDir = TempDir.Path() / ModuleId / "state";
+ std::filesystem::path TempPath = TempDir.Path() / ModuleId / "temp";
+ CreateDirectories(StateDir);
+ CreateDirectories(TempPath);
+
+ Modules[I].Config.ServerStateDir = StateDir;
+ Modules[I].Config.TempDir = TempPath;
+ Modules[I].Config.ModuleId = ModuleId;
+ Modules[I].Config.TargetSpecification = "file://" + HydrationStore.string();
+ Modules[I].Files = CreateTestTree(StateDir);
+ }
+
+ // Concurrent dehydrate
+ {
+ WorkerThreadPool Pool(kModuleCount, "hydration_file_dehy");
+ std::atomic<bool> AbortFlag{false};
+ std::atomic<bool> PauseFlag{false};
+ ParallelWork Work(AbortFlag, PauseFlag, WorkerThreadPool::EMode::EnableBacklog);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ Work.ScheduleWork(Pool, [&Config = Modules[I].Config](std::atomic<bool>&) {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ });
+ }
+ Work.Wait();
+ CHECK_FALSE(Work.IsAborted());
+ }
+
+ // Concurrent hydrate
+ {
+ WorkerThreadPool Pool(kModuleCount, "hydration_file_hy");
+ std::atomic<bool> AbortFlag{false};
+ std::atomic<bool> PauseFlag{false};
+ ParallelWork Work(AbortFlag, PauseFlag, WorkerThreadPool::EMode::EnableBacklog);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ Work.ScheduleWork(Pool, [&Config = Modules[I].Config](std::atomic<bool>&) {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ });
+ }
+ Work.Wait();
+ CHECK_FALSE(Work.IsAborted());
+ }
+
+ // Verify all modules restored correctly
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ VerifyTree(Modules[I].Config.ServerStateDir, Modules[I].Files);
+ }
+}
+
+// ---------------------------------------------------------------------------
+// S3Hydrator tests
+//
+// Each test case spawns its own local MinIO instance (self-contained, no external setup needed).
+// The MinIO binary must be present in the same directory as the test executable (copied by xmake).
+// ---------------------------------------------------------------------------
+
+TEST_CASE("hydration.s3.dehydrate_hydrate")
+{
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19010;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationTemp);
+
+ const std::string ModuleId = "s3test_roundtrip";
+ auto TestFiles = CreateTestTree(ServerStateDir);
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = ModuleId;
+ std::string ConfigJson =
+ fmt::format(R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test","endpoint":"{}","path-style":true}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Config.Options = std::move(Root).AsObject();
+
+ // Dehydrate: upload server state to MinIO
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ // Wipe server state
+ CleanDirectory(ServerStateDir, true);
+ CHECK(std::filesystem::is_empty(ServerStateDir));
+
+ // Hydrate: download from MinIO back to server state
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ }
+
+ // Verify restored contents match the original
+ VerifyTree(ServerStateDir, TestFiles);
+}
+
+TEST_CASE("hydration.s3.current_state_json_selects_latest_folder")
+{
+ // Each Dehydrate() uploads files to a new timestamp-named folder and then overwrites
+ // current-state.json to point at that folder. Old folders are NOT deleted.
+ // Hydrate() must read current-state.json to determine which folder to restore from.
+ //
+ // This test verifies that:
+ // 1. After two dehydrations, Hydrate() restores from the second snapshot, not the first,
+ // confirming that current-state.json was updated between dehydrations.
+ // 2. current-state.json is updated to point at the second (latest) folder.
+ // 3. Hydrate() restores the v2 snapshot (identified by v2marker.bin), NOT the v1 snapshot.
+
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19011;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationTemp);
+
+ const std::string ModuleId = "s3test_folder_select";
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = ModuleId;
+ {
+ std::string ConfigJson =
+ fmt::format(R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test","endpoint":"{}","path-style":true}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Config.Options = std::move(Root).AsObject();
+ }
+
+ // v1: dehydrate without a marker file
+ CreateTestTree(ServerStateDir);
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ // ServerStateDir is now empty. Wait so the v2 timestamp folder name is strictly later
+ // (timestamp resolution is 1 ms, but macOS scheduler granularity requires a larger margin).
+ Sleep(100);
+
+ // v2: dehydrate WITH a marker file that only v2 has
+ CreateTestTree(ServerStateDir);
+ WriteFile(ServerStateDir / "v2marker.bin", CreateSemiRandomBlob(64));
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ // Hydrate must restore v2 (current-state.json points to the v2 folder)
+ CleanDirectory(ServerStateDir, true);
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ }
+
+ // v2 marker must be present - confirms current-state.json pointed to the v2 folder
+ CHECK(std::filesystem::exists(ServerStateDir / "v2marker.bin"));
+ // Subdirectory hierarchy must also be intact
+ CHECK(std::filesystem::exists(ServerStateDir / "subdir" / "file_b.bin"));
+ CHECK(std::filesystem::exists(ServerStateDir / "subdir" / "nested" / "file_c.bin"));
+}
+
+TEST_CASE("hydration.s3.module_isolation")
+{
+ // Two independent modules dehydrate/hydrate without interfering with each other.
+ // Uses VerifyTree with per-module byte content to detect cross-module data mixing.
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19012;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+
+ ScopedTemporaryDirectory TempDir;
+
+ struct ModuleData
+ {
+ HydrationConfig Config;
+ std::vector<std::pair<std::filesystem::path, IoBuffer>> Files;
+ };
+
+ std::vector<ModuleData> Modules;
+ for (const char* ModuleId : {"s3test_iso_a", "s3test_iso_b"})
+ {
+ std::filesystem::path StateDir = TempDir.Path() / ModuleId / "state";
+ std::filesystem::path TempPath = TempDir.Path() / ModuleId / "temp";
+ CreateDirectories(StateDir);
+ CreateDirectories(TempPath);
+
+ ModuleData Data;
+ Data.Config.ServerStateDir = StateDir;
+ Data.Config.TempDir = TempPath;
+ Data.Config.ModuleId = ModuleId;
+ {
+ std::string ConfigJson =
+ fmt::format(R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test","endpoint":"{}","path-style":true}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Data.Config.Options = std::move(Root).AsObject();
+ }
+ Data.Files = CreateTestTree(StateDir);
+
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Data.Config);
+ Hydrator->Dehydrate();
+
+ Modules.push_back(std::move(Data));
+ }
+
+ for (ModuleData& Module : Modules)
+ {
+ CleanDirectory(Module.Config.ServerStateDir, true);
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Module.Config);
+ Hydrator->Hydrate();
+
+ // Each module's files must be independently restorable with correct byte content.
+ // If S3 key prefixes were mixed up, CreateSemiRandomBlob content would differ.
+ VerifyTree(Module.Config.ServerStateDir, Module.Files);
+ }
+}
+
+// ---------------------------------------------------------------------------
+// S3Hydrator concurrent test
+// ---------------------------------------------------------------------------
+
+TEST_CASE("hydration.s3.concurrent")
+{
+ // N modules dehydrate and hydrate concurrently against MinIO.
+ // Each module has a distinct ModuleId, so S3 key prefixes don't overlap.
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19013;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+
+ constexpr int kModuleCount = 16;
+ constexpr int kThreadCount = 4;
+
+ ScopedTemporaryDirectory TempDir;
+
+ struct ModuleData
+ {
+ HydrationConfig Config;
+ std::vector<std::pair<std::filesystem::path, IoBuffer>> Files;
+ };
+ std::vector<ModuleData> Modules(kModuleCount);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ std::string ModuleId = fmt::format("s3_concurrent_{}", I);
+ std::filesystem::path StateDir = TempDir.Path() / ModuleId / "state";
+ std::filesystem::path TempPath = TempDir.Path() / ModuleId / "temp";
+ CreateDirectories(StateDir);
+ CreateDirectories(TempPath);
+
+ Modules[I].Config.ServerStateDir = StateDir;
+ Modules[I].Config.TempDir = TempPath;
+ Modules[I].Config.ModuleId = ModuleId;
+ {
+ std::string ConfigJson =
+ fmt::format(R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test","endpoint":"{}","path-style":true}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Modules[I].Config.Options = std::move(Root).AsObject();
+ }
+ Modules[I].Files = CreateTestTree(StateDir);
+ }
+
+ // Concurrent dehydrate
+ {
+ WorkerThreadPool Pool(kThreadCount, "hydration_s3_dehy");
+ std::atomic<bool> AbortFlag{false};
+ std::atomic<bool> PauseFlag{false};
+ ParallelWork Work(AbortFlag, PauseFlag, WorkerThreadPool::EMode::EnableBacklog);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ Work.ScheduleWork(Pool, [&Config = Modules[I].Config](std::atomic<bool>&) {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ });
+ }
+ Work.Wait();
+ CHECK_FALSE(Work.IsAborted());
+ }
+
+ // Concurrent hydrate
+ {
+ WorkerThreadPool Pool(kThreadCount, "hydration_s3_hy");
+ std::atomic<bool> AbortFlag{false};
+ std::atomic<bool> PauseFlag{false};
+ ParallelWork Work(AbortFlag, PauseFlag, WorkerThreadPool::EMode::EnableBacklog);
+
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ Work.ScheduleWork(Pool, [&Config = Modules[I].Config](std::atomic<bool>&) {
+ CleanDirectory(Config.ServerStateDir, true);
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ });
+ }
+ Work.Wait();
+ CHECK_FALSE(Work.IsAborted());
+ }
+
+ // Verify all modules restored correctly
+ for (int I = 0; I < kModuleCount; ++I)
+ {
+ VerifyTree(Modules[I].Config.ServerStateDir, Modules[I].Files);
+ }
+}
+
+// ---------------------------------------------------------------------------
+// S3Hydrator: no prior state (first-boot path)
+// ---------------------------------------------------------------------------
+
+TEST_CASE("hydration.s3.no_prior_state")
+{
+ // Hydrate() against an empty bucket (first-boot scenario) must leave ServerStateDir empty.
+ // The "No state found in S3" path goes through the error-cleanup branch, which wipes
+ // ServerStateDir to ensure no partial or stale content is left for the server to start on.
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19014;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationTemp);
+
+ // Pre-populate ServerStateDir to confirm the wipe actually runs.
+ WriteFile(ServerStateDir / "stale.bin", CreateSemiRandomBlob(256));
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = "s3test_no_prior";
+ {
+ std::string ConfigJson =
+ fmt::format(R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test","endpoint":"{}","path-style":true}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Config.Options = std::move(Root).AsObject();
+ }
+
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+
+ // ServerStateDir must be empty: the error path wipes it to prevent a server start
+ // against stale or partially-installed content.
+ CHECK(std::filesystem::is_empty(ServerStateDir));
+}
+
+// ---------------------------------------------------------------------------
+// S3Hydrator: bucket path prefix in TargetSpecification
+// ---------------------------------------------------------------------------
+
+TEST_CASE("hydration.s3.path_prefix")
+{
+ // TargetSpecification of the form "s3://bucket/some/prefix" stores objects under
+ // "some/prefix/<ModuleId>/..." rather than directly under "<ModuleId>/...".
+ // Tests the second branch of the m_KeyPrefix calculation in S3Hydrator::Configure().
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19015;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationTemp);
+
+ std::vector<std::pair<std::filesystem::path, IoBuffer>> TestFiles = CreateTestTree(ServerStateDir);
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = "s3test_prefix";
+ {
+ std::string ConfigJson =
+ fmt::format(R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test/team/project","endpoint":"{}","path-style":true}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Config.Options = std::move(Root).AsObject();
+ }
+
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ CleanDirectory(ServerStateDir, true);
+
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ }
+
+ VerifyTree(ServerStateDir, TestFiles);
+}
+
+TEST_CASE("hydration.s3.options_region_override")
+{
+ // Verify that 'region' in Options["settings"] takes precedence over AWS_DEFAULT_REGION env var.
+ // AWS_DEFAULT_REGION is set to a bogus value; hydration must succeed using the region from Options.
+
+ MinioProcessOptions MinioOpts;
+ MinioOpts.Port = 19016;
+ MinioProcess Minio(MinioOpts);
+ Minio.SpawnMinioServer();
+ Minio.CreateBucket("zen-hydration-test");
+
+ ScopedEnvVar EnvAccessKey("AWS_ACCESS_KEY_ID", Minio.RootUser());
+ ScopedEnvVar EnvSecretKey("AWS_SECRET_ACCESS_KEY", Minio.RootPassword());
+ ScopedEnvVar EnvRegion("AWS_DEFAULT_REGION", "wrong-region");
+
+ ScopedTemporaryDirectory TempDir;
+
+ std::filesystem::path ServerStateDir = TempDir.Path() / "server_state";
+ std::filesystem::path HydrationTemp = TempDir.Path() / "hydration_temp";
+ CreateDirectories(ServerStateDir);
+ CreateDirectories(HydrationTemp);
+
+ auto TestFiles = CreateTestTree(ServerStateDir);
+
+ HydrationConfig Config;
+ Config.ServerStateDir = ServerStateDir;
+ Config.TempDir = HydrationTemp;
+ Config.ModuleId = "s3test_region_override";
+ {
+ std::string ConfigJson = fmt::format(
+ R"({{"type":"s3","settings":{{"uri":"s3://zen-hydration-test","endpoint":"{}","path-style":true,"region":"us-east-1"}}}})",
+ Minio.Endpoint());
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(ConfigJson, ParseError);
+ ZEN_ASSERT(ParseError.empty() && Root.IsObject());
+ Config.Options = std::move(Root).AsObject();
+ }
+
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Dehydrate();
+ }
+
+ CleanDirectory(ServerStateDir, true);
+
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+ Hydrator->Hydrate();
+ }
+
+ VerifyTree(ServerStateDir, TestFiles);
+}
+
+TEST_SUITE_END();
+
+void
+hydration_forcelink()
+{
+}
+
+#endif // ZEN_WITH_TESTS
+
} // namespace zen
diff --git a/src/zenserver/hub/hydration.h b/src/zenserver/hub/hydration.h
index 95b5cfae0..19a96c248 100644
--- a/src/zenserver/hub/hydration.h
+++ b/src/zenserver/hub/hydration.h
@@ -2,6 +2,8 @@
#pragma once
+#include <zencore/compactbinary.h>
+
#include <filesystem>
namespace zen {
@@ -16,6 +18,8 @@ struct HydrationConfig
std::string ModuleId;
// Back-end specific target specification (e.g. S3 bucket, file path, etc)
std::string TargetSpecification;
+ // Full config object when using --hub-hydration-target-config (mutually exclusive with TargetSpecification)
+ CbObject Options;
};
/**
@@ -35,6 +39,10 @@ struct HydrationStrategyBase
virtual void Configure(const HydrationConfig& Config) = 0;
};
-std::unique_ptr<HydrationStrategyBase> CreateFileHydrator();
+std::unique_ptr<HydrationStrategyBase> CreateHydrator(const HydrationConfig& Config);
+
+#if ZEN_WITH_TESTS
+void hydration_forcelink();
+#endif // ZEN_WITH_TESTS
} // namespace zen
diff --git a/src/zenserver/hub/storageserverinstance.cpp b/src/zenserver/hub/storageserverinstance.cpp
index 8e71e7aca..0c9354990 100644
--- a/src/zenserver/hub/storageserverinstance.cpp
+++ b/src/zenserver/hub/storageserverinstance.cpp
@@ -28,6 +28,7 @@ void
StorageServerInstance::SpawnServerProcess()
{
ZEN_ASSERT_FORMAT(!m_ServerInstance.IsRunning(), "Storage server instance for module '{}' is already running", m_ModuleId);
+ m_ServerInstance.ResetDeadProcess();
m_ServerInstance.SetServerExecutablePath(GetRunningExecutablePath());
m_ServerInstance.SetDataDir(m_BaseDir);
@@ -56,160 +57,305 @@ StorageServerInstance::SpawnServerProcess()
m_ServerInstance.EnableShutdownOnDestroy();
}
-void
-StorageServerInstance::Provision()
+ProcessMetrics
+StorageServerInstance::GetProcessMetrics() const
{
- RwLock::ExclusiveLockScope _(m_Lock);
+ ProcessMetrics Metrics;
+ if (m_ServerInstance.IsRunning())
+ {
+ zen::GetProcessMetrics(m_ServerInstance.GetProcessHandle(), Metrics);
+ }
+ return Metrics;
+}
- if (m_IsProvisioned)
+void
+StorageServerInstance::ProvisionLocked()
+{
+ if (m_ServerInstance.IsRunning())
{
ZEN_WARN("Storage server instance for module '{}' is already provisioned", m_ModuleId);
-
return;
}
- if (m_IsHibernated)
+ ZEN_INFO("Provisioning storage server instance for module '{}', at '{}'", m_ModuleId, m_BaseDir);
+ try
{
- WakeLocked();
+ Hydrate();
+ SpawnServerProcess();
}
- else
+ catch (const std::exception& Ex)
{
- ZEN_INFO("Provisioning storage server instance for module '{}', at '{}'", m_ModuleId, m_BaseDir);
-
- Hydrate();
+ ZEN_WARN("Failed spawning server instance for module '{}', at '{}' during provisioning. Reason: {}",
+ m_ModuleId,
+ m_BaseDir,
+ Ex.what());
+ throw;
+ }
+}
- SpawnServerProcess();
+void
+StorageServerInstance::DeprovisionLocked()
+{
+ if (m_ServerInstance.IsRunning())
+ {
+ // m_ServerInstance.Shutdown() never throws.
+ m_ServerInstance.Shutdown();
}
- m_IsProvisioned = true;
+ // Crashed or Hibernated: process already dead; skip Shutdown.
+ // Dehydrate preserves instance state for future re-provisioning. Failure means saved state
+ // may be stale or absent, but the process is already dead so the slot can still be released.
+ // Swallow the exception and proceed with cleanup rather than leaving the module stuck.
+ try
+ {
+ Dehydrate();
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("Dehydration of module {} failed during deprovisioning, current state not saved. Reason: {}", m_ModuleId, Ex.what());
+ }
}
void
-StorageServerInstance::Deprovision()
+StorageServerInstance::HibernateLocked()
{
- RwLock::ExclusiveLockScope _(m_Lock);
+ // Signal server to shut down, but keep data around for later wake
- if (!m_IsProvisioned)
+ if (!m_ServerInstance.IsRunning())
{
- ZEN_WARN("Attempted to deprovision storage server instance for module '{}' which is not provisioned", m_ModuleId);
-
return;
}
- ZEN_INFO("Deprovisioning storage server instance for module '{}'", m_ModuleId);
-
+ // m_ServerInstance.Shutdown() never throws.
m_ServerInstance.Shutdown();
-
- Dehydrate();
-
- m_IsProvisioned = false;
}
void
-StorageServerInstance::Hibernate()
+StorageServerInstance::WakeLocked()
{
- // Signal server to shut down, but keep data around for later wake
-
- RwLock::ExclusiveLockScope _(m_Lock);
+ // Start server in-place using existing data
- if (!m_IsProvisioned)
+ if (m_ServerInstance.IsRunning())
{
- ZEN_WARN("Attempted to hibernate storage server instance for module '{}' which is not provisioned", m_ModuleId);
-
return;
}
- if (m_IsHibernated)
+ try
{
- ZEN_WARN("Storage server instance for module '{}' is already hibernated", m_ModuleId);
-
- return;
+ SpawnServerProcess();
}
-
- if (!m_ServerInstance.IsRunning())
+ catch (const std::exception& Ex)
{
- ZEN_WARN("Attempted to hibernate storage server instance for module '{}' which is not running", m_ModuleId);
+ ZEN_WARN("Failed spawning server instance for module '{}', at '{}' during waking. Reason: {}", m_ModuleId, m_BaseDir, Ex.what());
+ throw;
+ }
+}
- // This is an unexpected state. Should consider the instance invalid?
+void
+StorageServerInstance::Hydrate()
+{
+ HydrationConfig Config{.ServerStateDir = m_BaseDir,
+ .TempDir = m_TempDir,
+ .ModuleId = m_ModuleId,
+ .TargetSpecification = m_Config.HydrationTargetSpecification,
+ .Options = m_Config.HydrationOptions};
- return;
- }
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
- try
+ Hydrator->Hydrate();
+}
+
+void
+StorageServerInstance::Dehydrate()
+{
+ HydrationConfig Config{.ServerStateDir = m_BaseDir,
+ .TempDir = m_TempDir,
+ .ModuleId = m_ModuleId,
+ .TargetSpecification = m_Config.HydrationTargetSpecification,
+ .Options = m_Config.HydrationOptions};
+
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
+
+ Hydrator->Dehydrate();
+}
+
+StorageServerInstance::SharedLockedPtr::SharedLockedPtr() : m_Lock(nullptr), m_Instance(nullptr)
+{
+}
+
+StorageServerInstance::SharedLockedPtr::SharedLockedPtr(RwLock& Lock, StorageServerInstance* Instance, bool Wait)
+: m_Lock(nullptr)
+, m_Instance(nullptr)
+{
+ ZEN_ASSERT(Instance != nullptr);
+ if (Wait)
{
- m_ServerInstance.Shutdown();
+ Lock.AcquireShared();
+ m_Lock = &Lock;
+ m_Instance = Instance;
+ }
+ else
+ {
+ if (Lock.TryAcquireShared())
+ {
+ m_Lock = &Lock;
+ m_Instance = Instance;
+ }
+ }
+}
- m_IsHibernated = true;
- m_IsProvisioned = false;
+StorageServerInstance::SharedLockedPtr::SharedLockedPtr(SharedLockedPtr&& Rhs) : m_Lock(Rhs.m_Lock), m_Instance(Rhs.m_Instance)
+{
+ Rhs.m_Lock = nullptr;
+ Rhs.m_Instance = nullptr;
+}
- return;
+StorageServerInstance::SharedLockedPtr::~SharedLockedPtr()
+{
+ if (m_Lock != nullptr)
+ {
+ m_Lock->ReleaseShared();
+ m_Lock = nullptr;
}
- catch (const std::exception& Ex)
+ m_Instance = nullptr;
+}
+
+StorageServerInstance::SharedLockedPtr&
+StorageServerInstance::SharedLockedPtr::operator=(SharedLockedPtr&& Rhs)
+{
+ if (m_Lock)
{
- ZEN_ERROR("Failed to hibernate storage server instance for module '{}': {}", m_ModuleId, Ex.what());
+ m_Lock->ReleaseShared();
+ m_Lock = nullptr;
+ m_Instance = nullptr;
}
+ m_Lock = Rhs.m_Lock;
+ m_Instance = Rhs.m_Instance;
+ Rhs.m_Lock = nullptr;
+ Rhs.m_Instance = nullptr;
+ return *this;
}
-void
-StorageServerInstance::Wake()
+std::string_view
+StorageServerInstance::SharedLockedPtr::GetModuleId() const
+{
+ ZEN_ASSERT(m_Instance != nullptr);
+ return m_Instance->m_ModuleId;
+}
+
+bool
+StorageServerInstance::SharedLockedPtr::IsRunning() const
{
- RwLock::ExclusiveLockScope _(m_Lock);
- WakeLocked();
+ ZEN_ASSERT(m_Instance != nullptr);
+ return m_Instance->m_ServerInstance.IsRunning();
}
+#if ZEN_WITH_TESTS
void
-StorageServerInstance::WakeLocked()
+StorageServerInstance::SharedLockedPtr::TerminateForTesting() const
{
- // Start server in-place using existing data
+ ZEN_ASSERT(m_Instance != nullptr);
+ m_Instance->m_ServerInstance.Terminate();
+}
+#endif
- if (!m_IsHibernated)
- {
- ZEN_WARN("Attempted to wake storage server instance for module '{}' which is not hibernated", m_ModuleId);
+StorageServerInstance::ExclusiveLockedPtr::ExclusiveLockedPtr() : m_Lock(nullptr), m_Instance(nullptr)
+{
+}
- return;
+StorageServerInstance::ExclusiveLockedPtr::ExclusiveLockedPtr(RwLock& Lock, StorageServerInstance* Instance, bool Wait)
+: m_Lock(nullptr)
+, m_Instance(nullptr)
+{
+ ZEN_ASSERT(Instance != nullptr);
+ if (Wait)
+ {
+ Lock.AcquireExclusive();
+ m_Lock = &Lock;
+ m_Instance = Instance;
+ }
+ else
+ {
+ if (Lock.TryAcquireExclusive())
+ {
+ m_Lock = &Lock;
+ m_Instance = Instance;
+ }
}
+}
- ZEN_ASSERT_FORMAT(!m_ServerInstance.IsRunning(), "Storage server instance for module '{}' is already running", m_ModuleId);
+StorageServerInstance::ExclusiveLockedPtr::ExclusiveLockedPtr(ExclusiveLockedPtr&& Rhs) : m_Lock(Rhs.m_Lock), m_Instance(Rhs.m_Instance)
+{
+ Rhs.m_Lock = nullptr;
+ Rhs.m_Instance = nullptr;
+}
- try
+StorageServerInstance::ExclusiveLockedPtr::~ExclusiveLockedPtr()
+{
+ if (m_Lock != nullptr)
{
- SpawnServerProcess();
- m_IsHibernated = false;
+ m_Lock->ReleaseExclusive();
+ m_Lock = nullptr;
}
- catch (const std::exception& Ex)
- {
- ZEN_ERROR("Failed to wake storage server instance for module '{}': {}", m_ModuleId, Ex.what());
+ m_Instance = nullptr;
+}
- // TODO: this instance should be marked as invalid
+StorageServerInstance::ExclusiveLockedPtr&
+StorageServerInstance::ExclusiveLockedPtr::operator=(ExclusiveLockedPtr&& Rhs)
+{
+ if (m_Lock)
+ {
+ m_Lock->ReleaseExclusive();
+ m_Lock = nullptr;
+ m_Instance = nullptr;
}
+ m_Lock = Rhs.m_Lock;
+ m_Instance = Rhs.m_Instance;
+ Rhs.m_Lock = nullptr;
+ Rhs.m_Instance = nullptr;
+ return *this;
}
-void
-StorageServerInstance::Hydrate()
+std::string_view
+StorageServerInstance::ExclusiveLockedPtr::GetModuleId() const
{
- HydrationConfig Config{.ServerStateDir = m_BaseDir,
- .TempDir = m_TempDir,
- .ModuleId = m_ModuleId,
- .TargetSpecification = WideToUtf8(m_Config.FileHydrationPath.native())};
+ ZEN_ASSERT(m_Instance != nullptr);
+ return m_Instance->m_ModuleId;
+}
- std::unique_ptr<HydrationStrategyBase> Hydrator = CreateFileHydrator();
+bool
+StorageServerInstance::ExclusiveLockedPtr::IsRunning() const
+{
+ ZEN_ASSERT(m_Instance != nullptr);
+ return m_Instance->m_ServerInstance.IsRunning();
+}
- Hydrator->Configure(Config);
- Hydrator->Hydrate();
+void
+StorageServerInstance::ExclusiveLockedPtr::Provision()
+{
+ ZEN_ASSERT(m_Instance != nullptr);
+ m_Instance->ProvisionLocked();
}
void
-StorageServerInstance::Dehydrate()
+StorageServerInstance::ExclusiveLockedPtr::Deprovision()
{
- HydrationConfig Config{.ServerStateDir = m_BaseDir,
- .TempDir = m_TempDir,
- .ModuleId = m_ModuleId,
- .TargetSpecification = WideToUtf8(m_Config.FileHydrationPath.native())};
+ ZEN_ASSERT(m_Instance != nullptr);
+ m_Instance->DeprovisionLocked();
+}
- std::unique_ptr<HydrationStrategyBase> Hydrator = CreateFileHydrator();
+void
+StorageServerInstance::ExclusiveLockedPtr::Hibernate()
+{
+ ZEN_ASSERT(m_Instance != nullptr);
+ m_Instance->HibernateLocked();
+}
- Hydrator->Configure(Config);
- Hydrator->Dehydrate();
+void
+StorageServerInstance::ExclusiveLockedPtr::Wake()
+{
+ ZEN_ASSERT(m_Instance != nullptr);
+ m_Instance->WakeLocked();
}
} // namespace zen
diff --git a/src/zenserver/hub/storageserverinstance.h b/src/zenserver/hub/storageserverinstance.h
index 3b3cae385..1b0078d87 100644
--- a/src/zenserver/hub/storageserverinstance.h
+++ b/src/zenserver/hub/storageserverinstance.h
@@ -2,8 +2,7 @@
#pragma once
-#include "resourcemetrics.h"
-
+#include <zencore/compactbinary.h>
#include <zenutil/zenserverprocess.h>
#include <atomic>
@@ -25,45 +24,117 @@ public:
{
uint16_t BasePort;
std::filesystem::path HydrationTempPath;
- std::filesystem::path FileHydrationPath;
- uint32_t HttpThreadCount = 0; // Deduce from core count
- int CoreLimit = 0; // Use hardware core count
+ std::string HydrationTargetSpecification;
+ CbObject HydrationOptions;
+ uint32_t HttpThreadCount = 0; // Automatic
+ int CoreLimit = 0; // Automatic
std::filesystem::path ConfigPath;
};
StorageServerInstance(ZenServerEnvironment& RunEnvironment, const Configuration& Config, std::string_view ModuleId);
~StorageServerInstance();
- void Provision();
- void Deprovision();
+ inline std::string_view GetModuleId() const { return m_ModuleId; }
+ inline uint16_t GetBasePort() const { return m_Config.BasePort; }
+ ProcessMetrics GetProcessMetrics() const;
- void Hibernate();
- void Wake();
+#if ZEN_PLATFORM_WINDOWS
+ void SetJobObject(JobObject* InJobObject) { m_JobObject = InJobObject; }
+#endif
- const ResourceMetrics& GetResourceMetrics() const { return m_ResourceMetrics; }
+ class SharedLockedPtr
+ {
+ public:
+ SharedLockedPtr(const SharedLockedPtr&) = delete;
+ SharedLockedPtr();
- inline std::string_view GetModuleId() const { return m_ModuleId; }
- inline bool IsProvisioned() const { return m_IsProvisioned.load(); }
+ SharedLockedPtr(RwLock& Lock, StorageServerInstance* Instance, bool Wait);
- inline uint16_t GetBasePort() const { return m_ServerInstance.GetBasePort(); }
+ SharedLockedPtr(SharedLockedPtr&& Rhs);
+ ~SharedLockedPtr();
-#if ZEN_PLATFORM_WINDOWS
- void SetJobObject(JobObject* InJobObject) { m_JobObject = InJobObject; }
+ SharedLockedPtr& operator=(const SharedLockedPtr&) = delete;
+ SharedLockedPtr& operator =(SharedLockedPtr&& Rhs);
+
+ operator bool() const { return m_Instance != nullptr; }
+
+ std::string_view GetModuleId() const;
+ uint16_t GetBasePort() const
+ {
+ ZEN_ASSERT(m_Instance);
+ return m_Instance->GetBasePort();
+ }
+ bool IsRunning() const;
+
+ ProcessMetrics GetProcessMetrics() const
+ {
+ ZEN_ASSERT(m_Instance);
+ return m_Instance->GetProcessMetrics();
+ }
+
+#if ZEN_WITH_TESTS
+ void TerminateForTesting() const; // kills the child process to simulate a crash
#endif
+ private:
+ RwLock* m_Lock = nullptr;
+ StorageServerInstance* m_Instance = nullptr;
+ };
+
+ [[nodiscard]] SharedLockedPtr LockShared(bool Wait) { return SharedLockedPtr(m_Lock, this, Wait); }
+
+ class ExclusiveLockedPtr
+ {
+ public:
+ ExclusiveLockedPtr(const ExclusiveLockedPtr&) = delete;
+ ExclusiveLockedPtr();
+
+ ExclusiveLockedPtr(RwLock& Lock, StorageServerInstance* Instance, bool Wait);
+
+ ExclusiveLockedPtr(ExclusiveLockedPtr&& Rhs);
+ ~ExclusiveLockedPtr();
+
+ ExclusiveLockedPtr& operator=(const ExclusiveLockedPtr&) = delete;
+ ExclusiveLockedPtr& operator =(ExclusiveLockedPtr&& Rhs);
+
+ operator bool() const { return m_Instance != nullptr; }
+
+ std::string_view GetModuleId() const;
+ uint16_t GetBasePort() const
+ {
+ ZEN_ASSERT(m_Instance);
+ return m_Instance->GetBasePort();
+ }
+ bool IsRunning() const;
+
+ void Provision();
+ void Deprovision();
+ void Hibernate();
+ void Wake();
+
+ private:
+ RwLock* m_Lock = nullptr;
+ StorageServerInstance* m_Instance = nullptr;
+ };
+
+ [[nodiscard]] ExclusiveLockedPtr LockExclusive(bool Wait) { return ExclusiveLockedPtr(m_Lock, this, Wait); }
+
private:
- void WakeLocked();
- RwLock m_Lock;
+ void ProvisionLocked();
+ void DeprovisionLocked();
+
+ void HibernateLocked();
+ void WakeLocked();
+
+ mutable RwLock m_Lock;
const Configuration m_Config;
std::string m_ModuleId;
ZenServerInstance m_ServerInstance;
- std::atomic<bool> m_IsProvisioned{false};
- std::atomic<bool> m_IsHibernated{false};
std::filesystem::path m_BaseDir;
std::filesystem::path m_TempDir;
- ResourceMetrics m_ResourceMetrics;
+
#if ZEN_PLATFORM_WINDOWS
JobObject* m_JobObject = nullptr;
#endif
@@ -72,6 +143,9 @@ private:
void Hydrate();
void Dehydrate();
+
+ friend class SharedLockedPtr;
+ friend class ExclusiveLockedPtr;
};
} // namespace zen
diff --git a/src/zenserver/hub/zenhubserver.cpp b/src/zenserver/hub/zenhubserver.cpp
index b36a0778e..5308a76f1 100644
--- a/src/zenserver/hub/zenhubserver.cpp
+++ b/src/zenserver/hub/zenhubserver.cpp
@@ -2,20 +2,28 @@
#include "zenhubserver.h"
+#include "config/luaconfig.h"
#include "frontend/frontend.h"
#include "httphubservice.h"
+#include "httpproxyhandler.h"
#include "hub.h"
+#include <zencore/compactbinary.h>
#include <zencore/config.h>
+#include <zencore/except.h>
+#include <zencore/except_fmt.h>
+#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
#include <zencore/memory/llm.h>
#include <zencore/memory/memorytrace.h>
#include <zencore/memory/tagtrace.h>
#include <zencore/scopeguard.h>
#include <zencore/sentryintegration.h>
+#include <zencore/system.h>
#include <zencore/windows.h>
#include <zenhttp/httpapiservice.h>
#include <zenutil/service.h>
+#include <zenutil/workerpools.h>
ZEN_THIRD_PARTY_INCLUDES_START
#include <cxxopts.hpp>
@@ -23,6 +31,13 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
+const std::string&
+GetDefaultConsulTokenEnvVariableName()
+{
+ static const std::string Name = "CONSUL_HTTP_TOKEN";
+ return Name;
+}
+
void
ZenHubServerConfigurator::AddCliOptions(cxxopts::Options& Options)
{
@@ -45,12 +60,19 @@ ZenHubServerConfigurator::AddCliOptions(cxxopts::Options& Options)
Options.add_option("hub",
"",
"instance-id",
- "Instance ID for use in notifications",
+ "Instance ID for use in notifications (deprecated, use --upstream-notification-instance-id)",
cxxopts::value<std::string>(m_ServerOptions.InstanceId)->default_value(""),
"");
Options.add_option("hub",
"",
+ "upstream-notification-instance-id",
+ "Instance ID for use in notifications",
+ cxxopts::value<std::string>(m_ServerOptions.InstanceId),
+ "");
+
+ Options.add_option("hub",
+ "",
"consul-endpoint",
"Consul endpoint URL for service registration (empty = disabled)",
cxxopts::value<std::string>(m_ServerOptions.ConsulEndpoint)->default_value(""),
@@ -58,13 +80,42 @@ ZenHubServerConfigurator::AddCliOptions(cxxopts::Options& Options)
Options.add_option("hub",
"",
+ "consul-token-env",
+ fmt::format("Name of environment variable that holds the consul access token (defaults to '{}')",
+ GetDefaultConsulTokenEnvVariableName()),
+ cxxopts::value<std::string>(m_ServerOptions.ConsulTokenEnv)->default_value(""),
+ "<envvariable>");
+
+ Options.add_option("hub",
+ "",
+ "consul-health-interval-seconds",
+ "Interval in seconds between Consul health checks",
+ cxxopts::value<uint32_t>(m_ServerOptions.ConsulHealthIntervalSeconds)->default_value("10"),
+ "<seconds>");
+
+ Options.add_option("hub",
+ "",
+ "consul-deregister-after-seconds",
+ "Seconds after which Consul deregisters an unhealthy service",
+ cxxopts::value<uint32_t>(m_ServerOptions.ConsulDeregisterAfterSeconds)->default_value("30"),
+ "<seconds>");
+
+ Options.add_option("hub",
+ "",
"hub-base-port-number",
- "Base port number for provisioned instances",
+ "Base port number for provisioned instances (deprecated, use --hub-instance-base-port-number)",
cxxopts::value<uint16_t>(m_ServerOptions.HubBasePortNumber)->default_value("21000"),
"");
Options.add_option("hub",
"",
+ "hub-instance-base-port-number",
+ "Base port number for provisioned instances",
+ cxxopts::value<uint16_t>(m_ServerOptions.HubBasePortNumber),
+ "");
+
+ Options.add_option("hub",
+ "",
"hub-instance-limit",
"Maximum number of provisioned instances for this hub",
cxxopts::value<int>(m_ServerOptions.HubInstanceLimit)->default_value("1000"),
@@ -101,6 +152,22 @@ ZenHubServerConfigurator::AddCliOptions(cxxopts::Options& Options)
cxxopts::value(m_ServerOptions.HubInstanceConfigPath),
"<instance config>");
+ Options.add_option("hub",
+ "",
+ "hub-hydration-target-spec",
+ "Specification for hydration target. 'file://<path>' prefix indicates file storage at <path>. Defaults to "
+ "<data-dir>/servers/hydration_storage",
+ cxxopts::value(m_ServerOptions.HydrationTargetSpecification),
+ "<hydration-target-spec>");
+
+ Options.add_option("hub",
+ "",
+ "hub-hydration-target-config",
+ "Path to JSON file specifying the hydration target (mutually exclusive with "
+ "--hub-hydration-target-spec). Supported types: 'file', 's3'.",
+ cxxopts::value(m_ServerOptions.HydrationTargetConfigPath),
+ "<path>");
+
#if ZEN_PLATFORM_WINDOWS
Options.add_option("hub",
"",
@@ -109,12 +176,159 @@ ZenHubServerConfigurator::AddCliOptions(cxxopts::Options& Options)
cxxopts::value<bool>(m_ServerOptions.HubUseJobObject)->default_value("true"),
"");
#endif // ZEN_PLATFORM_WINDOWS
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-cycle-interval-ms",
+ "Interval between watchdog cycles in milliseconds",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.CycleIntervalMs)->default_value("3000"),
+ "<ms>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-cycle-processing-budget-ms",
+ "Maximum processing time budget per watchdog cycle in milliseconds",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.CycleProcessingBudgetMs)->default_value("500"),
+ "<ms>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-instance-check-throttle-ms",
+ "Delay between checking successive instances per watchdog cycle in milliseconds",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.InstanceCheckThrottleMs)->default_value("5"),
+ "<ms>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-provisioned-inactivity-timeout-seconds",
+ "Seconds of inactivity after which a provisioned instance is deprovisioned",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.ProvisionedInactivityTimeoutSeconds)->default_value("600"),
+ "<seconds>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-hibernated-inactivity-timeout-seconds",
+ "Seconds of inactivity after which a hibernated instance is deprovisioned",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.HibernatedInactivityTimeoutSeconds)->default_value("1800"),
+ "<seconds>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-inactivity-check-margin-seconds",
+ "Margin in seconds subtracted from inactivity timeout before triggering an activity check",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.InactivityCheckMarginSeconds)->default_value("60"),
+ "<seconds>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-activity-check-connect-timeout-ms",
+ "Connect timeout in milliseconds for instance activity check requests",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.ActivityCheckConnectTimeoutMs)->default_value("100"),
+ "<ms>");
+
+ Options.add_option("hub",
+ "",
+ "hub-watchdog-activity-check-request-timeout-ms",
+ "Request timeout in milliseconds for instance activity check requests",
+ cxxopts::value<uint32_t>(m_ServerOptions.WatchdogConfig.ActivityCheckRequestTimeoutMs)->default_value("200"),
+ "<ms>");
+
+ Options.add_option("hub",
+ "",
+ "hub-provision-disk-limit-bytes",
+ "Reject provisioning when used disk bytes exceed this value (0 = no limit).",
+ cxxopts::value<uint64_t>(m_ServerOptions.HubProvisionDiskLimitBytes),
+ "<bytes>");
+
+ Options.add_option("hub",
+ "",
+ "hub-provision-disk-limit-percent",
+ "Reject provisioning when used disk exceeds this percentage of total disk (0 = no limit).",
+ cxxopts::value<uint32_t>(m_ServerOptions.HubProvisionDiskLimitPercent),
+ "<percent>");
+
+ Options.add_option("hub",
+ "",
+ "hub-provision-memory-limit-bytes",
+ "Reject provisioning when used memory bytes exceed this value (0 = no limit).",
+ cxxopts::value<uint64_t>(m_ServerOptions.HubProvisionMemoryLimitBytes),
+ "<bytes>");
+
+ Options.add_option("hub",
+ "",
+ "hub-provision-memory-limit-percent",
+ "Reject provisioning when used memory exceeds this percentage of total RAM (0 = no limit).",
+ cxxopts::value<uint32_t>(m_ServerOptions.HubProvisionMemoryLimitPercent),
+ "<percent>");
}
void
ZenHubServerConfigurator::AddConfigOptions(LuaConfig::Options& Options)
{
- ZEN_UNUSED(Options);
+ using namespace std::literals;
+
+ Options.AddOption("hub.upstreamnotification.endpoint"sv,
+ m_ServerOptions.UpstreamNotificationEndpoint,
+ "upstream-notification-endpoint"sv);
+ Options.AddOption("hub.upstreamnotification.instanceid"sv, m_ServerOptions.InstanceId, "upstream-notification-instance-id"sv);
+
+ Options.AddOption("hub.consul.endpoint"sv, m_ServerOptions.ConsulEndpoint, "consul-endpoint"sv);
+ Options.AddOption("hub.consul.tokenenv"sv, m_ServerOptions.ConsulTokenEnv, "consul-token-env"sv);
+ Options.AddOption("hub.consul.healthintervalseconds"sv,
+ m_ServerOptions.ConsulHealthIntervalSeconds,
+ "consul-health-interval-seconds"sv);
+ Options.AddOption("hub.consul.deregisterafterseconds"sv,
+ m_ServerOptions.ConsulDeregisterAfterSeconds,
+ "consul-deregister-after-seconds"sv);
+
+ Options.AddOption("hub.instance.baseportnumber"sv, m_ServerOptions.HubBasePortNumber, "hub-instance-base-port-number"sv);
+ Options.AddOption("hub.instance.http"sv, m_ServerOptions.HubInstanceHttpClass, "hub-instance-http"sv);
+ Options.AddOption("hub.instance.httpthreads"sv, m_ServerOptions.HubInstanceHttpThreadCount, "hub-instance-http-threads"sv);
+ Options.AddOption("hub.instance.corelimit"sv, m_ServerOptions.HubInstanceCoreLimit, "hub-instance-corelimit"sv);
+ Options.AddOption("hub.instance.config"sv, m_ServerOptions.HubInstanceConfigPath, "hub-instance-config"sv);
+ Options.AddOption("hub.instance.limits.count"sv, m_ServerOptions.HubInstanceLimit, "hub-instance-limit"sv);
+ Options.AddOption("hub.instance.limits.disklimitbytes"sv,
+ m_ServerOptions.HubProvisionDiskLimitBytes,
+ "hub-provision-disk-limit-bytes"sv);
+ Options.AddOption("hub.instance.limits.disklimitpercent"sv,
+ m_ServerOptions.HubProvisionDiskLimitPercent,
+ "hub-provision-disk-limit-percent"sv);
+ Options.AddOption("hub.instance.limits.memorylimitbytes"sv,
+ m_ServerOptions.HubProvisionMemoryLimitBytes,
+ "hub-provision-memory-limit-bytes"sv);
+ Options.AddOption("hub.instance.limits.memorylimitpercent"sv,
+ m_ServerOptions.HubProvisionMemoryLimitPercent,
+ "hub-provision-memory-limit-percent"sv);
+
+ Options.AddOption("hub.hydration.targetspec"sv, m_ServerOptions.HydrationTargetSpecification, "hub-hydration-target-spec"sv);
+ Options.AddOption("hub.hydration.targetconfig"sv, m_ServerOptions.HydrationTargetConfigPath, "hub-hydration-target-config"sv);
+
+ Options.AddOption("hub.watchdog.cycleintervalms"sv, m_ServerOptions.WatchdogConfig.CycleIntervalMs, "hub-watchdog-cycle-interval-ms"sv);
+ Options.AddOption("hub.watchdog.cycleprocessingbudgetms"sv,
+ m_ServerOptions.WatchdogConfig.CycleProcessingBudgetMs,
+ "hub-watchdog-cycle-processing-budget-ms"sv);
+ Options.AddOption("hub.watchdog.instancecheckthrottlems"sv,
+ m_ServerOptions.WatchdogConfig.InstanceCheckThrottleMs,
+ "hub-watchdog-instance-check-throttle-ms"sv);
+ Options.AddOption("hub.watchdog.provisionedinactivitytimeoutseconds"sv,
+ m_ServerOptions.WatchdogConfig.ProvisionedInactivityTimeoutSeconds,
+ "hub-watchdog-provisioned-inactivity-timeout-seconds"sv);
+ Options.AddOption("hub.watchdog.hibernatedinactivitytimeoutseconds"sv,
+ m_ServerOptions.WatchdogConfig.HibernatedInactivityTimeoutSeconds,
+ "hub-watchdog-hibernated-inactivity-timeout-seconds"sv);
+ Options.AddOption("hub.watchdog.inactivitycheckmarginseconds"sv,
+ m_ServerOptions.WatchdogConfig.InactivityCheckMarginSeconds,
+ "hub-watchdog-inactivity-check-margin-seconds"sv);
+ Options.AddOption("hub.watchdog.activitycheckconnecttimeoutms"sv,
+ m_ServerOptions.WatchdogConfig.ActivityCheckConnectTimeoutMs,
+ "hub-watchdog-activity-check-connect-timeout-ms"sv);
+ Options.AddOption("hub.watchdog.activitycheckrequesttimeoutms"sv,
+ m_ServerOptions.WatchdogConfig.ActivityCheckRequestTimeoutMs,
+ "hub-watchdog-activity-check-request-timeout-ms"sv);
+
+#if ZEN_PLATFORM_WINDOWS
+ Options.AddOption("hub.usejobobject"sv, m_ServerOptions.HubUseJobObject, "hub-use-job-object"sv);
+#endif
}
void
@@ -132,6 +346,28 @@ ZenHubServerConfigurator::OnConfigFileParsed(LuaConfig::Options& LuaOptions)
void
ZenHubServerConfigurator::ValidateOptions()
{
+ if (m_ServerOptions.HubProvisionDiskLimitPercent > 100)
+ {
+ throw OptionParseException(
+ fmt::format("'--hub-provision-disk-limit-percent' ({}) must be in range 0..100", m_ServerOptions.HubProvisionDiskLimitPercent),
+ {});
+ }
+ if (m_ServerOptions.HubProvisionMemoryLimitPercent > 100)
+ {
+ throw OptionParseException(fmt::format("'--hub-provision-memory-limit-percent' ({}) must be in range 0..100",
+ m_ServerOptions.HubProvisionMemoryLimitPercent),
+ {});
+ }
+ if (!m_ServerOptions.HydrationTargetSpecification.empty() && !m_ServerOptions.HydrationTargetConfigPath.empty())
+ {
+ throw OptionParseException("'--hub-hydration-target-spec' and '--hub-hydration-target-config' are mutually exclusive", {});
+ }
+ if (!m_ServerOptions.HydrationTargetConfigPath.empty() && !std::filesystem::exists(m_ServerOptions.HydrationTargetConfigPath))
+ {
+ throw OptionParseException(
+ fmt::format("'--hub-hydration-target-config': file not found: '{}'", m_ServerOptions.HydrationTargetConfigPath.string()),
+ {});
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -146,21 +382,43 @@ ZenHubServer::~ZenHubServer()
}
void
-ZenHubServer::OnProvisioned(std::string_view HubInstanceId, std::string_view ModuleId, const HubProvisionedInstanceInfo& Info)
+ZenHubServer::OnModuleStateChanged(std::string_view HubInstanceId,
+ std::string_view ModuleId,
+ const HubProvisionedInstanceInfo& Info,
+ HubInstanceState PreviousState,
+ HubInstanceState NewState)
{
- if (m_ConsulClient)
+ ZEN_UNUSED(PreviousState);
+
+ if (NewState == HubInstanceState::Deprovisioning || NewState == HubInstanceState::Hibernating)
+ {
+ if (Info.Port != 0)
+ {
+ m_Proxy->PrunePort(Info.Port);
+ }
+ }
+
+ if (!m_ConsulClient)
+ {
+ return;
+ }
+
+ if (NewState == HubInstanceState::Provisioning || NewState == HubInstanceState::Provisioned)
{
consul::ServiceRegistrationInfo ServiceInfo{
- .ServiceId = std::string(ModuleId),
- .ServiceName = "zen-storage",
- // .Address = "localhost", // Let the consul agent figure out out external address // TODO: Info.BaseUri?
+ .ServiceId = std::string(ModuleId),
+ .ServiceName = "zen-storage",
.Port = Info.Port,
.HealthEndpoint = "health",
.Tags = std::vector<std::pair<std::string, std::string>>{std::make_pair("module", std::string(ModuleId)),
std::make_pair("zen-hub", std::string(HubInstanceId)),
std::make_pair("version", std::string(ZEN_CFG_VERSION))},
- .HealthIntervalSeconds = 10,
- .DeregisterAfterSeconds = 30};
+ .HealthIntervalSeconds = NewState == HubInstanceState::Provisioning
+ ? 0u
+ : m_ConsulHealthIntervalSeconds, // Disable health checks while not finished provisioning
+ .DeregisterAfterSeconds = NewState == HubInstanceState::Provisioning
+ ? 0u
+ : m_ConsulDeregisterAfterSeconds}; // Disable health checks while not finished provisioning
if (!m_ConsulClient->RegisterService(ServiceInfo))
{
@@ -174,13 +432,7 @@ ZenHubServer::OnProvisioned(std::string_view HubInstanceId, std::string_view Mod
ServiceInfo.ServiceName);
}
}
-}
-
-void
-ZenHubServer::OnDeprovisioned(std::string_view HubInstanceId, std::string_view ModuleId, const HubProvisionedInstanceInfo& Info)
-{
- ZEN_UNUSED(HubInstanceId);
- if (m_ConsulClient)
+ else if (NewState == HubInstanceState::Unprovisioned)
{
if (!m_ConsulClient->DeregisterService(ModuleId))
{
@@ -193,6 +445,8 @@ ZenHubServer::OnDeprovisioned(std::string_view HubInstanceId, std::string_view M
ZEN_INFO("Deregistered storage server instance for module '{}' at port {} from Consul", ModuleId, Info.Port);
}
}
+ // Transitional states (Waking, Recovering, Crashed) and stable states
+ // not handled above (Hibernated) are intentionally ignored by Consul.
}
int
@@ -245,10 +499,21 @@ ZenHubServer::Cleanup()
m_Http->Close();
}
+ if (m_Proxy)
+ {
+ m_Proxy->Shutdown();
+ }
+
+ if (m_Hub)
+ {
+ m_Hub->Shutdown();
+ }
+
m_FrontendService.reset();
m_HubService.reset();
m_ApiService.reset();
m_Hub.reset();
+ m_Proxy.reset();
m_ConsulRegistration.reset();
m_ConsulClient.reset();
@@ -265,40 +530,119 @@ ZenHubServer::InitializeState(const ZenHubServerConfig& ServerConfig)
ZEN_UNUSED(ServerConfig);
}
+ResourceMetrics
+ZenHubServer::ResolveLimits(const ZenHubServerConfig& ServerConfig)
+{
+ uint64_t DiskTotal = 0;
+ uint64_t MemoryTotal = 0;
+
+ if (ServerConfig.HubProvisionDiskLimitPercent > 0)
+ {
+ DiskSpace Disk;
+ if (DiskSpaceInfo(ServerConfig.DataDir, Disk))
+ {
+ DiskTotal = Disk.Total;
+ }
+ else
+ {
+ ZEN_WARN("Failed to query disk space for '{}'; disk percent limit will not be applied", ServerConfig.DataDir);
+ }
+ }
+ if (ServerConfig.HubProvisionMemoryLimitPercent > 0)
+ {
+ MemoryTotal = GetSystemMetrics().SystemMemoryMiB * 1024 * 1024;
+ }
+
+ auto Resolve = [](uint64_t Bytes, uint32_t Pct, uint64_t Total) -> uint64_t {
+ const uint64_t PctBytes = Pct > 0 ? (Total * Pct) / 100 : 0;
+ if (Bytes > 0 && PctBytes > 0)
+ {
+ return Min(Bytes, PctBytes);
+ }
+ return Bytes > 0 ? Bytes : PctBytes;
+ };
+
+ return {
+ .DiskUsageBytes = Resolve(ServerConfig.HubProvisionDiskLimitBytes, ServerConfig.HubProvisionDiskLimitPercent, DiskTotal),
+ .MemoryUsageBytes = Resolve(ServerConfig.HubProvisionMemoryLimitBytes, ServerConfig.HubProvisionMemoryLimitPercent, MemoryTotal),
+ };
+}
+
void
ZenHubServer::InitializeServices(const ZenHubServerConfig& ServerConfig)
{
- ZEN_UNUSED(ServerConfig);
-
ZEN_INFO("instantiating Hub");
+ Hub::Configuration HubConfig{
+ .UseJobObject = ServerConfig.HubUseJobObject,
+ .BasePortNumber = ServerConfig.HubBasePortNumber,
+ .InstanceLimit = ServerConfig.HubInstanceLimit,
+ .InstanceHttpThreadCount = ServerConfig.HubInstanceHttpThreadCount,
+ .InstanceCoreLimit = ServerConfig.HubInstanceCoreLimit,
+ .InstanceConfigPath = ServerConfig.HubInstanceConfigPath,
+ .HydrationTargetSpecification = ServerConfig.HydrationTargetSpecification,
+ .WatchDog =
+ {
+ .CycleInterval = std::chrono::milliseconds(ServerConfig.WatchdogConfig.CycleIntervalMs),
+ .CycleProcessingBudget = std::chrono::milliseconds(ServerConfig.WatchdogConfig.CycleProcessingBudgetMs),
+ .InstanceCheckThrottle = std::chrono::milliseconds(ServerConfig.WatchdogConfig.InstanceCheckThrottleMs),
+ .ProvisionedInactivityTimeout = std::chrono::seconds(ServerConfig.WatchdogConfig.ProvisionedInactivityTimeoutSeconds),
+ .HibernatedInactivityTimeout = std::chrono::seconds(ServerConfig.WatchdogConfig.HibernatedInactivityTimeoutSeconds),
+ .InactivityCheckMargin = std::chrono::seconds(ServerConfig.WatchdogConfig.InactivityCheckMarginSeconds),
+ .ActivityCheckConnectTimeout = std::chrono::milliseconds(ServerConfig.WatchdogConfig.ActivityCheckConnectTimeoutMs),
+ .ActivityCheckRequestTimeout = std::chrono::milliseconds(ServerConfig.WatchdogConfig.ActivityCheckRequestTimeoutMs),
+ },
+ .ResourceLimits = ResolveLimits(ServerConfig)};
+
+ if (!ServerConfig.HydrationTargetConfigPath.empty())
+ {
+ FileContents Contents = ReadFile(ServerConfig.HydrationTargetConfigPath);
+ if (!Contents)
+ {
+ throw zen::runtime_error("Failed to read hydration config '{}': {}",
+ ServerConfig.HydrationTargetConfigPath.string(),
+ Contents.ErrorCode.message());
+ }
+ IoBuffer Buffer(Contents.Flatten());
+ std::string_view JsonText(static_cast<const char*>(Buffer.GetData()), Buffer.GetSize());
+
+ std::string ParseError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(JsonText, ParseError);
+ if (!ParseError.empty() || !Root.IsObject())
+ {
+ throw zen::runtime_error("Failed to parse hydration config '{}': {}",
+ ServerConfig.HydrationTargetConfigPath.string(),
+ ParseError.empty() ? "root must be a JSON object" : ParseError);
+ }
+ HubConfig.HydrationOptions = std::move(Root).AsObject();
+ }
+
+ m_Proxy = std::make_unique<HttpProxyHandler>();
+
m_Hub = std::make_unique<Hub>(
- Hub::Configuration{.UseJobObject = ServerConfig.HubUseJobObject,
- .BasePortNumber = ServerConfig.HubBasePortNumber,
- .InstanceLimit = ServerConfig.HubInstanceLimit,
- .InstanceHttpThreadCount = ServerConfig.HubInstanceHttpThreadCount,
- .InstanceCoreLimit = ServerConfig.HubInstanceCoreLimit,
- .InstanceConfigPath = ServerConfig.HubInstanceConfigPath},
+ std::move(HubConfig),
ZenServerEnvironment(ZenServerEnvironment::Hub,
ServerConfig.DataDir / "hub",
ServerConfig.DataDir / "servers",
ServerConfig.HubInstanceHttpClass),
- m_ConsulClient ? [this, HubInstanceId = fmt::format("zen-hub-{}", ServerConfig.InstanceId)](
- std::string_view ModuleId,
- const HubProvisionedInstanceInfo& Info) { OnProvisioned(HubInstanceId, ModuleId, Info); }
- : Hub::ProvisionModuleCallbackFunc{},
- m_ConsulClient ? [this, HubInstanceId = fmt::format("zen-hub-{}", ServerConfig.InstanceId)](
- std::string_view ModuleId,
- const HubProvisionedInstanceInfo& Info) { OnDeprovisioned(HubInstanceId, ModuleId, Info); }
- : Hub::ProvisionModuleCallbackFunc{});
+ &GetMediumWorkerPool(EWorkloadType::Background),
+ Hub::AsyncModuleStateChangeCallbackFunc{
+ [this, HubInstanceId = fmt::format("zen-hub-{}", ServerConfig.InstanceId)](std::string_view ModuleId,
+ const HubProvisionedInstanceInfo& Info,
+ HubInstanceState PreviousState,
+ HubInstanceState NewState) {
+ OnModuleStateChanged(HubInstanceId, ModuleId, Info, PreviousState, NewState);
+ }});
+
+ m_Proxy->SetPortValidator([Hub = m_Hub.get()](uint16_t Port) { return Hub->IsInstancePort(Port); });
ZEN_INFO("instantiating API service");
m_ApiService = std::make_unique<zen::HttpApiService>(*m_Http);
ZEN_INFO("instantiating hub service");
- m_HubService = std::make_unique<HttpHubService>(*m_Hub);
+ m_HubService = std::make_unique<HttpHubService>(*m_Hub, *m_Proxy, m_StatsService, m_StatusService);
m_HubService->SetNotificationEndpoint(ServerConfig.UpstreamNotificationEndpoint, ServerConfig.InstanceId);
- m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatusService);
+ m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatsService, m_StatusService);
}
void
@@ -333,9 +677,29 @@ ZenHubServer::InitializeConsulRegistration(const ZenHubServerConfig& ServerConfi
ZEN_INFO("Initializing Consul registration with endpoint: {}", ServerConfig.ConsulEndpoint);
+ std::string ConsulAccessTokenEnvName =
+ ServerConfig.ConsulTokenEnv.empty() ? GetDefaultConsulTokenEnvVariableName() : ServerConfig.ConsulTokenEnv;
+ std::string ConsulAccessToken = GetEnvVariable(ConsulAccessTokenEnvName);
+ if (ConsulAccessToken.empty())
+ {
+ if (!ServerConfig.ConsulTokenEnv.empty())
+ {
+ ZEN_WARN("Consul token environment variable '{}' is not set or empty", ServerConfig.ConsulTokenEnv);
+ }
+ }
+ else
+ {
+ ZEN_INFO("Consul token will be read from environment variable '{}'", ConsulAccessTokenEnvName);
+ }
+
try
{
- m_ConsulClient = std::make_unique<consul::ConsulClient>(ServerConfig.ConsulEndpoint);
+ m_ConsulClient = std::make_unique<consul::ConsulClient>(consul::ConsulClient::Configuration{
+ .BaseUri = ServerConfig.ConsulEndpoint,
+ .TokenEnvName = ConsulAccessTokenEnvName,
+ });
+ m_ConsulHealthIntervalSeconds = ServerConfig.ConsulHealthIntervalSeconds;
+ m_ConsulDeregisterAfterSeconds = ServerConfig.ConsulDeregisterAfterSeconds;
consul::ServiceRegistrationInfo Info;
Info.ServiceId = fmt::format("zen-hub-{}", ServerConfig.InstanceId);
@@ -349,6 +713,8 @@ ZenHubServer::InitializeConsulRegistration(const ZenHubServerConfig& ServerConfi
std::make_pair("base-port-number", fmt::format("{}", ServerConfig.HubBasePortNumber)),
std::make_pair("instance-limit", fmt::format("{}", ServerConfig.HubInstanceLimit)),
std::make_pair("use-job-object", fmt::format("{}", ServerConfig.HubUseJobObject))};
+ Info.HealthIntervalSeconds = ServerConfig.ConsulHealthIntervalSeconds;
+ Info.DeregisterAfterSeconds = ServerConfig.ConsulDeregisterAfterSeconds;
m_ConsulRegistration = std::make_unique<consul::ServiceRegistration>(m_ConsulClient.get(), Info);
diff --git a/src/zenserver/hub/zenhubserver.h b/src/zenserver/hub/zenhubserver.h
index 7e85159f1..d1add7690 100644
--- a/src/zenserver/hub/zenhubserver.h
+++ b/src/zenserver/hub/zenhubserver.h
@@ -2,6 +2,8 @@
#pragma once
+#include "hubinstancestate.h"
+#include "resourcemetrics.h"
#include "zenserver.h"
#include <zenutil/consul.h>
@@ -18,19 +20,42 @@ namespace zen {
class HttpApiService;
class HttpFrontendService;
class HttpHubService;
+class HttpProxyHandler;
+
+struct ZenHubWatchdogConfig
+{
+ uint32_t CycleIntervalMs = 3000;
+ uint32_t CycleProcessingBudgetMs = 500;
+ uint32_t InstanceCheckThrottleMs = 5;
+ uint32_t ProvisionedInactivityTimeoutSeconds = 600;
+ uint32_t HibernatedInactivityTimeoutSeconds = 1800;
+ uint32_t InactivityCheckMarginSeconds = 60; // Activity check is triggered this far before the inactivity timeout
+ uint32_t ActivityCheckConnectTimeoutMs = 100;
+ uint32_t ActivityCheckRequestTimeoutMs = 200;
+};
struct ZenHubServerConfig : public ZenServerConfig
{
std::string UpstreamNotificationEndpoint;
std::string InstanceId; // For use in notifications
std::string ConsulEndpoint; // If set, enables Consul service registration
- uint16_t HubBasePortNumber = 21000;
- int HubInstanceLimit = 1000;
- bool HubUseJobObject = true;
- std::string HubInstanceHttpClass = "asio";
- uint32_t HubInstanceHttpThreadCount = 0; // Deduce from core count
- int HubInstanceCoreLimit = 0; // Use hardware core count
- std::filesystem::path HubInstanceConfigPath; // Path to Lua config file
+ std::string ConsulTokenEnv; // Environment variable name to read a Consul token from; defaults to CONSUL_HTTP_TOKEN if empty
+ uint32_t ConsulHealthIntervalSeconds = 10; // Interval in seconds between Consul health checks
+ uint32_t ConsulDeregisterAfterSeconds = 30; // Seconds before Consul deregisters an unhealthy service
+ uint16_t HubBasePortNumber = 21000;
+ int HubInstanceLimit = 1000;
+ bool HubUseJobObject = true;
+ std::string HubInstanceHttpClass = "asio";
+ uint32_t HubInstanceHttpThreadCount = 0; // Automatic
+ int HubInstanceCoreLimit = 0; // Automatic
+ std::filesystem::path HubInstanceConfigPath; // Path to Lua config file
+ std::string HydrationTargetSpecification; // hydration/dehydration target specification
+ std::filesystem::path HydrationTargetConfigPath; // path to JSON config file (mutually exclusive with HydrationTargetSpecification)
+ ZenHubWatchdogConfig WatchdogConfig;
+ uint64_t HubProvisionDiskLimitBytes = 0;
+ uint32_t HubProvisionDiskLimitPercent = 0;
+ uint64_t HubProvisionMemoryLimitBytes = 0;
+ uint32_t HubProvisionMemoryLimitPercent = 0;
};
class Hub;
@@ -87,14 +112,18 @@ public:
void SetContentRoot(std::filesystem::path Root) { m_ContentRoot = Root; }
private:
- void OnProvisioned(std::string_view HubInstanceId, std::string_view ModuleId, const HubProvisionedInstanceInfo& Info);
- void OnDeprovisioned(std::string_view HubInstanceId, std::string_view ModuleId, const HubProvisionedInstanceInfo& Info);
+ void OnModuleStateChanged(std::string_view HubInstanceId,
+ std::string_view ModuleId,
+ const HubProvisionedInstanceInfo& Info,
+ HubInstanceState PreviousState,
+ HubInstanceState NewState);
std::filesystem::path m_DataRoot;
std::filesystem::path m_ContentRoot;
bool m_DebugOptionForcedCrash = false;
- std::unique_ptr<Hub> m_Hub;
+ std::unique_ptr<HttpProxyHandler> m_Proxy;
+ std::unique_ptr<Hub> m_Hub;
std::unique_ptr<HttpHubService> m_HubService;
std::unique_ptr<HttpApiService> m_ApiService;
@@ -102,6 +131,10 @@ private:
std::unique_ptr<consul::ConsulClient> m_ConsulClient;
std::unique_ptr<consul::ServiceRegistration> m_ConsulRegistration;
+ uint32_t m_ConsulHealthIntervalSeconds = 10;
+ uint32_t m_ConsulDeregisterAfterSeconds = 30;
+
+ static ResourceMetrics ResolveLimits(const ZenHubServerConfig& ServerConfig);
void InitializeState(const ZenHubServerConfig& ServerConfig);
void InitializeServices(const ZenHubServerConfig& ServerConfig);
diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp
index bf328c499..00b7a67d7 100644
--- a/src/zenserver/main.cpp
+++ b/src/zenserver/main.cpp
@@ -123,10 +123,6 @@ AppMain(int argc, char* argv[])
signal(SIGINT, utils::SignalCallbackHandler);
signal(SIGTERM, utils::SignalCallbackHandler);
-#if ZEN_PLATFORM_LINUX
- IgnoreChildSignals();
-#endif
-
try
{
typename Main::Config ServerOptions;
@@ -253,7 +249,9 @@ test_main(int argc, char** argv)
zen::MaximizeOpenFileCount();
- return ZEN_RUN_TESTS(argc, argv);
+ zen::testing::TestRunner Runner;
+ Runner.ApplyCommandLine(argc, argv);
+ return Runner.Run();
}
#endif
@@ -271,26 +269,6 @@ main(int argc, char* argv[])
using namespace zen;
using namespace std::literals;
- // note: doctest has locally (in thirdparty) been fixed to not cause shutdown
- // crashes due to TLS destructors
- //
- // mimalloc on the other hand might still be causing issues, in which case
- // we should work out either how to eliminate the mimalloc dependency or how
- // to configure it in a way that doesn't cause shutdown issues
-
-#if 0
- auto _ = zen::MakeGuard([] {
- // Allow some time for worker threads to unravel, in an effort
- // to prevent shutdown races in TLS object destruction, mainly due to
- // threads which we don't directly control (Windows thread pool) and
- // therefore can't join.
- //
- // This isn't a great solution, but for now it seems to help reduce
- // shutdown crashes observed in some situations.
- WaitForThreads(1000);
- });
-#endif
-
enum
{
kHub,
diff --git a/src/zenserver/proxy/httpproxystats.cpp b/src/zenserver/proxy/httpproxystats.cpp
index 6aa3e5c9b..337be2417 100644
--- a/src/zenserver/proxy/httpproxystats.cpp
+++ b/src/zenserver/proxy/httpproxystats.cpp
@@ -140,6 +140,12 @@ HttpProxyStatsService::HandleRecordStatus(HttpServerRequest& Request)
Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
+void
+HttpProxyStatsService::HandleStatsRequest(HttpServerRequest& Request)
+{
+ Request.WriteResponse(HttpResponseCode::OK, CollectStats());
+}
+
CbObject
HttpProxyStatsService::CollectStats()
{
@@ -225,10 +231,4 @@ HttpProxyStatsService::CollectStats()
return Cbo.Save();
}
-void
-HttpProxyStatsService::HandleStatsRequest(HttpServerRequest& Request)
-{
- Request.WriteResponse(HttpResponseCode::OK, CollectStats());
-}
-
} // namespace zen
diff --git a/src/zenserver/proxy/zenproxyserver.cpp b/src/zenserver/proxy/zenproxyserver.cpp
index cf84c159a..7e59a7b7e 100644
--- a/src/zenserver/proxy/zenproxyserver.cpp
+++ b/src/zenserver/proxy/zenproxyserver.cpp
@@ -324,7 +324,7 @@ ZenProxyServer::Initialize(const ZenProxyServerConfig& ServerConfig, ZenServerSt
m_ApiService = std::make_unique<HttpApiService>(*m_Http);
m_Http->RegisterService(*m_ApiService);
- m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatusService);
+ m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatsService, m_StatusService);
m_Http->RegisterService(*m_FrontendService);
std::string DefaultRecordDir = (m_DataRoot / "recordings").string();
diff --git a/src/zenserver/sessions/httpsessions.cpp b/src/zenserver/sessions/httpsessions.cpp
index 6cf12bea4..c21ae6a5c 100644
--- a/src/zenserver/sessions/httpsessions.cpp
+++ b/src/zenserver/sessions/httpsessions.cpp
@@ -3,7 +3,6 @@
#include "httpsessions.h"
#include <zencore/compactbinarybuilder.h>
-#include <zencore/compactbinaryvalidation.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zencore/trace.h>
@@ -12,17 +11,22 @@
namespace zen {
using namespace std::literals;
-HttpSessionsService::HttpSessionsService(HttpStatusService& StatusService, HttpStatsService& StatsService, SessionsService& Sessions)
+HttpSessionsService::HttpSessionsService(HttpStatusService& StatusService,
+ HttpStatsService& StatsService,
+ SessionsService& Sessions,
+ asio::io_context& IoContext)
: m_Log(logging::Get("sessions"))
, m_StatusService(StatusService)
, m_StatsService(StatsService)
, m_Sessions(Sessions)
+, m_PushTimer(IoContext)
{
Initialize();
}
HttpSessionsService::~HttpSessionsService()
{
+ m_PushTimer.cancel();
m_StatsService.UnregisterHandler("sessions", *this);
m_StatusService.UnregisterHandler("sessions", *this);
}
@@ -45,6 +49,21 @@ HttpSessionsService::HandleRequest(HttpServerRequest& Request)
}
}
+void
+HttpSessionsService::HandleStatusRequest(HttpServerRequest& Request)
+{
+ ZEN_TRACE_CPU("HttpSessionsService::Status");
+ CbObjectWriter Cbo;
+ Cbo << "ok" << true;
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+void
+HttpSessionsService::HandleStatsRequest(HttpServerRequest& HttpReq)
+{
+ HttpReq.WriteResponse(HttpResponseCode::OK, CollectStats());
+}
+
CbObject
HttpSessionsService::CollectStats()
{
@@ -68,19 +87,10 @@ HttpSessionsService::CollectStats()
return Cbo.Save();
}
-void
-HttpSessionsService::HandleStatsRequest(HttpServerRequest& HttpReq)
+uint64_t
+HttpSessionsService::GetActivityCounter()
{
- HttpReq.WriteResponse(HttpResponseCode::OK, CollectStats());
-}
-
-void
-HttpSessionsService::HandleStatusRequest(HttpServerRequest& Request)
-{
- ZEN_TRACE_CPU("HttpSessionsService::Status");
- CbObjectWriter Cbo;
- Cbo << "ok" << true;
- Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+ return m_HttpRequests.Count();
}
void
@@ -107,12 +117,24 @@ HttpSessionsService::Initialize()
HttpVerb::kGet | HttpVerb::kPost | HttpVerb::kPut | HttpVerb::kDelete);
m_Router.RegisterRoute(
+ "{session_id}/log",
+ [this](HttpRouterRequest& Req) { SessionLogRequest(Req); },
+ HttpVerb::kGet | HttpVerb::kPost);
+
+ m_Router.RegisterRoute(
"",
[this](HttpRouterRequest& Req) { ListSessionsRequest(Req); },
HttpVerb::kGet);
+ m_Router.RegisterRoute(
+ "ws",
+ [this](HttpRouterRequest& Req) { Req.ServerRequest().WriteResponse(HttpResponseCode::OK); },
+ HttpVerb::kGet);
+
m_StatsService.RegisterHandler("sessions", *this);
m_StatusService.RegisterHandler("sessions", *this);
+
+ EnqueuePushTimer();
}
static void
@@ -123,22 +145,53 @@ WriteSessionInfo(CbWriter& Writer, const SessionsService::SessionInfo& Info)
{
Writer << "appname" << Info.AppName;
}
+ if (!Info.Mode.empty())
+ {
+ Writer << "mode" << Info.Mode;
+ }
if (Info.JobId != Oid::Zero)
{
Writer << "jobid" << Info.JobId;
}
Writer << "created_at" << Info.CreatedAt;
Writer << "updated_at" << Info.UpdatedAt;
+ if (Info.EndedAt.GetTicks() != 0)
+ {
+ Writer << "ended_at" << Info.EndedAt;
+ }
if (Info.Metadata.GetSize() > 0)
{
- Writer.BeginObject("metadata");
- for (const CbField& Field : Info.Metadata)
- {
- Writer.AddField(Field);
- }
- Writer.EndObject();
+ Writer.AddObject("metadata"sv, Info.Metadata);
+ }
+}
+
+CbObject
+HttpSessionsService::BuildSessionListResponse()
+{
+ std::vector<Ref<SessionsService::Session>> Active = m_Sessions.GetSessions();
+ std::vector<Ref<SessionsService::Session>> Ended = m_Sessions.GetEndedSessions();
+
+ CbObjectWriter Response;
+ if (m_SelfSessionId != Oid::Zero)
+ {
+ Response << "self_id" << m_SelfSessionId;
}
+ Response.BeginArray("sessions");
+ for (const Ref<SessionsService::Session>& Session : Active)
+ {
+ Response.BeginObject();
+ WriteSessionInfo(Response, Session->Info());
+ Response.EndObject();
+ }
+ for (const Ref<SessionsService::Session>& Session : Ended)
+ {
+ Response.BeginObject();
+ WriteSessionInfo(Response, Session->Info());
+ Response.EndObject();
+ }
+ Response.EndArray();
+ return Response.Save();
}
void
@@ -149,16 +202,35 @@ HttpSessionsService::ListSessionsRequest(HttpRouterRequest& Req)
m_SessionsStats.SessionListCount++;
m_SessionsStats.RequestCount++;
- std::vector<Ref<SessionsService::Session>> Sessions = m_Sessions.GetSessions();
+ HttpServerRequest::QueryParams Params = ServerRequest.GetQueryParams();
+ std::string_view Status = Params.GetValue("status"sv);
+
+ std::vector<Ref<SessionsService::Session>> Sessions;
+ if (Status == "ended"sv)
+ {
+ Sessions = m_Sessions.GetEndedSessions();
+ }
+ else if (Status == "all"sv)
+ {
+ Sessions = m_Sessions.GetSessions();
+ std::vector<Ref<SessionsService::Session>> Ended = m_Sessions.GetEndedSessions();
+ Sessions.insert(Sessions.end(), Ended.begin(), Ended.end());
+ }
+ else
+ {
+ Sessions = m_Sessions.GetSessions();
+ }
CbObjectWriter Response;
+ if (m_SelfSessionId != Oid::Zero)
+ {
+ Response << "self_id" << m_SelfSessionId;
+ }
Response.BeginArray("sessions");
for (const Ref<SessionsService::Session>& Session : Sessions)
{
Response.BeginObject();
- {
- WriteSessionInfo(Response, Session->Info());
- }
+ WriteSessionInfo(Response, Session->Info());
Response.EndObject();
}
Response.EndArray();
@@ -187,30 +259,17 @@ HttpSessionsService::SessionRequest(HttpRouterRequest& Req)
case HttpVerb::kPost:
case HttpVerb::kPut:
{
- IoBuffer Payload = ServerRequest.ReadPayload();
- CbObject RequestObject;
-
- if (Payload.GetSize() > 0)
- {
- if (CbValidateError ValidationResult = ValidateCompactBinary(Payload.GetView(), CbValidateMode::All);
- ValidationResult != CbValidateError::None)
- {
- m_SessionsStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid payload: {}", zen::ToString(ValidationResult)));
- }
- RequestObject = LoadCompactBinaryObject(Payload);
- }
+ CbObject RequestObject = ServerRequest.ReadPayloadObject();
if (ServerRequest.RequestVerb() == HttpVerb::kPost)
{
std::string AppName(RequestObject["appname"sv].AsString());
+ std::string Mode(RequestObject["mode"sv].AsString());
Oid JobId = RequestObject["jobid"sv].AsObjectId();
CbObjectView MetadataView = RequestObject["metadata"sv].AsObjectView();
m_SessionsStats.SessionWriteCount++;
- if (m_Sessions.RegisterSession(SessionId, std::move(AppName), JobId, MetadataView))
+ if (m_Sessions.RegisterSession(SessionId, std::move(AppName), std::move(Mode), JobId, MetadataView))
{
return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", SessionId));
}
@@ -265,4 +324,256 @@ HttpSessionsService::SessionRequest(HttpRouterRequest& Req)
}
}
+//////////////////////////////////////////////////////////////////////////
+//
+// Session log
+//
+
+static void
+WriteLogEntry(CbWriter& Writer, const SessionsService::LogEntry& Entry)
+{
+ Writer << "timestamp" << Entry.Timestamp;
+ if (!Entry.Level.empty())
+ {
+ Writer << "level" << Entry.Level;
+ }
+ if (!Entry.Message.empty())
+ {
+ Writer << "message" << Entry.Message;
+ }
+ if (Entry.Data.GetSize() > 0)
+ {
+ Writer.AddObject("data"sv, Entry.Data);
+ }
+}
+
+void
+HttpSessionsService::SessionLogRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+
+ const Oid SessionId = Oid::TryFromHexString(Req.GetCapture(1));
+ if (SessionId == Oid::Zero)
+ {
+ m_SessionsStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid session id '{}'", Req.GetCapture(1)));
+ }
+
+ m_SessionsStats.RequestCount++;
+
+ Ref<SessionsService::Session> Session = m_Sessions.GetSession(SessionId);
+ if (!Session)
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound,
+ HttpContentType::kText,
+ fmt::format("Session '{}' not found", SessionId));
+ }
+
+ if (ServerRequest.RequestVerb() == HttpVerb::kPost)
+ {
+ m_SessionsStats.SessionWriteCount++;
+
+ if (ServerRequest.RequestContentType() == HttpContentType::kText)
+ {
+ // Raw text — split by newlines, one entry per line
+ IoBuffer Payload = ServerRequest.ReadPayload();
+ std::string_view Text(reinterpret_cast<const char*>(Payload.GetData()), Payload.GetSize());
+ const DateTime Now = DateTime::Now();
+
+ size_t Pos = 0;
+ while (Pos < Text.size())
+ {
+ size_t End = Text.find('\n', Pos);
+ if (End == std::string_view::npos)
+ {
+ End = Text.size();
+ }
+
+ std::string_view Line = Text.substr(Pos, End - Pos);
+ // Strip trailing \r
+ if (!Line.empty() && Line.back() == '\r')
+ {
+ Line.remove_suffix(1);
+ }
+
+ if (!Line.empty())
+ {
+ Session->AppendLog(SessionsService::LogEntry{
+ .Timestamp = Now,
+ .Message = std::string(Line),
+ });
+ }
+
+ Pos = End + 1;
+ }
+ }
+ else
+ {
+ // Structured log (JSON or CbObject)
+ // Accepts a single record or an "entries" array of records
+ CbObject RequestObject = ServerRequest.ReadPayloadObject();
+ const DateTime Now = DateTime::Now();
+
+ auto AppendFromObject = [&](CbObjectView Obj) {
+ std::string Level(Obj["level"sv].AsString());
+ std::string Message(Obj["message"sv].AsString());
+ CbObjectView DataView = Obj["data"sv].AsObjectView();
+
+ Session->AppendLog(SessionsService::LogEntry{
+ .Timestamp = Now,
+ .Level = std::move(Level),
+ .Message = std::move(Message),
+ .Data = CbObject::Clone(DataView),
+ });
+ };
+
+ CbFieldView EntriesField = RequestObject["entries"sv];
+ if (EntriesField.IsArray())
+ {
+ for (CbFieldView Entry : EntriesField)
+ {
+ AppendFromObject(Entry.AsObjectView());
+ }
+ }
+ else
+ {
+ AppendFromObject(RequestObject);
+ }
+ }
+
+ return ServerRequest.WriteResponse(HttpResponseCode::OK);
+ }
+ else
+ {
+ // GET - return log entries
+ m_SessionsStats.SessionReadCount++;
+
+ HttpServerRequest::QueryParams Params = ServerRequest.GetQueryParams();
+
+ // cursor-based retrieval: client passes the cursor from the previous response
+ // and receives only entries appended since then.
+ std::string_view CursorStr = Params.GetValue("cursor"sv);
+ if (!CursorStr.empty())
+ {
+ uint64_t AfterCursor = std::strtoull(std::string(CursorStr).c_str(), nullptr, 10);
+
+ SessionsService::Session::CursorResult Result = Session->GetLogEntriesAfter(AfterCursor);
+
+ CbObjectWriter Response;
+ Response << "cursor" << Result.Cursor;
+ Response << "count" << Result.Count;
+ Response.BeginArray("entries");
+ for (const SessionsService::LogEntry& Entry : Result.Entries)
+ {
+ Response.BeginObject();
+ WriteLogEntry(Response, Entry);
+ Response.EndObject();
+ }
+ Response.EndArray();
+
+ return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save());
+ }
+
+ // Legacy offset/limit retrieval
+ uint32_t Limit = 0;
+ uint32_t Offset = 0;
+
+ if (std::string_view LimitStr = Params.GetValue("limit"sv); !LimitStr.empty())
+ {
+ Limit = uint32_t(std::strtoul(std::string(LimitStr).c_str(), nullptr, 10));
+ }
+ if (std::string_view OffsetStr = Params.GetValue("offset"sv); !OffsetStr.empty())
+ {
+ Offset = uint32_t(std::strtoul(std::string(OffsetStr).c_str(), nullptr, 10));
+ }
+
+ std::vector<SessionsService::LogEntry> Entries = Session->GetLogEntries(Limit, Offset);
+
+ CbObjectWriter Response;
+ Response << "total" << Session->GetLogCount();
+ Response.BeginArray("entries");
+ for (const SessionsService::LogEntry& Entry : Entries)
+ {
+ Response.BeginObject();
+ WriteLogEntry(Response, Entry);
+ Response.EndObject();
+ }
+ Response.EndArray();
+
+ return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// WebSocket push
+//
+
+void
+HttpSessionsService::OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri)
+{
+ ZEN_UNUSED(RelativeUri);
+ ZEN_INFO("Sessions WebSocket client connected");
+ m_WsConnectionsLock.WithExclusiveLock([&] { m_WsConnections.push_back(std::move(Connection)); });
+}
+
+void
+HttpSessionsService::OnWebSocketMessage(WebSocketConnection& /*Conn*/, const WebSocketMessage& /*Msg*/)
+{
+ // No client-to-server messages expected
+}
+
+void
+HttpSessionsService::OnWebSocketClose(WebSocketConnection& Conn, [[maybe_unused]] uint16_t Code, [[maybe_unused]] std::string_view Reason)
+{
+ ZEN_INFO("Sessions WebSocket client disconnected (code {})", Code);
+ m_WsConnectionsLock.WithExclusiveLock([&] {
+ auto It = std::remove_if(m_WsConnections.begin(), m_WsConnections.end(), [&Conn](const Ref<WebSocketConnection>& C) {
+ return C.Get() == &Conn;
+ });
+ m_WsConnections.erase(It, m_WsConnections.end());
+ });
+}
+
+void
+HttpSessionsService::BroadcastSessions()
+{
+ std::vector<Ref<WebSocketConnection>> Connections;
+ m_WsConnectionsLock.WithSharedLock([&] { Connections = m_WsConnections; });
+
+ if (Connections.empty())
+ {
+ return;
+ }
+
+ ExtendableStringBuilder<4096> JsonBuilder;
+ BuildSessionListResponse().ToJson(JsonBuilder);
+ std::string_view Json = JsonBuilder.ToView();
+
+ for (const Ref<WebSocketConnection>& Conn : Connections)
+ {
+ if (Conn->IsOpen())
+ {
+ Conn->SendText(Json);
+ }
+ }
+}
+
+void
+HttpSessionsService::EnqueuePushTimer()
+{
+ m_PushTimer.expires_after(std::chrono::seconds(2));
+ m_PushTimer.async_wait([this](const asio::error_code& Ec) {
+ if (Ec)
+ {
+ return;
+ }
+
+ BroadcastSessions();
+ EnqueuePushTimer();
+ });
+}
+
} // namespace zen
diff --git a/src/zenserver/sessions/httpsessions.h b/src/zenserver/sessions/httpsessions.h
index e07f3b59b..6ebe61c8d 100644
--- a/src/zenserver/sessions/httpsessions.h
+++ b/src/zenserver/sessions/httpsessions.h
@@ -5,24 +5,41 @@
#include <zenhttp/httpserver.h>
#include <zenhttp/httpstats.h>
#include <zenhttp/httpstatus.h>
+#include <zenhttp/websocket.h>
#include <zentelemetry/stats.h>
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <asio/io_context.hpp>
+#include <asio/steady_timer.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
namespace zen {
class SessionsService;
-class HttpSessionsService final : public HttpService, public IHttpStatusProvider, public IHttpStatsProvider
+class HttpSessionsService final : public HttpService, public IHttpStatusProvider, public IHttpStatsProvider, public IWebSocketHandler
{
public:
- HttpSessionsService(HttpStatusService& StatusService, HttpStatsService& StatsService, SessionsService& Sessions);
+ HttpSessionsService(HttpStatusService& StatusService,
+ HttpStatsService& StatsService,
+ SessionsService& Sessions,
+ asio::io_context& IoContext);
virtual ~HttpSessionsService();
virtual const char* BaseUri() const override;
virtual void HandleRequest(HttpServerRequest& Request) override;
- virtual CbObject CollectStats() override;
- virtual void HandleStatsRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
+
+ void SetSelfSessionId(const Oid& Id) { m_SelfSessionId = Id; }
+
+ // IWebSocketHandler
+ void OnWebSocketOpen(Ref<WebSocketConnection> Connection, std::string_view RelativeUri) override;
+ void OnWebSocketMessage(WebSocketConnection& Conn, const WebSocketMessage& Msg) override;
+ void OnWebSocketClose(WebSocketConnection& Conn, uint16_t Code, std::string_view Reason) override;
private:
struct SessionsStats
@@ -43,6 +60,7 @@ private:
void ListSessionsRequest(HttpRouterRequest& Req);
void SessionRequest(HttpRouterRequest& Req);
+ void SessionLogRequest(HttpRouterRequest& Req);
HttpStatusService& m_StatusService;
HttpStatsService& m_StatsService;
@@ -50,6 +68,18 @@ private:
SessionsService& m_Sessions;
SessionsStats m_SessionsStats;
metrics::OperationTiming m_HttpRequests;
+
+ // WebSocket push
+ RwLock m_WsConnectionsLock;
+ std::vector<Ref<WebSocketConnection>> m_WsConnections;
+ asio::steady_timer m_PushTimer;
+
+ void BroadcastSessions();
+ void EnqueuePushTimer();
+
+ Oid m_SelfSessionId = Oid::Zero;
+
+ CbObject BuildSessionListResponse();
};
} // namespace zen
diff --git a/src/zenserver/sessions/inprocsessionlogsink.cpp b/src/zenserver/sessions/inprocsessionlogsink.cpp
new file mode 100644
index 000000000..9982859b6
--- /dev/null
+++ b/src/zenserver/sessions/inprocsessionlogsink.cpp
@@ -0,0 +1,39 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "inprocsessionlogsink.h"
+
+#include <zencore/logbase.h>
+
+namespace zen {
+
+/// Bias in seconds from DateTime epoch (year 1) to Unix epoch (1970).
+static constexpr uint64_t UnixEpochBiasSeconds = uint64_t(double(1970 - 1) * 365.2425) * 86400;
+
+static DateTime
+TimePointToDateTime(logging::LogClock::time_point Time)
+{
+ auto Duration = Time.time_since_epoch();
+ auto Seconds = std::chrono::duration_cast<std::chrono::seconds>(Duration);
+ uint64_t Ticks = (UnixEpochBiasSeconds + static_cast<uint64_t>(Seconds.count())) * TimeSpan::TicksPerSecond;
+ return DateTime{Ticks};
+}
+
+void
+InProcSessionLogSink::Log(const logging::LogMessage& Msg)
+{
+ Ref<SessionsService::Session> Session = m_Service.GetSession(m_SessionId);
+ if (!Session)
+ {
+ return;
+ }
+
+ SessionsService::LogEntry Entry{
+ .Timestamp = TimePointToDateTime(Msg.GetTime()),
+ .Level = std::string(logging::ToStringView(Msg.GetLevel())),
+ .Message = std::string(Msg.GetPayload()),
+ };
+
+ Session->AppendLog(std::move(Entry));
+}
+
+} // namespace zen
diff --git a/src/zenserver/sessions/inprocsessionlogsink.h b/src/zenserver/sessions/inprocsessionlogsink.h
new file mode 100644
index 000000000..15f9b5ec3
--- /dev/null
+++ b/src/zenserver/sessions/inprocsessionlogsink.h
@@ -0,0 +1,30 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "sessions.h"
+
+#include <zencore/logging/sink.h>
+#include <zencore/session.h>
+
+#include <mutex>
+
+namespace zen {
+
+/// Log sink that forwards log messages to the server's own session
+/// in the SessionsService, making them visible in the sessions browser UI.
+class InProcSessionLogSink : public logging::Sink
+{
+public:
+ explicit InProcSessionLogSink(SessionsService& Service) : m_Service(Service), m_SessionId(GetSessionId()) {}
+
+ void Log(const logging::LogMessage& Msg) override;
+ void Flush() override {}
+ void SetFormatter(std::unique_ptr<logging::Formatter> /*InFormatter*/) override {}
+
+private:
+ SessionsService& m_Service;
+ Oid m_SessionId;
+};
+
+} // namespace zen
diff --git a/src/zenserver/sessions/sessions.cpp b/src/zenserver/sessions/sessions.cpp
index d919db6e9..1212ba5d8 100644
--- a/src/zenserver/sessions/sessions.cpp
+++ b/src/zenserver/sessions/sessions.cpp
@@ -46,6 +46,78 @@ SessionsService::Session::Session(const SessionInfo& Info) : m_Info(Info)
}
SessionsService::Session::~Session() = default;
+void
+SessionsService::Session::AppendLog(LogEntry Entry)
+{
+ RwLock::ExclusiveLockScope Lock(m_LogLock);
+ m_LogEntries.push_back(std::move(Entry));
+ ++m_TotalAppended;
+ while (m_LogEntries.size() > MaxLogEntries)
+ {
+ m_LogEntries.pop_front();
+ }
+}
+
+std::vector<SessionsService::LogEntry>
+SessionsService::Session::GetLogEntries(uint32_t Limit, uint32_t Offset) const
+{
+ RwLock::SharedLockScope Lock(m_LogLock);
+
+ const uint32_t Total = uint32_t(m_LogEntries.size());
+ if (Offset >= Total)
+ {
+ return {};
+ }
+
+ const uint32_t Available = Total - Offset;
+ const uint32_t Count = (Limit > 0) ? std::min(Limit, Available) : Available;
+
+ std::vector<LogEntry> Result;
+ Result.reserve(Count);
+ for (uint32_t i = Offset; i < Offset + Count; i++)
+ {
+ Result.push_back(m_LogEntries[i]);
+ }
+ return Result;
+}
+
+uint64_t
+SessionsService::Session::GetLogCount() const
+{
+ RwLock::SharedLockScope Lock(m_LogLock);
+ return m_LogEntries.size();
+}
+
+SessionsService::Session::CursorResult
+SessionsService::Session::GetLogEntriesAfter(uint64_t AfterCursor) const
+{
+ RwLock::SharedLockScope Lock(m_LogLock);
+
+ const uint64_t DequeSize = m_LogEntries.size();
+
+ // Cursor 0 means "give me everything currently in the deque".
+ // Otherwise, compute how many new entries were appended since the cursor.
+ uint64_t NewCount = (AfterCursor == 0) ? DequeSize : (m_TotalAppended > AfterCursor ? m_TotalAppended - AfterCursor : 0);
+
+ // Clamp to what's actually available in the deque (entries may have been evicted).
+ NewCount = std::min(NewCount, DequeSize);
+
+ std::vector<LogEntry> Result;
+ Result.reserve(NewCount);
+
+ const uint64_t StartIndex = DequeSize - NewCount;
+ for (uint64_t i = StartIndex; i < DequeSize; i++)
+ {
+ Result.push_back(m_LogEntries[i]);
+ }
+
+ return CursorResult{
+ .Entries = std::move(Result),
+ .Cursor = m_TotalAppended,
+ .Count = DequeSize,
+ };
+}
+
//////////////////////////////////////////////////////////////////////////
SessionsService::SessionsService() : m_Log(logging::Get("sessions"))
@@ -55,25 +127,31 @@ SessionsService::SessionsService() : m_Log(logging::Get("sessions"))
SessionsService::~SessionsService() = default;
bool
-SessionsService::RegisterSession(const Oid& SessionId, std::string AppName, const Oid& JobId, CbObjectView Metadata)
+SessionsService::RegisterSession(const Oid& SessionId, std::string AppName, std::string Mode, const Oid& JobId, CbObjectView Metadata)
{
- RwLock::ExclusiveLockScope Lock(m_Lock);
-
- if (m_Sessions.contains(SessionId))
+ // Log outside the lock scope — InProcSessionLogSink calls back into
+ // GetSession() which acquires m_Lock shared, so logging while holding
+ // m_Lock exclusively would deadlock.
{
- return false;
+ RwLock::ExclusiveLockScope Lock(m_Lock);
+
+ if (m_Sessions.contains(SessionId))
+ {
+ return false;
+ }
+
+ const DateTime Now = DateTime::Now();
+ m_Sessions.emplace(SessionId,
+ Ref(new Session(SessionInfo{.Id = SessionId,
+ .AppName = AppName,
+ .Mode = Mode,
+ .JobId = JobId,
+ .Metadata = CbObject::Clone(Metadata),
+ .CreatedAt = Now,
+ .UpdatedAt = Now})));
}
- ZEN_INFO("Session {} registered (AppName: {}, JobId: {})", SessionId, AppName, JobId);
-
- const DateTime Now = DateTime::Now();
- m_Sessions.emplace(SessionId,
- Ref(new Session(SessionInfo{.Id = SessionId,
- .AppName = std::move(AppName),
- .JobId = JobId,
- .Metadata = CbObject::Clone(Metadata),
- .CreatedAt = Now,
- .UpdatedAt = Now})));
+ ZEN_INFO("Session {} registered (AppName: {}, Mode: {}, JobId: {})", SessionId, AppName, Mode, JobId);
return true;
}
@@ -126,20 +204,39 @@ SessionsService::GetSessions() const
bool
SessionsService::RemoveSession(const Oid& SessionId)
{
- RwLock::ExclusiveLockScope Lock(m_Lock);
+ std::string RemovedAppName;
+ Oid RemovedJobId;
- auto It = m_Sessions.find(SessionId);
- if (It == m_Sessions.end())
{
- return false;
- }
+ RwLock::ExclusiveLockScope Lock(m_Lock);
+
+ auto It = m_Sessions.find(SessionId);
+ if (It == m_Sessions.end())
+ {
+ return false;
+ }
+
+ RemovedAppName = It.value()->Info().AppName;
+ RemovedJobId = It.value()->Info().JobId;
+
+ Ref<Session> Ended = It.value();
+ Ended->SetEndedAt(DateTime::Now());
+ m_EndedSessions.push_back(std::move(Ended));
- ZEN_INFO("Session {} removed (AppName: {}, JobId: {})", SessionId, It.value()->Info().AppName, It.value()->Info().JobId);
+ m_Sessions.erase(It);
+ }
- m_Sessions.erase(It);
+ ZEN_INFO("Session {} removed (AppName: {}, JobId: {})", SessionId, RemovedAppName, RemovedJobId);
return true;
}
+std::vector<Ref<SessionsService::Session>>
+SessionsService::GetEndedSessions() const
+{
+ RwLock::SharedLockScope Lock(m_Lock);
+ return m_EndedSessions;
+}
+
uint64_t
SessionsService::GetSessionCount() const
{
diff --git a/src/zenserver/sessions/sessions.h b/src/zenserver/sessions/sessions.h
index db9704430..8f07bfc31 100644
--- a/src/zenserver/sessions/sessions.h
+++ b/src/zenserver/sessions/sessions.h
@@ -11,6 +11,7 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <tsl/robin_map.h>
ZEN_THIRD_PARTY_INCLUDES_END
+#include <deque>
#include <optional>
#include <string>
#include <vector>
@@ -33,10 +34,20 @@ public:
{
Oid Id;
std::string AppName;
+ std::string Mode;
Oid JobId;
CbObject Metadata;
DateTime CreatedAt;
DateTime UpdatedAt;
+ DateTime EndedAt{0};
+ };
+
+ struct LogEntry
+ {
+ DateTime Timestamp;
+ std::string Level;
+ std::string Message;
+ CbObject Data;
};
class Session : public TRefCounted<Session>
@@ -51,23 +62,44 @@ public:
const SessionInfo& Info() const { return m_Info; }
void UpdateMetadata(CbObjectView Metadata)
{
- // Should this be additive rather than replacing the whole thing? We'll see.
m_Info.Metadata = CbObject::Clone(Metadata);
m_Info.UpdatedAt = DateTime::Now();
}
+ void SetEndedAt(DateTime When) { m_Info.EndedAt = When; }
+
+ void AppendLog(LogEntry Entry);
+ std::vector<LogEntry> GetLogEntries(uint32_t Limit = 0, uint32_t Offset = 0) const;
+ uint64_t GetLogCount() const;
+
+ /// Returns entries appended after the given cursor and the new cursor value.
+ /// A cursor of 0 returns all entries currently in the deque.
+ struct CursorResult
+ {
+ std::vector<LogEntry> Entries;
+ uint64_t Cursor; // new cursor for next poll
+ uint64_t Count; // current deque size
+ };
+ CursorResult GetLogEntriesAfter(uint64_t AfterCursor) const;
+
private:
- SessionInfo m_Info;
- Ref<SessionLog> m_Log;
+ SessionInfo m_Info;
+ Ref<SessionLog> m_Log;
+ mutable RwLock m_LogLock;
+ std::deque<LogEntry> m_LogEntries;
+ uint64_t m_TotalAppended = 0; // monotonically increasing counter
+
+ static constexpr uint32_t MaxLogEntries = 10000;
};
SessionsService();
~SessionsService();
- bool RegisterSession(const Oid& SessionId, std::string AppName, const Oid& JobId, CbObjectView Metadata);
- bool UpdateSession(const Oid& SessionId, CbObjectView Metadata);
- Ref<Session> GetSession(const Oid& SessionId) const;
+ bool RegisterSession(const Oid& SessionId, std::string AppName, std::string Mode, const Oid& JobId, CbObjectView Metadata);
+ bool UpdateSession(const Oid& SessionId, CbObjectView Metadata);
+ Ref<Session> GetSession(const Oid& SessionId) const;
std::vector<Ref<Session>> GetSessions() const;
+ std::vector<Ref<Session>> GetEndedSessions() const;
bool RemoveSession(const Oid& SessionId);
uint64_t GetSessionCount() const;
@@ -77,6 +109,7 @@ private:
LoggerRef m_Log;
mutable RwLock m_Lock;
tsl::robin_map<Oid, Ref<Session>, Oid::Hasher> m_Sessions;
+ std::vector<Ref<Session>> m_EndedSessions;
std::unique_ptr<SessionLogStore> m_SessionLogs;
};
diff --git a/src/zenserver/stats/statsreporter.cpp b/src/zenserver/stats/statsreporter.cpp
index a1926eba4..ff055cf18 100644
--- a/src/zenserver/stats/statsreporter.cpp
+++ b/src/zenserver/stats/statsreporter.cpp
@@ -40,6 +40,10 @@ StatsReporter::Shutdown()
void
StatsReporter::AddProvider(StatsProvider* Provider)
{
+ if (!Provider)
+ {
+ return;
+ }
RwLock::ExclusiveLockScope _(m_Lock);
m_Providers.push_back(Provider);
}
diff --git a/src/zenserver/storage/admin/admin.cpp b/src/zenserver/storage/admin/admin.cpp
index 6e78a6179..f1c2daea4 100644
--- a/src/zenserver/storage/admin/admin.cpp
+++ b/src/zenserver/storage/admin/admin.cpp
@@ -791,6 +791,139 @@ HttpAdminService::HttpAdminService(GcScheduler& Scheduler,
},
HttpVerb::kPost);
m_Router.RegisterRoute(
+ "storage",
+ [this](HttpRouterRequest& Req) {
+ CbObjectWriter Obj;
+
+ // Collect known storage directories
+ struct StorageDir
+ {
+ std::string_view Name;
+ std::filesystem::path Path;
+ };
+
+ std::vector<StorageDir> Dirs;
+ const std::filesystem::path& DataDir = m_ServerOptions.DataDir;
+ Dirs.push_back({"cache"sv, DataDir / "cache"});
+ Dirs.push_back({"cas"sv, DataDir / "cas"});
+ Dirs.push_back({"projects"sv, DataDir / "projects"});
+ Dirs.push_back({"builds"sv, DataDir / "builds"});
+ Dirs.push_back({"builds_cas"sv, DataDir / "builds_cas"});
+ Dirs.push_back({"obj"sv, DataDir / "obj"});
+
+ // Group directories by volume (identified by total capacity)
+ struct VolumeInfo
+ {
+ DiskSpace Space;
+ std::vector<const StorageDir*> Directories;
+ };
+
+ // Use canonical path to identify volumes. Directories on the same volume
+ // will report the same total capacity from DiskSpaceInfo.
+ std::vector<VolumeInfo> Volumes;
+ auto FindOrAddVolume = [&](DiskSpace Space) -> VolumeInfo& {
+ for (VolumeInfo& V : Volumes)
+ {
+ if (V.Space.Total == Space.Total && V.Space.Free == Space.Free)
+ {
+ return V;
+ }
+ }
+ Volumes.push_back({Space, {}});
+ return Volumes.back();
+ };
+
+ for (StorageDir& Dir : Dirs)
+ {
+ if (!IsDir(Dir.Path))
+ {
+ continue;
+ }
+ DiskSpace Space;
+ if (DiskSpaceInfo(Dir.Path, Space))
+ {
+ FindOrAddVolume(Space).Directories.push_back(&Dir);
+ }
+ }
+
+ Obj.BeginArray("volumes"sv);
+ for (const VolumeInfo& Vol : Volumes)
+ {
+ Obj.BeginObject();
+ Obj << "total"sv << Vol.Space.Total;
+ Obj << "free"sv << Vol.Space.Free;
+ Obj << "used"sv << (Vol.Space.Total - Vol.Space.Free);
+
+ Obj.BeginArray("directories"sv);
+ for (const StorageDir* Dir : Vol.Directories)
+ {
+ Obj.BeginObject();
+ Obj << "name"sv << Dir->Name;
+ Obj << "path"sv << Dir->Path.string();
+
+ DirStats Stats = GetStatsForDirectory(Dir->Path);
+ Obj << "bytes"sv << Stats.ByteCount;
+ Obj << "files"sv << Stats.FileCount;
+ Obj.EndObject();
+ }
+ Obj.EndArray();
+ Obj.EndObject();
+ }
+ Obj.EndArray();
+
+ Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "gclog",
+ [this](HttpRouterRequest& Req) {
+ const GcSchedulerState State = m_GcScheduler.GetState();
+ const std::filesystem::path Path = State.Config.RootDirectory / "gc.log";
+
+ CbObjectWriter Response;
+ Response.BeginArray("entries"sv);
+
+ try
+ {
+ if (IsFile(Path))
+ {
+ IoBuffer FileData = ReadFile(Path).Flatten();
+
+ // The log file contains concatenated named CBO object fields.
+ // Each field is a complete entry: [type+name header][object payload].
+ // We wrap each one in a CbObject and add it to the response array.
+ const uint8_t* Ptr = static_cast<const uint8_t*>(FileData.GetData());
+ const uint8_t* End = Ptr + FileData.GetSize();
+
+ while (Ptr < End)
+ {
+ CbFieldView Field(Ptr);
+ uint64_t FieldSize = Field.GetSize();
+ if (FieldSize == 0 || Ptr + FieldSize > End)
+ {
+ break;
+ }
+
+ // Wrap the named field as an object and add it
+ CbObjectView ObjView = Field.AsObjectView();
+ CbObject Entry = CbObject::Clone(ObjView);
+ Response.AddObject(Entry);
+ Ptr += FieldSize;
+ }
+ }
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("failed to read gc log '{}': {}", Path, Ex.what());
+ }
+
+ Response.EndArray();
+ Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Response.Save());
+ },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
"flush",
[this](HttpRouterRequest& Req) {
HttpServerRequest& HttpReq = Req.ServerRequest();
diff --git a/src/zenserver/storage/admin/admin.h b/src/zenserver/storage/admin/admin.h
index ee3da4579..361153e42 100644
--- a/src/zenserver/storage/admin/admin.h
+++ b/src/zenserver/storage/admin/admin.h
@@ -13,7 +13,7 @@ class JobQueue;
class ZenCacheStore;
struct ZenServerConfig;
-class HttpAdminService : public zen::HttpService
+class HttpAdminService : public HttpService
{
public:
struct LogPaths
@@ -31,7 +31,7 @@ public:
~HttpAdminService();
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
private:
HttpRequestRouter m_Router;
diff --git a/src/zenserver/storage/buildstore/httpbuildstore.cpp b/src/zenserver/storage/buildstore/httpbuildstore.cpp
index de9589078..bbbb0c37b 100644
--- a/src/zenserver/storage/buildstore/httpbuildstore.cpp
+++ b/src/zenserver/storage/buildstore/httpbuildstore.cpp
@@ -605,6 +605,26 @@ HttpBuildStoreService::BlobsExistsRequest(HttpRouterRequest& Req)
return ServerRequest.WriteResponse(HttpResponseCode::OK, ResponseObject);
}
+void
+HttpBuildStoreService::HandleStatusRequest(HttpServerRequest& Request)
+{
+ ZEN_TRACE_CPU("HttpBuildStoreService::Status");
+ CbObjectWriter Cbo;
+ Cbo << "ok" << true;
+ Cbo.BeginObject("capabilities");
+ {
+ Cbo << "maxrangecountperrequest" << MaxRangeCountPerRequestSupported;
+ }
+ Cbo.EndObject(); // capabilities
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+void
+HttpBuildStoreService::HandleStatsRequest(HttpServerRequest& Request)
+{
+ Request.WriteResponse(HttpResponseCode::OK, CollectStats());
+}
+
CbObject
HttpBuildStoreService::CollectStats()
{
@@ -663,24 +683,10 @@ HttpBuildStoreService::CollectStats()
return Cbo.Save();
}
-void
-HttpBuildStoreService::HandleStatsRequest(HttpServerRequest& Request)
-{
- Request.WriteResponse(HttpResponseCode::OK, CollectStats());
-}
-
-void
-HttpBuildStoreService::HandleStatusRequest(HttpServerRequest& Request)
+uint64_t
+HttpBuildStoreService::GetActivityCounter()
{
- ZEN_TRACE_CPU("HttpBuildStoreService::Status");
- CbObjectWriter Cbo;
- Cbo << "ok" << true;
- Cbo.BeginObject("capabilities");
- {
- Cbo << "maxrangecountperrequest" << MaxRangeCountPerRequestSupported;
- }
- Cbo.EndObject(); // capabilities
- Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+ return m_HttpRequests.Count();
}
} // namespace zen
diff --git a/src/zenserver/storage/buildstore/httpbuildstore.h b/src/zenserver/storage/buildstore/httpbuildstore.h
index 2a09b71cf..864d12edc 100644
--- a/src/zenserver/storage/buildstore/httpbuildstore.h
+++ b/src/zenserver/storage/buildstore/httpbuildstore.h
@@ -13,18 +13,19 @@ namespace zen {
class BuildStore;
-class HttpBuildStoreService final : public zen::HttpService, public IHttpStatusProvider, public IHttpStatsProvider
+class HttpBuildStoreService final : public HttpService, public IHttpStatusProvider, public IHttpStatsProvider
{
public:
HttpBuildStoreService(HttpStatusService& StatusService, HttpStatsService& StatsService, BuildStore& Store);
virtual ~HttpBuildStoreService();
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
- virtual CbObject CollectStats() override;
- virtual void HandleStatsRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
private:
struct BuildStoreStats
diff --git a/src/zenserver/storage/cache/httpstructuredcache.cpp b/src/zenserver/storage/cache/httpstructuredcache.cpp
index bbdb03ba4..8ad48225b 100644
--- a/src/zenserver/storage/cache/httpstructuredcache.cpp
+++ b/src/zenserver/storage/cache/httpstructuredcache.cpp
@@ -80,7 +80,8 @@ HttpStructuredCacheService::HttpStructuredCacheService(ZenCacheStore& InCach
HttpStatusService& StatusService,
UpstreamCache& UpstreamCache,
const DiskWriteBlocker* InDiskWriteBlocker,
- OpenProcessCache& InOpenProcessCache)
+ OpenProcessCache& InOpenProcessCache,
+ const ILocalRefPolicy* InLocalRefPolicy)
: m_Log(logging::Get("cache"))
, m_CacheStore(InCacheStore)
, m_StatsService(StatsService)
@@ -90,6 +91,7 @@ HttpStructuredCacheService::HttpStructuredCacheService(ZenCacheStore& InCach
, m_DiskWriteBlocker(InDiskWriteBlocker)
, m_OpenProcessCache(InOpenProcessCache)
, m_RpcHandler(m_Log, m_CacheStats, UpstreamCache, InCacheStore, InCidStore, InDiskWriteBlocker)
+, m_LocalRefPolicy(InLocalRefPolicy)
{
m_StatsService.RegisterHandler("z$", *this);
m_StatusService.RegisterHandler("z$", *this);
@@ -114,6 +116,18 @@ HttpStructuredCacheService::BaseUri() const
return "/z$/";
}
+bool
+HttpStructuredCacheService::AcceptsLocalFileReferences() const
+{
+ return true;
+}
+
+const ILocalRefPolicy*
+HttpStructuredCacheService::GetLocalRefPolicy() const
+{
+ return m_LocalRefPolicy;
+}
+
void
HttpStructuredCacheService::Flush()
{
@@ -1827,113 +1841,12 @@ HttpStructuredCacheService::HandleRpcRequest(HttpServerRequest& Request, std::st
}
}
-CbObject
-HttpStructuredCacheService::CollectStats()
+void
+HttpStructuredCacheService::HandleStatusRequest(HttpServerRequest& Request)
{
- ZEN_MEMSCOPE(GetCacheHttpTag());
-
CbObjectWriter Cbo;
-
- EmitSnapshot("requests", m_HttpRequests, Cbo);
-
- const uint64_t HitCount = m_CacheStats.HitCount;
- const uint64_t UpstreamHitCount = m_CacheStats.UpstreamHitCount;
- const uint64_t MissCount = m_CacheStats.MissCount;
- const uint64_t WriteCount = m_CacheStats.WriteCount;
- const uint64_t BadRequestCount = m_CacheStats.BadRequestCount;
- struct CidStoreStats StoreStats = m_CidStore.Stats();
- const uint64_t ChunkHitCount = StoreStats.HitCount;
- const uint64_t ChunkMissCount = StoreStats.MissCount;
- const uint64_t ChunkWriteCount = StoreStats.WriteCount;
- const uint64_t TotalCount = HitCount + MissCount;
-
- const uint64_t RpcRequests = m_CacheStats.RpcRequests;
- const uint64_t RpcRecordRequests = m_CacheStats.RpcRecordRequests;
- const uint64_t RpcRecordBatchRequests = m_CacheStats.RpcRecordBatchRequests;
- const uint64_t RpcValueRequests = m_CacheStats.RpcValueRequests;
- const uint64_t RpcValueBatchRequests = m_CacheStats.RpcValueBatchRequests;
- const uint64_t RpcChunkRequests = m_CacheStats.RpcChunkRequests;
- const uint64_t RpcChunkBatchRequests = m_CacheStats.RpcChunkBatchRequests;
-
- const CidStoreSize CidSize = m_CidStore.TotalSize();
- const CacheStoreSize CacheSize = m_CacheStore.TotalSize();
-
- Cbo.BeginObject("cache");
- {
- Cbo << "badrequestcount" << BadRequestCount;
- Cbo.BeginObject("rpc");
- Cbo << "count" << RpcRequests;
- Cbo << "ops" << RpcRecordBatchRequests + RpcValueBatchRequests + RpcChunkBatchRequests;
- Cbo.BeginObject("records");
- Cbo << "count" << RpcRecordRequests;
- Cbo << "ops" << RpcRecordBatchRequests;
- Cbo.EndObject();
- Cbo.BeginObject("values");
- Cbo << "count" << RpcValueRequests;
- Cbo << "ops" << RpcValueBatchRequests;
- Cbo.EndObject();
- Cbo.BeginObject("chunks");
- Cbo << "count" << RpcChunkRequests;
- Cbo << "ops" << RpcChunkBatchRequests;
- Cbo.EndObject();
- Cbo.EndObject();
-
- Cbo.BeginObject("size");
- {
- Cbo << "disk" << CacheSize.DiskSize;
- Cbo << "memory" << CacheSize.MemorySize;
- }
- Cbo.EndObject();
-
- Cbo << "hits" << HitCount << "misses" << MissCount << "writes" << WriteCount;
- Cbo << "hit_ratio" << (TotalCount > 0 ? (double(HitCount) / double(TotalCount)) : 0.0);
-
- if (m_UpstreamCache.IsActive())
- {
- Cbo << "upstream_ratio" << (HitCount > 0 ? (double(UpstreamHitCount) / double(HitCount)) : 0.0);
- Cbo << "upstream_hits" << m_CacheStats.UpstreamHitCount;
- }
-
- Cbo << "cidhits" << ChunkHitCount << "cidmisses" << ChunkMissCount << "cidwrites" << ChunkWriteCount;
-
- {
- ZenCacheStore::CacheStoreStats StoreStatsData = m_CacheStore.Stats();
- Cbo.BeginObject("store");
- Cbo << "hits" << StoreStatsData.HitCount << "misses" << StoreStatsData.MissCount << "writes" << StoreStatsData.WriteCount
- << "rejected_writes" << StoreStatsData.RejectedWriteCount << "rejected_reads" << StoreStatsData.RejectedReadCount;
- const uint64_t StoreTotal = StoreStatsData.HitCount + StoreStatsData.MissCount;
- Cbo << "hit_ratio" << (StoreTotal > 0 ? (double(StoreStatsData.HitCount) / double(StoreTotal)) : 0.0);
- EmitSnapshot("read", StoreStatsData.GetOps, Cbo);
- EmitSnapshot("write", StoreStatsData.PutOps, Cbo);
- Cbo.EndObject();
- }
- }
- Cbo.EndObject();
-
- if (m_UpstreamCache.IsActive())
- {
- EmitSnapshot("upstream_gets", m_UpstreamGetRequestTiming, Cbo);
- Cbo.BeginObject("upstream");
- {
- m_UpstreamCache.GetStatus(Cbo);
- }
- Cbo.EndObject();
- }
-
- Cbo.BeginObject("cid");
- {
- Cbo.BeginObject("size");
- {
- Cbo << "tiny" << CidSize.TinySize;
- Cbo << "small" << CidSize.SmallSize;
- Cbo << "large" << CidSize.LargeSize;
- Cbo << "total" << CidSize.TotalSize;
- }
- Cbo.EndObject();
- }
- Cbo.EndObject();
-
- return Cbo.Save();
+ Cbo << "ok" << true;
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
void
@@ -1944,12 +1857,6 @@ HttpStructuredCacheService::HandleStatsRequest(HttpServerRequest& Request)
bool ShowCidStoreStats = Request.GetQueryParams().GetValue("cidstorestats") == "true";
bool ShowCacheStoreStats = Request.GetQueryParams().GetValue("cachestorestats") == "true";
- if (!ShowCidStoreStats && !ShowCacheStoreStats)
- {
- Request.WriteResponse(HttpResponseCode::OK, CollectStats());
- return;
- }
-
// Full stats with optional detailed store/cid breakdowns
CbObjectWriter Cbo;
@@ -2156,12 +2063,38 @@ HttpStructuredCacheService::HandleStatsRequest(HttpServerRequest& Request)
Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
-void
-HttpStructuredCacheService::HandleStatusRequest(HttpServerRequest& Request)
+CbObject
+HttpStructuredCacheService::CollectStats()
{
+ ZEN_TRACE_CPU("HttpStructuredCacheService::Stats");
+ ZEN_MEMSCOPE(GetCacheHttpTag());
+
CbObjectWriter Cbo;
- Cbo << "ok" << true;
- Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+
+ const CacheStoreSize CacheSize = m_CacheStore.TotalSize();
+
+ Cbo.BeginObject("cache");
+ {
+ Cbo.BeginObject("size");
+ {
+ Cbo << "disk" << CacheSize.DiskSize;
+ Cbo << "memory" << CacheSize.MemorySize;
+ }
+ Cbo.EndObject();
+
+ Cbo << "hits" << m_CacheStats.HitCount << "misses" << m_CacheStats.MissCount;
+ }
+ Cbo.EndObject();
+
+ return Cbo.Save();
+}
+
+uint64_t
+HttpStructuredCacheService::GetActivityCounter()
+{
+ return m_HttpRequests.Count();
}
bool
diff --git a/src/zenserver/storage/cache/httpstructuredcache.h b/src/zenserver/storage/cache/httpstructuredcache.h
index d462415d4..f606126d6 100644
--- a/src/zenserver/storage/cache/httpstructuredcache.h
+++ b/src/zenserver/storage/cache/httpstructuredcache.h
@@ -76,11 +76,14 @@ public:
HttpStatusService& StatusService,
UpstreamCache& UpstreamCache,
const DiskWriteBlocker* InDiskWriteBlocker,
- OpenProcessCache& InOpenProcessCache);
+ OpenProcessCache& InOpenProcessCache,
+ const ILocalRefPolicy* InLocalRefPolicy = nullptr);
~HttpStructuredCacheService();
- virtual const char* BaseUri() const override;
- virtual void HandleRequest(HttpServerRequest& Request) override;
+ virtual const char* BaseUri() const override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
+ virtual bool AcceptsLocalFileReferences() const override;
+ virtual const ILocalRefPolicy* GetLocalRefPolicy() const override;
void Flush();
@@ -105,9 +108,10 @@ private:
void HandleCacheRequest(HttpServerRequest& Request);
void HandleCacheNamespaceRequest(HttpServerRequest& Request, std::string_view Namespace);
void HandleCacheBucketRequest(HttpServerRequest& Request, std::string_view Namespace, std::string_view Bucket);
- virtual CbObject CollectStats() override;
- virtual void HandleStatsRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
bool AreDiskWritesAllowed() const;
@@ -124,6 +128,7 @@ private:
const DiskWriteBlocker* m_DiskWriteBlocker = nullptr;
OpenProcessCache& m_OpenProcessCache;
CacheRpcHandler m_RpcHandler;
+ const ILocalRefPolicy* m_LocalRefPolicy = nullptr;
void ReplayRequestRecorder(const CacheRequestContext& Context, cache::IRpcRequestReplayer& Replayer, uint32_t ThreadCount);
diff --git a/src/zenserver/storage/localrefpolicy.cpp b/src/zenserver/storage/localrefpolicy.cpp
new file mode 100644
index 000000000..47ef13b28
--- /dev/null
+++ b/src/zenserver/storage/localrefpolicy.cpp
@@ -0,0 +1,29 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "localrefpolicy.h"
+
+#include <zencore/except_fmt.h>
+#include <zencore/fmtutils.h>
+
+#include <filesystem>
+
+namespace zen {
+
+DataRootLocalRefPolicy::DataRootLocalRefPolicy(const std::filesystem::path& DataRoot)
+: m_CanonicalRoot(std::filesystem::weakly_canonical(DataRoot).string())
+{
+}
+
+void
+DataRootLocalRefPolicy::ValidatePath(const std::filesystem::path& Path) const
+{
+ std::filesystem::path CanonicalFile = std::filesystem::weakly_canonical(Path);
+ std::string FileStr = CanonicalFile.string();
+
+ if (FileStr.size() < m_CanonicalRoot.size() || FileStr.compare(0, m_CanonicalRoot.size(), m_CanonicalRoot) != 0)
+ {
+ throw zen::invalid_argument("local file reference '{}' is outside allowed data root", CanonicalFile);
+ }
+}
+
+} // namespace zen
diff --git a/src/zenserver/storage/localrefpolicy.h b/src/zenserver/storage/localrefpolicy.h
new file mode 100644
index 000000000..3686d1880
--- /dev/null
+++ b/src/zenserver/storage/localrefpolicy.h
@@ -0,0 +1,25 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zenhttp/localrefpolicy.h>
+
+#include <filesystem>
+#include <string>
+
+namespace zen {
+
+/// Local ref policy that restricts file paths to a canonical data root directory.
+/// Uses weakly_canonical + string prefix comparison to detect path traversal.
+class DataRootLocalRefPolicy : public ILocalRefPolicy
+{
+public:
+ explicit DataRootLocalRefPolicy(const std::filesystem::path& DataRoot);
+
+ void ValidatePath(const std::filesystem::path& Path) const override;
+
+private:
+ std::string m_CanonicalRoot;
+};
+
+} // namespace zen
diff --git a/src/zenserver/storage/objectstore/objectstore.cpp b/src/zenserver/storage/objectstore/objectstore.cpp
index e347e2dfe..d6516fa1a 100644
--- a/src/zenserver/storage/objectstore/objectstore.cpp
+++ b/src/zenserver/storage/objectstore/objectstore.cpp
@@ -14,6 +14,7 @@
#include "zencore/compactbinarybuilder.h"
#include "zenhttp/httpcommon.h"
#include "zenhttp/httpserver.h"
+#include "zenhttp/httpstats.h"
#include <filesystem>
#include <thread>
@@ -220,17 +221,20 @@ private:
StringBuilderBase& Builder;
};
-HttpObjectStoreService::HttpObjectStoreService(HttpStatusService& StatusService, ObjectStoreConfig Cfg)
-: m_StatusService(StatusService)
+HttpObjectStoreService::HttpObjectStoreService(HttpStatsService& StatsService, HttpStatusService& StatusService, ObjectStoreConfig Cfg)
+: m_StatsService(StatsService)
+, m_StatusService(StatusService)
, m_Cfg(std::move(Cfg))
{
- Inititalize();
+ Initialize();
+ m_StatsService.RegisterHandler("obj", *this);
m_StatusService.RegisterHandler("obj", *this);
}
HttpObjectStoreService::~HttpObjectStoreService()
{
m_StatusService.UnregisterHandler("obj", *this);
+ m_StatsService.UnregisterHandler("obj", *this);
}
const char*
@@ -240,8 +244,10 @@ HttpObjectStoreService::BaseUri() const
}
void
-HttpObjectStoreService::HandleRequest(zen::HttpServerRequest& Request)
+HttpObjectStoreService::HandleRequest(HttpServerRequest& Request)
{
+ metrics::OperationTiming::Scope $(m_HttpRequests);
+
if (m_Router.HandleRequest(Request) == false)
{
ZEN_LOG_WARN(LogObj, "No route found for {0}", Request.RelativeUri());
@@ -258,12 +264,36 @@ HttpObjectStoreService::HandleStatusRequest(HttpServerRequest& Request)
}
void
-HttpObjectStoreService::Inititalize()
+HttpObjectStoreService::HandleStatsRequest(HttpServerRequest& Request)
+{
+ Request.WriteResponse(HttpResponseCode::OK, CollectStats());
+}
+
+CbObject
+HttpObjectStoreService::CollectStats()
+{
+ ZEN_TRACE_CPU("HttpObjectStoreService::Stats");
+ CbObjectWriter Cbo;
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+ Cbo << "total_bytes_served" << m_TotalBytesServed.load();
+
+ return Cbo.Save();
+}
+
+uint64_t
+HttpObjectStoreService::GetActivityCounter()
+{
+ return m_HttpRequests.Count();
+}
+
+void
+HttpObjectStoreService::Initialize()
{
- ZEN_TRACE_CPU("HttpObjectStoreService::Inititalize");
+ ZEN_TRACE_CPU("HttpObjectStoreService::Initialize");
namespace fs = std::filesystem;
- ZEN_LOG_INFO(LogObj, "Initialzing Object Store in '{}'", m_Cfg.RootDirectory);
+ ZEN_LOG_INFO(LogObj, "Initializing Object Store in '{}'", m_Cfg.RootDirectory);
const fs::path BucketsPath = m_Cfg.RootDirectory / "buckets";
if (!IsDir(BucketsPath))
@@ -280,18 +310,28 @@ HttpObjectStoreService::Inititalize()
[](std::string_view Str) -> bool { return !Str.empty() && AsciiSet::HasOnly(Str, ValidBucketCharactersSet); });
m_Router.RegisterRoute(
+ "",
+ [this](HttpRouterRequest& Request) { ListBuckets(Request); },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
"bucket",
- [this](zen::HttpRouterRequest& Request) { CreateBucket(Request); },
+ [this](HttpRouterRequest& Request) { ListBuckets(Request); },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "bucket",
+ [this](HttpRouterRequest& Request) { CreateBucket(Request); },
HttpVerb::kPost | HttpVerb::kPut);
m_Router.RegisterRoute(
"bucket",
- [this](zen::HttpRouterRequest& Request) { DeleteBucket(Request); },
+ [this](HttpRouterRequest& Request) { DeleteBucket(Request); },
HttpVerb::kDelete);
m_Router.RegisterRoute(
"bucket/{path}",
- [this](zen::HttpRouterRequest& Request) {
+ [this](HttpRouterRequest& Request) {
const std::string_view Path = Request.GetCapture(1);
const auto Sep = Path.find_last_of('.');
const bool IsObject = Sep != std::string_view::npos && Path.size() - Sep > 0;
@@ -309,7 +349,7 @@ HttpObjectStoreService::Inititalize()
m_Router.RegisterRoute(
"bucket/{bucket}/{path}",
- [this](zen::HttpRouterRequest& Request) { PutObject(Request); },
+ [this](HttpRouterRequest& Request) { PutObject(Request); },
HttpVerb::kPost | HttpVerb::kPut);
}
@@ -317,7 +357,7 @@ std::filesystem::path
HttpObjectStoreService::GetBucketDirectory(std::string_view BucketName)
{
{
- std::lock_guard _(BucketsMutex);
+ std::lock_guard _(m_BucketsMutex);
if (const auto It = std::find_if(std::begin(m_Cfg.Buckets),
std::end(m_Cfg.Buckets),
@@ -332,7 +372,99 @@ HttpObjectStoreService::GetBucketDirectory(std::string_view BucketName)
}
void
-HttpObjectStoreService::CreateBucket(zen::HttpRouterRequest& Request)
+HttpObjectStoreService::ListBuckets(HttpRouterRequest& Request)
+{
+ namespace fs = std::filesystem;
+
+ const fs::path BucketsPath = m_Cfg.RootDirectory / "buckets";
+
+ CbObjectWriter Response;
+ Response.BeginArray("buckets");
+ {
+ std::lock_guard _(m_BucketsMutex);
+
+ // Configured buckets
+ for (const ObjectStoreConfig::BucketConfig& Bucket : m_Cfg.Buckets)
+ {
+ Response.BeginObject();
+ Response << "name" << Bucket.Name;
+
+ const fs::path Dir = Bucket.Directory.empty() ? (m_Cfg.RootDirectory / Bucket.Name) : Bucket.Directory;
+ if (IsDir(Dir))
+ {
+ uint64_t TotalSize = 0;
+ uint64_t FileCount = 0;
+ for (const fs::directory_entry& Entry :
+ fs::recursive_directory_iterator(Dir, fs::directory_options::skip_permission_denied))
+ {
+ if (Entry.is_regular_file())
+ {
+ TotalSize += Entry.file_size();
+ FileCount++;
+ }
+ }
+ Response << "size" << TotalSize;
+ Response << "object_count" << FileCount;
+ }
+ Response.EndObject();
+ }
+
+ // Dynamic buckets (on-disk directories not in config)
+ if (IsDir(BucketsPath))
+ {
+ for (const fs::directory_entry& Entry : fs::directory_iterator(BucketsPath))
+ {
+ if (!Entry.is_directory())
+ {
+ continue;
+ }
+ const std::string Name = Entry.path().filename().string();
+
+ // Skip if already listed as a configured bucket
+ bool IsConfigured = false;
+ for (const ObjectStoreConfig::BucketConfig& Bucket : m_Cfg.Buckets)
+ {
+ if (Bucket.Name == Name)
+ {
+ IsConfigured = true;
+ break;
+ }
+ }
+ if (IsConfigured)
+ {
+ continue;
+ }
+
+ Response.BeginObject();
+ Response << "name" << Name;
+
+ uint64_t TotalSize = 0;
+ uint64_t FileCount = 0;
+ for (const fs::directory_entry& FileEntry :
+ fs::recursive_directory_iterator(Entry.path(), fs::directory_options::skip_permission_denied))
+ {
+ if (FileEntry.is_regular_file())
+ {
+ TotalSize += FileEntry.file_size();
+ FileCount++;
+ }
+ }
+ Response << "size" << TotalSize;
+ Response << "object_count" << FileCount;
+
+ Response.EndObject();
+ }
+ }
+ }
+ Response.EndArray();
+
+ Response << "total_bytes_served" << m_TotalBytesServed.load();
+
+ return Request.ServerRequest().WriteResponse(HttpResponseCode::OK, Response.Save());
+}
+
+void
+HttpObjectStoreService::CreateBucket(HttpRouterRequest& Request)
{
namespace fs = std::filesystem;
@@ -346,7 +478,7 @@ HttpObjectStoreService::CreateBucket(zen::HttpRouterRequest& Request)
const fs::path BucketPath = m_Cfg.RootDirectory / "buckets" / BucketName;
{
- std::lock_guard _(BucketsMutex);
+ std::lock_guard _(m_BucketsMutex);
if (!IsDir(BucketPath))
{
CreateDirectories(BucketPath);
@@ -360,7 +492,7 @@ HttpObjectStoreService::CreateBucket(zen::HttpRouterRequest& Request)
}
void
-HttpObjectStoreService::ListBucket(zen::HttpRouterRequest& Request, const std::string_view Path)
+HttpObjectStoreService::ListBucket(HttpRouterRequest& Request, const std::string_view Path)
{
namespace fs = std::filesystem;
@@ -431,7 +563,7 @@ HttpObjectStoreService::ListBucket(zen::HttpRouterRequest& Request, const std::s
if (IsDir(FullPath))
{
- std::lock_guard _(BucketsMutex);
+ std::lock_guard _(m_BucketsMutex);
Traversal.TraverseFileSystem(FullPath, FileVisitor);
}
CbObject Result = FileVisitor.GetResult();
@@ -450,7 +582,7 @@ HttpObjectStoreService::ListBucket(zen::HttpRouterRequest& Request, const std::s
}
void
-HttpObjectStoreService::DeleteBucket(zen::HttpRouterRequest& Request)
+HttpObjectStoreService::DeleteBucket(HttpRouterRequest& Request)
{
namespace fs = std::filesystem;
@@ -464,7 +596,7 @@ HttpObjectStoreService::DeleteBucket(zen::HttpRouterRequest& Request)
const fs::path BucketPath = m_Cfg.RootDirectory / "buckets" / BucketName;
{
- std::lock_guard _(BucketsMutex);
+ std::lock_guard _(m_BucketsMutex);
DeleteDirectories(BucketPath);
}
@@ -473,7 +605,7 @@ HttpObjectStoreService::DeleteBucket(zen::HttpRouterRequest& Request)
}
void
-HttpObjectStoreService::GetObject(zen::HttpRouterRequest& Request, const std::string_view Path)
+HttpObjectStoreService::GetObject(HttpRouterRequest& Request, const std::string_view Path)
{
namespace fs = std::filesystem;
@@ -504,7 +636,7 @@ HttpObjectStoreService::GetObject(zen::HttpRouterRequest& Request, const std::st
return Request.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
}
- zen::HttpRanges Ranges;
+ HttpRanges Ranges;
if (Request.ServerRequest().TryGetRanges(Ranges); Ranges.size() > 1)
{
// Only a single range is supported
@@ -513,7 +645,7 @@ HttpObjectStoreService::GetObject(zen::HttpRouterRequest& Request, const std::st
FileContents File;
{
- std::lock_guard _(BucketsMutex);
+ std::lock_guard _(m_BucketsMutex);
File = ReadFile(FilePath);
}
@@ -533,7 +665,7 @@ HttpObjectStoreService::GetObject(zen::HttpRouterRequest& Request, const std::st
if (Ranges.empty())
{
- const uint64_t TotalServed = TotalBytesServed.fetch_add(FileBuf.Size()) + FileBuf.Size();
+ const uint64_t TotalServed = m_TotalBytesServed.fetch_add(FileBuf.Size()) + FileBuf.Size();
ZEN_LOG_DEBUG(LogObj,
"GET - '{}/{}' ({}) [OK] (Served: {})",
@@ -548,7 +680,7 @@ HttpObjectStoreService::GetObject(zen::HttpRouterRequest& Request, const std::st
{
const auto Range = Ranges[0];
const uint64_t RangeSize = 1 + (Range.End - Range.Start);
- const uint64_t TotalServed = TotalBytesServed.fetch_add(RangeSize) + RangeSize;
+ const uint64_t TotalServed = m_TotalBytesServed.fetch_add(RangeSize) + RangeSize;
ZEN_LOG_DEBUG(LogObj,
"GET - '{}/{}' (Range: {}-{}) ({}/{}) [OK] (Served: {})",
@@ -572,7 +704,7 @@ HttpObjectStoreService::GetObject(zen::HttpRouterRequest& Request, const std::st
}
void
-HttpObjectStoreService::PutObject(zen::HttpRouterRequest& Request)
+HttpObjectStoreService::PutObject(HttpRouterRequest& Request)
{
namespace fs = std::filesystem;
@@ -597,7 +729,7 @@ HttpObjectStoreService::PutObject(zen::HttpRouterRequest& Request)
const fs::path FileDirectory = FilePath.parent_path();
{
- std::lock_guard _(BucketsMutex);
+ std::lock_guard _(m_BucketsMutex);
if (!IsDir(FileDirectory))
{
diff --git a/src/zenserver/storage/objectstore/objectstore.h b/src/zenserver/storage/objectstore/objectstore.h
index 44e50e208..f51254357 100644
--- a/src/zenserver/storage/objectstore/objectstore.h
+++ b/src/zenserver/storage/objectstore/objectstore.h
@@ -11,6 +11,7 @@
namespace zen {
class HttpRouterRequest;
+class HttpStatsService;
struct ObjectStoreConfig
{
@@ -24,30 +25,36 @@ struct ObjectStoreConfig
std::vector<BucketConfig> Buckets;
};
-class HttpObjectStoreService final : public zen::HttpService, public IHttpStatusProvider
+class HttpObjectStoreService final : public HttpService, public IHttpStatusProvider, public IHttpStatsProvider
{
public:
- HttpObjectStoreService(HttpStatusService& StatusService, ObjectStoreConfig Cfg);
+ HttpObjectStoreService(HttpStatsService& StatsService, HttpStatusService& StatusService, ObjectStoreConfig Cfg);
virtual ~HttpObjectStoreService();
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
private:
- void Inititalize();
+ void Initialize();
std::filesystem::path GetBucketDirectory(std::string_view BucketName);
- void CreateBucket(zen::HttpRouterRequest& Request);
- void ListBucket(zen::HttpRouterRequest& Request, const std::string_view Path);
- void DeleteBucket(zen::HttpRouterRequest& Request);
- void GetObject(zen::HttpRouterRequest& Request, const std::string_view Path);
- void PutObject(zen::HttpRouterRequest& Request);
-
- HttpStatusService& m_StatusService;
- ObjectStoreConfig m_Cfg;
- std::mutex BucketsMutex;
- HttpRequestRouter m_Router;
- std::atomic_uint64_t TotalBytesServed{0};
+ void ListBuckets(HttpRouterRequest& Request);
+ void CreateBucket(HttpRouterRequest& Request);
+ void ListBucket(HttpRouterRequest& Request, const std::string_view Path);
+ void DeleteBucket(HttpRouterRequest& Request);
+ void GetObject(HttpRouterRequest& Request, const std::string_view Path);
+ void PutObject(HttpRouterRequest& Request);
+
+ HttpStatsService& m_StatsService;
+ HttpStatusService& m_StatusService;
+ ObjectStoreConfig m_Cfg;
+ std::mutex m_BucketsMutex;
+ HttpRequestRouter m_Router;
+ std::atomic_uint64_t m_TotalBytesServed{0};
+ metrics::OperationTiming m_HttpRequests;
};
} // namespace zen
diff --git a/src/zenserver/storage/projectstore/httpprojectstore.cpp b/src/zenserver/storage/projectstore/httpprojectstore.cpp
index 03b8aa382..afd0d8f82 100644
--- a/src/zenserver/storage/projectstore/httpprojectstore.cpp
+++ b/src/zenserver/storage/projectstore/httpprojectstore.cpp
@@ -656,7 +656,8 @@ HttpProjectService::HttpProjectService(CidStore& Store,
JobQueue& InJobQueue,
bool InRestrictContentTypes,
const std::filesystem::path& InOidcTokenExePath,
- bool InAllowExternalOidcTokenExe)
+ bool InAllowExternalOidcTokenExe,
+ const ILocalRefPolicy* InLocalRefPolicy)
: m_Log(logging::Get("project"))
, m_CidStore(Store)
, m_ProjectStore(Projects)
@@ -668,6 +669,7 @@ HttpProjectService::HttpProjectService(CidStore& Store,
, m_RestrictContentTypes(InRestrictContentTypes)
, m_OidcTokenExePath(InOidcTokenExePath)
, m_AllowExternalOidcTokenExe(InAllowExternalOidcTokenExe)
+, m_LocalRefPolicy(InLocalRefPolicy)
{
ZEN_MEMSCOPE(GetProjectHttpTag());
@@ -820,6 +822,18 @@ HttpProjectService::BaseUri() const
return "/prj/";
}
+bool
+HttpProjectService::AcceptsLocalFileReferences() const
+{
+ return true;
+}
+
+const ILocalRefPolicy*
+HttpProjectService::GetLocalRefPolicy() const
+{
+ return m_LocalRefPolicy;
+}
+
void
HttpProjectService::HandleRequest(HttpServerRequest& Request)
{
@@ -836,8 +850,17 @@ HttpProjectService::HandleRequest(HttpServerRequest& Request)
}
}
-CbObject
-HttpProjectService::CollectStats()
+void
+HttpProjectService::HandleStatusRequest(HttpServerRequest& Request)
+{
+ ZEN_TRACE_CPU("HttpProjectService::Status");
+ CbObjectWriter Cbo;
+ Cbo << "ok" << true;
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+void
+HttpProjectService::HandleStatsRequest(HttpServerRequest& HttpReq)
{
ZEN_TRACE_CPU("ProjectService::Stats");
@@ -848,6 +871,8 @@ HttpProjectService::CollectStats()
EmitSnapshot("requests", m_HttpRequests, Cbo);
+ Cbo << "project_count" << (uint64_t)m_ProjectStore->ProjectCount();
+
Cbo.BeginObject("store");
{
Cbo.BeginObject("size");
@@ -903,22 +928,25 @@ HttpProjectService::CollectStats()
}
Cbo.EndObject();
- return Cbo.Save();
+ HttpReq.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
-void
-HttpProjectService::HandleStatsRequest(HttpServerRequest& HttpReq)
+CbObject
+HttpProjectService::CollectStats()
{
- HttpReq.WriteResponse(HttpResponseCode::OK, CollectStats());
+ CbObjectWriter Cbo;
+ // CollectStats does not use the HandleStatsRequest implementation to get stats since it uses some heavy operations such as
+ // m_ProjectStore->StorageSize();
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+ Cbo << "project_count" << (uint64_t)m_ProjectStore->ProjectCount();
+
+ return Cbo.Save();
}
-void
-HttpProjectService::HandleStatusRequest(HttpServerRequest& Request)
+uint64_t
+HttpProjectService::GetActivityCounter()
{
- ZEN_TRACE_CPU("HttpProjectService::Status");
- CbObjectWriter Cbo;
- Cbo << "ok" << true;
- Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+ return m_HttpRequests.Count();
}
void
@@ -1654,7 +1682,8 @@ HttpProjectService::HandleOplogOpNewRequest(HttpRouterRequest& Req)
CbPackage Package;
- if (!legacy::TryLoadCbPackage(Package, Payload, &UniqueBuffer::Alloc, &Resolver))
+ const bool ValidateHashes = false;
+ if (!legacy::TryLoadCbPackage(Package, Payload, &UniqueBuffer::Alloc, &Resolver, ValidateHashes))
{
CbValidateError ValidateResult;
if (CbObject Core = ValidateAndReadCompactBinaryObject(IoBuffer(Payload), ValidateResult);
@@ -2749,7 +2778,11 @@ HttpProjectService::HandleRpcRequest(HttpRouterRequest& Req)
case HttpContentType::kCbPackage:
try
{
- Package = ParsePackageMessage(Payload);
+ ParseFlags PkgFlags = (HttpReq.IsLocalMachineRequest() && AcceptsLocalFileReferences()) ? ParseFlags::kAllowLocalReferences
+ : ParseFlags::kDefault;
+ const ILocalRefPolicy* PkgPolicy =
+ EnumHasAllFlags(PkgFlags, ParseFlags::kAllowLocalReferences) ? GetLocalRefPolicy() : nullptr;
+ Package = ParsePackageMessage(Payload, {}, PkgFlags, PkgPolicy);
Cb = Package.GetObject();
}
catch (const std::invalid_argument& ex)
diff --git a/src/zenserver/storage/projectstore/httpprojectstore.h b/src/zenserver/storage/projectstore/httpprojectstore.h
index 917337324..8aa345fa7 100644
--- a/src/zenserver/storage/projectstore/httpprojectstore.h
+++ b/src/zenserver/storage/projectstore/httpprojectstore.h
@@ -47,15 +47,19 @@ public:
JobQueue& InJobQueue,
bool InRestrictContentTypes,
const std::filesystem::path& InOidcTokenExePath,
- bool AllowExternalOidcTokenExe);
+ bool AllowExternalOidcTokenExe,
+ const ILocalRefPolicy* InLocalRefPolicy = nullptr);
~HttpProjectService();
- virtual const char* BaseUri() const override;
- virtual void HandleRequest(HttpServerRequest& Request) override;
+ virtual const char* BaseUri() const override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
+ virtual bool AcceptsLocalFileReferences() const override;
+ virtual const ILocalRefPolicy* GetLocalRefPolicy() const override;
- virtual CbObject CollectStats() override;
- virtual void HandleStatsRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
private:
struct ProjectStats
@@ -116,6 +120,7 @@ private:
bool m_RestrictContentTypes;
std::filesystem::path m_OidcTokenExePath;
bool m_AllowExternalOidcTokenExe;
+ const ILocalRefPolicy* m_LocalRefPolicy;
Ref<TransferThreadWorkers> GetThreadWorkers(bool BoostWorkers, bool SingleThreaded);
};
diff --git a/src/zenserver/storage/storageconfig.cpp b/src/zenserver/storage/storageconfig.cpp
index e8ccb9097..0dbb45164 100644
--- a/src/zenserver/storage/storageconfig.cpp
+++ b/src/zenserver/storage/storageconfig.cpp
@@ -373,6 +373,7 @@ ZenStorageServerConfigurator::AddConfigOptions(LuaConfig::Options& LuaOptions)
////// server
LuaOptions.AddOption("server.pluginsconfigfile"sv, ServerOptions.PluginsConfigFile, "plugins-config"sv);
+ LuaOptions.AddOption("sessions.url"sv, ServerOptions.SessionsTargetUrl, "sessions-url"sv);
////// objectstore
LuaOptions.AddOption("server.objectstore.enabled"sv, ServerOptions.ObjectStoreEnabled, "objectstore-enabled"sv);
@@ -620,6 +621,8 @@ ZenStorageServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenStor
cxxopts::value(ServerOptions.ScrubOptions)->implicit_value("yes"),
"(nocas,nogc,nodelete,yes,no)*");
+ options.add_options()("sessions-url", "URL of remote zenserver to announce session to", cxxopts::value<std::string>(SessionsTargetUrl));
+
AddSecurityOptions(options, ServerOptions);
AddCacheOptions(options, ServerOptions);
AddGcOptions(options, ServerOptions);
@@ -1069,6 +1072,7 @@ ZenStorageServerCmdLineOptions::ApplyOptions(cxxopts::Options& options, ZenStora
{.Name = OpenIdProviderName, .Url = OpenIdProviderUrl, .ClientId = OpenIdClientId});
}
+ ServerOptions.SessionsTargetUrl = SessionsTargetUrl;
ServerOptions.ObjectStoreConfig = ParseBucketConfigs(BucketConfigs);
ServerOptions.OidcTokenExecutable = MakeSafeAbsolutePath(OidcTokenExecutable);
}
diff --git a/src/zenserver/storage/storageconfig.h b/src/zenserver/storage/storageconfig.h
index 128804d92..18af4f096 100644
--- a/src/zenserver/storage/storageconfig.h
+++ b/src/zenserver/storage/storageconfig.h
@@ -162,6 +162,7 @@ struct ZenStorageServerConfig : public ZenServerConfig
bool RestrictContentTypes = false;
std::filesystem::path OidcTokenExecutable;
bool AllowExternalOidcTokenExe = true;
+ std::string SessionsTargetUrl;
};
struct ZenStorageServerCmdLineOptions
@@ -183,6 +184,8 @@ struct ZenStorageServerCmdLineOptions
void AddSecurityOptions(cxxopts::Options& options, ZenStorageServerConfig& ServerOptions);
+ std::string SessionsTargetUrl;
+
std::string UpstreamCachePolicyOptions;
void AddCacheOptions(cxxopts::Options& options, ZenStorageServerConfig& ServerOptions);
diff --git a/src/zenserver/storage/upstream/upstreamservice.h b/src/zenserver/storage/upstream/upstreamservice.h
index f1da03c8c..c0063c055 100644
--- a/src/zenserver/storage/upstream/upstreamservice.h
+++ b/src/zenserver/storage/upstream/upstreamservice.h
@@ -9,14 +9,14 @@ namespace zen {
class AuthMgr;
class UpstreamCache;
-class HttpUpstreamService final : public zen::HttpService
+class HttpUpstreamService final : public HttpService
{
public:
HttpUpstreamService(UpstreamCache& Upstream, AuthMgr& Mgr);
virtual ~HttpUpstreamService();
virtual const char* BaseUri() const override;
- virtual void HandleRequest(zen::HttpServerRequest& Request) override;
+ virtual void HandleRequest(HttpServerRequest& Request) override;
private:
UpstreamCache& m_Upstream;
diff --git a/src/zenserver/storage/workspaces/httpworkspaces.cpp b/src/zenserver/storage/workspaces/httpworkspaces.cpp
index 785dd62f0..12e7bae73 100644
--- a/src/zenserver/storage/workspaces/httpworkspaces.cpp
+++ b/src/zenserver/storage/workspaces/httpworkspaces.cpp
@@ -110,10 +110,18 @@ HttpWorkspacesService::HandleRequest(HttpServerRequest& Request)
}
}
-CbObject
-HttpWorkspacesService::CollectStats()
+void
+HttpWorkspacesService::HandleStatusRequest(HttpServerRequest& Request)
+{
+ ZEN_TRACE_CPU("HttpWorkspacesService::Status");
+ CbObjectWriter Cbo;
+ Cbo << "ok" << true;
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+void
+HttpWorkspacesService::HandleStatsRequest(HttpServerRequest& HttpReq)
{
- ZEN_TRACE_CPU("WorkspacesService::Stats");
CbObjectWriter Cbo;
EmitSnapshot("requests", m_HttpRequests, Cbo);
@@ -150,22 +158,26 @@ HttpWorkspacesService::CollectStats()
}
Cbo.EndObject();
- return Cbo.Save();
+ HttpReq.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
-void
-HttpWorkspacesService::HandleStatsRequest(HttpServerRequest& HttpReq)
+CbObject
+HttpWorkspacesService::CollectStats()
{
- HttpReq.WriteResponse(HttpResponseCode::OK, CollectStats());
+ ZEN_TRACE_CPU("HttpWorkspacesService::Stats");
+ CbObjectWriter Cbo;
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+
+ Cbo << "workspaces" << m_Workspaces.GetWorkspaces().size();
+
+ return Cbo.Save();
}
-void
-HttpWorkspacesService::HandleStatusRequest(HttpServerRequest& Request)
+uint64_t
+HttpWorkspacesService::GetActivityCounter()
{
- ZEN_TRACE_CPU("HttpWorkspacesService::Status");
- CbObjectWriter Cbo;
- Cbo << "ok" << true;
- Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+ return m_HttpRequests.Count();
}
void
diff --git a/src/zenserver/storage/workspaces/httpworkspaces.h b/src/zenserver/storage/workspaces/httpworkspaces.h
index 7c5ddeff1..4af1316f8 100644
--- a/src/zenserver/storage/workspaces/httpworkspaces.h
+++ b/src/zenserver/storage/workspaces/httpworkspaces.h
@@ -29,9 +29,10 @@ public:
virtual const char* BaseUri() const override;
virtual void HandleRequest(HttpServerRequest& Request) override;
- virtual CbObject CollectStats() override;
- virtual void HandleStatsRequest(HttpServerRequest& Request) override;
virtual void HandleStatusRequest(HttpServerRequest& Request) override;
+ virtual void HandleStatsRequest(HttpServerRequest& Request) override;
+ virtual CbObject CollectStats() override;
+ virtual uint64_t GetActivityCounter() override;
private:
struct WorkspacesStats
diff --git a/src/zenserver/storage/zenstorageserver.cpp b/src/zenserver/storage/zenstorageserver.cpp
index f5ede5692..6b1da5f12 100644
--- a/src/zenserver/storage/zenstorageserver.cpp
+++ b/src/zenserver/storage/zenstorageserver.cpp
@@ -13,6 +13,8 @@
#include <zencore/iobuffer.h>
#include <zencore/jobqueue.h>
#include <zencore/logging.h>
+#include <zencore/logging/broadcastsink.h>
+#include <zencore/logging/registry.h>
#include <zencore/scopeguard.h>
#include <zencore/sentryintegration.h>
#include <zencore/session.h>
@@ -30,10 +32,13 @@
#include <zenstore/vfsimpl.h>
#include <zenstore/workspaces.h>
#include <zentelemetry/otlptrace.h>
+#include <zenutil/logging.h>
#include <zenutil/service.h>
+#include <zenutil/sessionsclient.h>
#include <zenutil/workerpools.h>
#include <zenutil/zenserverprocess.h>
-#include "../sessions/sessions.h"
+#include "sessions/inprocsessionlogsink.h"
+#include "sessions/sessions.h"
#if ZEN_PLATFORM_WINDOWS
# include <zencore/windows.h>
@@ -165,7 +170,7 @@ ZenStorageServer::RegisterServices()
m_Http->RegisterService(*m_HttpSessionsService);
}
- m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatusService);
+ m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatsService, m_StatusService);
if (m_FrontendService)
{
@@ -218,6 +223,7 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
ZEN_INFO("instantiating project service");
+ m_LocalRefPolicy = std::make_unique<DataRootLocalRefPolicy>(m_DataRoot);
m_JobQueue = MakeJobQueue(8, "bgjobs");
m_OpenProcessCache = std::make_unique<OpenProcessCache>();
@@ -231,7 +237,8 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
*m_JobQueue,
ServerOptions.RestrictContentTypes,
ServerOptions.OidcTokenExecutable,
- ServerOptions.AllowExternalOidcTokenExe});
+ ServerOptions.AllowExternalOidcTokenExe,
+ m_LocalRefPolicy.get()});
if (ServerOptions.WorksSpacesConfig.Enabled)
{
@@ -248,7 +255,22 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
{
m_SessionsService = std::make_unique<SessionsService>();
- m_HttpSessionsService = std::make_unique<HttpSessionsService>(m_StatusService, m_StatsService, *m_SessionsService);
+ m_HttpSessionsService = std::make_unique<HttpSessionsService>(m_StatusService, m_StatsService, *m_SessionsService, m_IoContext);
+ m_HttpSessionsService->SetSelfSessionId(GetSessionId());
+
+ m_InProcSessionLogSink = logging::SinkPtr(new InProcSessionLogSink(*m_SessionsService));
+ m_InProcSessionLogSink->SetLevel(logging::Info);
+ GetDefaultBroadcastSink()->AddSink(m_InProcSessionLogSink);
+ }
+
+ if (!ServerOptions.SessionsTargetUrl.empty())
+ {
+ m_SessionsClient = std::make_unique<SessionsServiceClient>(SessionsServiceClient::Options{
+ .TargetUrl = ServerOptions.SessionsTargetUrl,
+ .AppName = "zenserver",
+ .Mode = GetServerMode(),
+ .SessionId = GetSessionId(),
+ });
}
if (ServerOptions.BuildStoreConfig.Enabled)
@@ -287,7 +309,7 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
ObjCfg.Buckets.push_back(std::move(NewBucket));
}
- m_ObjStoreService = std::make_unique<HttpObjectStoreService>(m_StatusService, std::move(ObjCfg));
+ m_ObjStoreService = std::make_unique<HttpObjectStoreService>(m_StatsService, m_StatusService, std::move(ObjCfg));
}
if (ServerOptions.BuildStoreConfig.Enabled)
@@ -510,7 +532,7 @@ ZenStorageServer::InitializeState(const ZenStorageServerConfig& ServerOptions)
std::error_code Ec;
for (const std::filesystem::directory_entry& DirEntry : std::filesystem::directory_iterator{m_DataRoot, Ec})
{
- if (DirEntry.is_directory() && (DirEntry.path().filename() != "logs"))
+ if (DirEntry.is_directory() && DirEntry.path().filename() != "logs" && DirEntry.path().filename() != ".sentry-native")
{
ZEN_INFO("Deleting '{}'", DirEntry.path());
@@ -693,11 +715,15 @@ ZenStorageServer::InitializeStructuredCache(const ZenStorageServerConfig& Server
m_StatusService,
*m_UpstreamCache,
m_GcManager.GetDiskWriteBlocker(),
- *m_OpenProcessCache);
+ *m_OpenProcessCache,
+ m_LocalRefPolicy.get());
m_StatsReporter.AddProvider(m_CacheStore.Get());
m_StatsReporter.AddProvider(m_CidStore.get());
- m_StatsReporter.AddProvider(m_BuildCidStore.get());
+ if (m_BuildCidStore)
+ {
+ m_StatsReporter.AddProvider(m_BuildCidStore.get());
+ }
}
void
@@ -815,6 +841,17 @@ ZenStorageServer::Run()
OnReady();
+ m_SessionsService->RegisterSession(GetSessionId(), "zenserver", GetServerMode(), Oid::Zero, {});
+
+ if (m_SessionsClient)
+ {
+ (void)m_SessionsClient->Announce();
+ EnqueueSessionAnnounceTimer();
+
+ m_SessionLogSink = m_SessionsClient->CreateLogSink();
+ GetDefaultBroadcastSink()->AddSink(m_SessionLogSink);
+ }
+
if (m_IsPowerCycle)
{
ZEN_INFO("Power cycle mode enabled -- shutting down");
@@ -835,19 +872,48 @@ ZenStorageServer::Cleanup()
ZEN_INFO(ZEN_APP_NAME " cleaning up");
try
{
+ m_SessionAnnounceTimer.cancel();
+
+ // Stop the IO context and join its thread first, before removing sinks.
+ // This ensures no async operations are trying to log through the
+ // broadcast sink while we modify its sink list.
m_IoContext.stop();
if (m_IoRunner.joinable())
{
m_IoRunner.join();
}
- ShutdownServices();
-
+ // Close the HTTP server before removing sinks. HTTP worker threads
+ // continuously log messages and hold the BroadcastSink shared lock,
+ // which would starve the exclusive lock needed by RemoveSink().
if (m_Http)
{
m_Http->Close();
}
+ if (m_InProcSessionLogSink)
+ {
+ GetDefaultBroadcastSink()->RemoveSink(m_InProcSessionLogSink);
+ m_InProcSessionLogSink = {};
+ }
+ if (m_SessionLogSink)
+ {
+ GetDefaultBroadcastSink()->RemoveSink(m_SessionLogSink);
+ m_SessionLogSink = {};
+ }
+ if (m_SessionsClient)
+ {
+ (void)m_SessionsClient->Remove();
+ m_SessionsClient.reset();
+ }
+
+ if (m_SessionsService)
+ {
+ m_SessionsService->RemoveSession(GetSessionId());
+ }
+
+ ShutdownServices();
+
if (m_JobQueue)
{
m_JobQueue->Stop();
@@ -932,6 +998,20 @@ ZenStorageServer::CheckStateMarker()
}
void
+ZenStorageServer::EnqueueSessionAnnounceTimer()
+{
+ m_SessionAnnounceTimer.expires_after(std::chrono::seconds(15));
+ m_SessionAnnounceTimer.async_wait([this](const asio::error_code& Ec) {
+ if (!Ec && m_SessionsClient)
+ {
+ (void)m_SessionsClient->Announce();
+ EnqueueSessionAnnounceTimer();
+ }
+ });
+ EnsureIoRunner();
+}
+
+void
ZenStorageServer::Flush()
{
ZEN_TRACE_CPU("ZenStorageServer::Flush");
diff --git a/src/zenserver/storage/zenstorageserver.h b/src/zenserver/storage/zenstorageserver.h
index d625f869c..e3c6248e6 100644
--- a/src/zenserver/storage/zenstorageserver.h
+++ b/src/zenserver/storage/zenstorageserver.h
@@ -11,8 +11,8 @@
#include <zenstore/cache/structuredcachestore.h>
#include <zenstore/gc.h>
#include <zenstore/projectstore.h>
+#include "localrefpolicy.h"
-#include "../sessions/httpsessions.h"
#include "admin/admin.h"
#include "buildstore/httpbuildstore.h"
#include "cache/httpstructuredcache.h"
@@ -20,11 +20,14 @@
#include "frontend/frontend.h"
#include "objectstore/objectstore.h"
#include "projectstore/httpprojectstore.h"
+#include "sessions/httpsessions.h"
#include "stats/statsreporter.h"
#include "upstream/upstream.h"
#include "vfs/vfsservice.h"
#include "workspaces/httpworkspaces.h"
+#include <zenutil/sessionsclient.h>
+
#if ZEN_WITH_COMPUTE_SERVICES
# include <zencompute/httpcomputeservice.h>
#endif
@@ -63,15 +66,16 @@ private:
void InitializeServices(const ZenStorageServerConfig& ServerOptions);
void RegisterServices();
- std::unique_ptr<JobQueue> m_JobQueue;
- GcManager m_GcManager;
- GcScheduler m_GcScheduler{m_GcManager};
- std::unique_ptr<CidStore> m_CidStore;
- Ref<ZenCacheStore> m_CacheStore;
- std::unique_ptr<OpenProcessCache> m_OpenProcessCache;
- HttpTestService m_TestService;
- std::unique_ptr<CidStore> m_BuildCidStore;
- std::unique_ptr<BuildStore> m_BuildStore;
+ std::unique_ptr<DataRootLocalRefPolicy> m_LocalRefPolicy;
+ std::unique_ptr<JobQueue> m_JobQueue;
+ GcManager m_GcManager;
+ GcScheduler m_GcScheduler{m_GcManager};
+ std::unique_ptr<CidStore> m_CidStore;
+ Ref<ZenCacheStore> m_CacheStore;
+ std::unique_ptr<OpenProcessCache> m_OpenProcessCache;
+ HttpTestService m_TestService;
+ std::unique_ptr<CidStore> m_BuildCidStore;
+ std::unique_ptr<BuildStore> m_BuildStore;
#if ZEN_WITH_TESTS
HttpTestingService m_TestingService;
@@ -94,6 +98,12 @@ private:
std::unique_ptr<HttpAdminService> m_AdminService;
std::unique_ptr<HttpApiService> m_ApiService;
+ std::unique_ptr<SessionsServiceClient> m_SessionsClient;
+ logging::SinkPtr m_SessionLogSink;
+ logging::SinkPtr m_InProcSessionLogSink;
+ asio::steady_timer m_SessionAnnounceTimer{m_IoContext};
+ void EnqueueSessionAnnounceTimer();
+
#if ZEN_WITH_COMPUTE_SERVICES
std::unique_ptr<compute::HttpComputeService> m_HttpComputeService;
#endif
diff --git a/src/zenserver/trace/tracerecorder.cpp b/src/zenserver/trace/tracerecorder.cpp
index 5dec20e18..9321a5ece 100644
--- a/src/zenserver/trace/tracerecorder.cpp
+++ b/src/zenserver/trace/tracerecorder.cpp
@@ -407,6 +407,7 @@ struct TraceRecorder::Impl
m_IoThread = std::thread([this]() {
try
{
+ zen::SetCurrentThreadName("TraceRecorderIO");
m_IoContext.run();
}
catch (const std::exception& Ex)
diff --git a/src/zenserver/xmake.lua b/src/zenserver/xmake.lua
index aa306190f..c2c81e7aa 100644
--- a/src/zenserver/xmake.lua
+++ b/src/zenserver/xmake.lua
@@ -34,6 +34,7 @@ target("zenserver")
add_deps("sol2")
add_packages("http_parser")
add_packages("json11")
+ add_packages("zlib")
add_packages("lua")
add_packages("consul")
add_packages("minio")
@@ -85,6 +86,7 @@ target("zenserver")
on_load(function(target)
local html_dir = path.join(os.projectdir(), "src/zenserver/frontend/html")
+ local docs_dir = path.join(os.projectdir(), "docs")
local zip_dir = path.join(os.projectdir(), get_config("buildir") or "build", "frontend")
local zip_path = path.join(zip_dir, "html.zip")
@@ -92,34 +94,56 @@ target("zenserver")
local need_update = not os.isfile(zip_path)
if not need_update then
local zip_mtime = os.mtime(zip_path)
+ -- Check html sources
for _, file in ipairs(os.files(path.join(html_dir, "**"))) do
if os.mtime(file) > zip_mtime then
need_update = true
break
end
end
+ -- Check docs sources (bundled as data/ in the zip)
+ if not need_update and os.isdir(docs_dir) then
+ for _, file in ipairs(os.files(path.join(docs_dir, "**"))) do
+ if os.mtime(file) > zip_mtime then
+ need_update = true
+ break
+ end
+ end
+ end
end
if need_update then
print("Regenerating frontend zip...")
- os.mkdir(zip_dir)
+
+ -- Stage files in a temporary directory so docs/ appears as data/ in the zip
+ local staging_dir = path.join(zip_dir, "staging")
+ os.tryrm(staging_dir)
+ os.mkdir(staging_dir)
+ os.cp(path.join(html_dir, "*"), staging_dir)
+ if os.isdir(docs_dir) then
+ os.cp(docs_dir, path.join(staging_dir, "data"))
+ os.tryrm(path.join(staging_dir, "data", "dev"))
+ end
+
os.tryrm(zip_path)
import("detect.tools.find_7z")
local cmd_7z = find_7z()
if cmd_7z then
- os.execv(cmd_7z, {"a", "-mx0", "-bso0", zip_path, path.join(html_dir, ".")})
+ os.execv(cmd_7z, {"a", "-bso0", zip_path, path.join(staging_dir, ".")})
else
import("detect.tools.find_zip")
local zip_cmd = find_zip()
if zip_cmd then
- local oldir = os.cd(html_dir)
- os.execv(zip_cmd, {"-r", "-0", "-q", zip_path, "."})
+ local oldir = os.cd(staging_dir)
+ os.execv(zip_cmd, {"-r", "-q", zip_path, "."})
os.cd(oldir)
else
raise("Unable to find a suitable zip tool (need 7z or zip)")
end
end
+
+ os.tryrm(staging_dir)
end
end)
diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp
index fe6a5a572..087b40d6a 100644
--- a/src/zenserver/zenserver.cpp
+++ b/src/zenserver/zenserver.cpp
@@ -272,6 +272,8 @@ ZenServerBase::GetBuildOptions(StringBuilderBase& OutOptions, char Separator) co
OutOptions << Separator;
OutOptions << "ZEN_WITH_MEMTRACK=" << (ZEN_WITH_MEMTRACK ? "1" : "0");
OutOptions << Separator;
+ OutOptions << "ZEN_WITH_COMPUTE_SERVICES=" << (ZEN_WITH_COMPUTE_SERVICES ? "1" : "0");
+ OutOptions << Separator;
OutOptions << "ZEN_WITH_TRACE=" << (ZEN_WITH_TRACE ? "1" : "0");
}
@@ -467,6 +469,15 @@ ZenServerBase::HandleStatusRequest(HttpServerRequest& Request)
Cbo << "hostname" << GetMachineName();
Cbo << "cpuUsagePercent" << Metrics.CpuUsagePercent;
Cbo << "serverMode" << std::string_view(m_ServerMode);
+
+ std::vector<std::string> IpAddresses = GetLocalIpAddresses();
+ Cbo.BeginArray("ipAddresses"sv);
+ for (const std::string& Ip : IpAddresses)
+ {
+ Cbo << Ip;
+ }
+ Cbo.EndArray();
+
Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
@@ -479,9 +490,10 @@ ZenServerBase::BuildSettingsList(const ZenServerConfig& ServerConfig)
{"ContentDir"sv, fmt::format("{}", ServerConfig.ContentDir)},
{"BasePort"sv, fmt::to_string(ServerConfig.BasePort)},
{"CoreLimit"sv, fmt::to_string(ServerConfig.CoreLimit)},
+ {"MemoryAllocator"sv, std::string(GMalloc->GetName())},
+ {"AsioVersion"sv, fmt::format("{}.{}.{}", ASIO_VERSION / 100000, (ASIO_VERSION / 100) % 1000, ASIO_VERSION % 100)},
{"IsDebug"sv, fmt::to_string(ServerConfig.IsDebug)},
{"IsCleanStart"sv, fmt::to_string(ServerConfig.IsCleanStart)},
- {"IsPowerCycle"sv, fmt::to_string(ServerConfig.IsPowerCycle)},
{"IsTest"sv, fmt::to_string(ServerConfig.IsTest)},
{"Detach"sv, fmt::to_string(ServerConfig.Detach)},
{"NoConsoleOutput"sv, fmt::to_string(ServerConfig.LoggingConfig.NoConsoleOutput)},
@@ -684,11 +696,33 @@ ZenServerMain::Run()
}
else
{
- ZEN_CONSOLE_WARN(ZEN_APP_NAME " exiting, failed to add sponsor owner pid {} to process listening to port {} (pid: {})",
- m_ServerOptions.OwnerPid,
- m_ServerOptions.BasePort,
- Entry->Pid.load());
- std::exit(1);
+ // The entry's process failed to pick up our sponsor request after
+ // multiple attempts. Before reclaiming the entry, verify that the
+ // PID does not still belong to a zenserver process. If it does, the
+ // server is alive but unresponsive – fall back to the original error
+ // path. If the PID is gone or belongs to a different executable the
+ // entry is genuinely stale and safe to reclaim.
+ const int StalePid = Entry->Pid.load();
+ std::error_code ExeEc;
+ std::filesystem::path PidExePath = GetProcessExecutablePath(StalePid, ExeEc);
+ const bool PidIsZenServer = !ExeEc && (PidExePath.filename() == GetRunningExecutablePath().filename());
+ if (PidIsZenServer)
+ {
+ ZEN_CONSOLE_WARN(ZEN_APP_NAME
+ " exiting, failed to add sponsor to process on port {} "
+ "(pid {}); that pid is still a running zenserver instance",
+ m_ServerOptions.BasePort,
+ StalePid);
+ std::exit(1);
+ }
+ ZEN_CONSOLE_WARN(
+ "Failed to add sponsor to process on port {} (pid {}); "
+ "pid belongs to '{}' – assuming stale entry and reclaiming",
+ m_ServerOptions.BasePort,
+ StalePid,
+ ExeEc ? "<unknown>" : PidExePath.filename().string());
+ Entry->Reset();
+ Entry = nullptr;
}
}
else
@@ -739,6 +773,8 @@ ZenServerMain::Run()
ZEN_INFO(ZEN_APP_NAME " - using lock file at '{}'", LockFilePath);
ZEN_INFO(ZEN_APP_NAME " - starting on port {}, version '{}'", m_ServerOptions.BasePort, ZEN_CFG_VERSION_BUILD_STRING_FULL);
+ ZEN_INFO(ZEN_APP_NAME " - memory allocator: {}", GMalloc->GetName());
+ ZEN_INFO(ZEN_APP_NAME " - asio: {}.{}.{}", ASIO_VERSION / 100000, (ASIO_VERSION / 100) % 1000, ASIO_VERSION % 100);
Entry = ServerState.Register(m_ServerOptions.BasePort);
diff --git a/src/zenserver/zenserver.h b/src/zenserver/zenserver.h
index d6bf4454f..f5286e9ee 100644
--- a/src/zenserver/zenserver.h
+++ b/src/zenserver/zenserver.h
@@ -45,12 +45,13 @@ public:
void SetIsReadyFunc(std::function<void()>&& IsReadyFunc) { m_IsReadyFunc = std::move(IsReadyFunc); }
- void SetDataRoot(std::filesystem::path Root) { m_DataRoot = Root; }
- void SetContentRoot(std::filesystem::path Root) { m_ContentRoot = Root; }
- void SetDedicatedMode(bool State) { m_IsDedicatedMode = State; }
- void SetAllowPortProbing(bool State) { m_AllowPortProbing = State; }
- void SetServerMode(std::string_view Mode) { m_ServerMode = Mode; }
- void SetTestMode(bool State) { m_TestMode = State; }
+ void SetDataRoot(std::filesystem::path Root) { m_DataRoot = Root; }
+ void SetContentRoot(std::filesystem::path Root) { m_ContentRoot = Root; }
+ void SetDedicatedMode(bool State) { m_IsDedicatedMode = State; }
+ void SetAllowPortProbing(bool State) { m_AllowPortProbing = State; }
+ void SetServerMode(std::string_view Mode) { m_ServerMode = Mode; }
+ const std::string& GetServerMode() const { return m_ServerMode; }
+ void SetTestMode(bool State) { m_TestMode = State; }
protected:
int Initialize(const ZenServerConfig& ServerOptions, ZenServerState::ZenServerEntry* ServerEntry);
diff --git a/src/zenstore/include/zenstore/projectstore.h b/src/zenstore/include/zenstore/projectstore.h
index 6f49cd024..100a82907 100644
--- a/src/zenstore/include/zenstore/projectstore.h
+++ b/src/zenstore/include/zenstore/projectstore.h
@@ -456,6 +456,7 @@ public:
bool DeleteProject(std::string_view ProjectId);
bool Exists(std::string_view ProjectId);
void Flush();
+ size_t ProjectCount() const;
void DiscoverProjects();
void IterateProjects(std::function<void(Project& Prj)>&& Fn);
diff --git a/src/zenstore/projectstore.cpp b/src/zenstore/projectstore.cpp
index 56d0f7d2b..7cd6b9e37 100644
--- a/src/zenstore/projectstore.cpp
+++ b/src/zenstore/projectstore.cpp
@@ -3180,6 +3180,7 @@ ProjectStore::Oplog::AddFileMapping(const RwLock::ExclusiveLockScope&,
}
else
{
+ m_ChunkMap.erase(FileId);
Entry.ServerPath = ServerPath;
}
@@ -4406,6 +4407,13 @@ ProjectStore::DiscoverProjects()
}
}
+size_t
+ProjectStore::ProjectCount() const
+{
+ RwLock::SharedLockScope _(m_ProjectsLock);
+ return m_Projects.size();
+}
+
void
ProjectStore::IterateProjects(std::function<void(Project& Prj)>&& Fn)
{
@@ -5161,7 +5169,10 @@ ExtractRange(IoBuffer&& Chunk, uint64_t Offset, uint64_t Size, ZenContentType Ac
const bool IsFullRange = (Offset == 0) && ((Size == ~(0ull)) || (Size == ChunkSize));
if (IsFullRange)
{
- Result.Chunk = CompositeBuffer(SharedBuffer(std::move(Chunk)));
+ if (ChunkSize > 0)
+ {
+ Result.Chunk = CompositeBuffer(SharedBuffer(std::move(Chunk)));
+ }
Result.RawSize = 0;
}
else
diff --git a/src/zentelemetry/hyperloglog.cpp b/src/zentelemetry/hyperloglog.cpp
new file mode 100644
index 000000000..3a06fc59f
--- /dev/null
+++ b/src/zentelemetry/hyperloglog.cpp
@@ -0,0 +1,127 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zentelemetry/hyperloglog.h>
+
+namespace zen {
+void
+hyperloglog_forcelink()
+{
+}
+} // namespace zen
+
+#if ZEN_WITH_TESTS
+
+# include <zencore/testing.h>
+
+# include <fmt/format.h>
+
+# include <set>
+# include <string>
+
+namespace zen::tests {
+
+TEST_SUITE_BEGIN("telemetry.hyperloglog");
+
+TEST_CASE("hyperloglog.empty")
+{
+ metrics::HyperLogLog<> Hll;
+ CHECK_EQ(Hll.Count(), 0);
+}
+
+TEST_CASE("hyperloglog.single_element")
+{
+ metrics::HyperLogLog<> Hll;
+ Hll.Add("hello");
+ CHECK(Hll.Count() >= 1);
+ CHECK(Hll.Count() <= 2);
+}
+
+TEST_CASE("hyperloglog.duplicates")
+{
+ metrics::HyperLogLog<> Hll;
+ for (int i = 0; i < 1000; ++i)
+ {
+ Hll.Add("same_value");
+ }
+ CHECK_EQ(Hll.Count(), 1);
+}
+
+TEST_CASE("hyperloglog.estimate_accuracy")
+{
+ // With precision 14, expected error is ~0.81%
+ // Use a generous margin (5%) for the test to be reliable
+ constexpr uint64_t N = 100000;
+
+ metrics::HyperLogLog<14> Hll;
+ for (uint64_t i = 0; i < N; ++i)
+ {
+ std::string Value = fmt::format("item_{}", i);
+ Hll.Add(Value);
+ }
+
+ uint64_t Estimate = Hll.Count();
+ double Error = std::abs(static_cast<double>(Estimate) - static_cast<double>(N)) / static_cast<double>(N);
+
+ CHECK(Error < 0.05);
+}
+
+TEST_CASE("hyperloglog.small_cardinality")
+{
+ metrics::HyperLogLog<> Hll;
+ for (int i = 0; i < 10; ++i)
+ {
+ std::string Value = fmt::format("key_{}", i);
+ Hll.Add(Value);
+ }
+
+ uint64_t Estimate = Hll.Count();
+ CHECK(Estimate >= 8);
+ CHECK(Estimate <= 12);
+}
+
+TEST_CASE("hyperloglog.clear")
+{
+ metrics::HyperLogLog<> Hll;
+ for (int i = 0; i < 100; ++i)
+ {
+ std::string Value = fmt::format("v_{}", i);
+ Hll.Add(Value);
+ }
+ CHECK(Hll.Count() > 0);
+
+ Hll.Clear();
+ CHECK_EQ(Hll.Count(), 0);
+}
+
+TEST_CASE("hyperloglog.merge")
+{
+ constexpr uint64_t N = 50000;
+
+ metrics::HyperLogLog<14> A;
+ metrics::HyperLogLog<14> B;
+
+ // A gets even numbers, B gets odd numbers
+ for (uint64_t i = 0; i < N; ++i)
+ {
+ std::string Value = fmt::format("item_{}", i * 2);
+ A.Add(Value);
+ }
+ for (uint64_t i = 0; i < N; ++i)
+ {
+ std::string Value = fmt::format("item_{}", i * 2 + 1);
+ B.Add(Value);
+ }
+
+ A.Merge(B);
+
+ uint64_t Estimate = A.Count();
+ double Error = std::abs(static_cast<double>(Estimate) - static_cast<double>(N * 2)) / static_cast<double>(N * 2);
+
+ CHECK(Error < 0.05);
+}
+
+TEST_SUITE_END();
+
+} // namespace zen::tests
+
+#endif // ZEN_WITH_TESTS
diff --git a/src/zentelemetry/include/zentelemetry/hyperloglog.h b/src/zentelemetry/include/zentelemetry/hyperloglog.h
new file mode 100644
index 000000000..502e2aee5
--- /dev/null
+++ b/src/zentelemetry/include/zentelemetry/hyperloglog.h
@@ -0,0 +1,166 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "zentelemetry.h"
+
+#include <zencore/intmath.h>
+#include <zencore/xxhash.h>
+
+#include <array>
+#include <atomic>
+#include <cmath>
+#include <cstdint>
+#include <string_view>
+
+namespace zen::metrics {
+
+/** HyperLogLog cardinality estimator.
+ *
+ * Estimates the number of distinct elements in a stream using O(2^Precision)
+ * bytes of memory. The relative error is approximately 1.04 / sqrt(2^Precision).
+ *
+ * @tparam Precision Number of bits used for register indexing (4..16).
+ * Higher precision = more memory but lower error.
+ * Default 14 gives 16384 registers (~16 KiB) and ~0.81% error.
+ *
+ * All operations are thread-safe. Add() uses relaxed atomic compare-exchange
+ * so concurrent updates are lock-free but may occasionally lose a race (which
+ * only means a slightly delayed register update, not a correctness issue).
+ */
+template<uint8_t Precision = 14>
+class HyperLogLog
+{
+ static_assert(Precision >= 4 && Precision <= 16, "Precision must be between 4 and 16");
+
+ static constexpr uint32_t RegisterCount = 1u << Precision;
+ static constexpr uint64_t IndexMask = RegisterCount - 1;
+
+public:
+ HyperLogLog() { Clear(); }
+
+ /** Add a raw byte sequence to the sketch. */
+ void Add(const void* Data, size_t Size)
+ {
+ XXH3_128 Hash = XXH3_128::HashMemory(Data, Size);
+ AddHash(Hash);
+ }
+
+ /** Add a string value to the sketch. */
+ void Add(std::string_view Value) { Add(Value.data(), Value.size()); }
+
+ /** Add a pre-computed hash to the sketch. */
+ void AddHash(const XXH3_128& Hash)
+ {
+ // Use the first 8 bytes of the hash as our 64-bit value
+ uint64_t H;
+ memcpy(&H, Hash.Hash, sizeof(H));
+
+ uint32_t Index = static_cast<uint32_t>(H >> (64 - Precision)) & IndexMask;
+ uint64_t W = H << Precision;
+
+ // Count leading zeros of W + 1 (the +1 ensures we never store 0)
+ uint8_t Rank = static_cast<uint8_t>(CountLeadingZeros64(W) + 1);
+
+ // Atomically update the register to the maximum observed rank
+ uint8_t Current = m_Registers[Index].load(std::memory_order_relaxed);
+ while (Rank > Current)
+ {
+ if (m_Registers[Index].compare_exchange_weak(Current, Rank, std::memory_order_relaxed))
+ {
+ break;
+ }
+ }
+ }
+
+ /** Estimate the number of distinct elements added. */
+ double Estimate() const
+ {
+ // Compute the raw harmonic mean estimate
+ double Sum = 0.0;
+ uint32_t ZeroCount = 0;
+
+ for (uint32_t i = 0; i < RegisterCount; ++i)
+ {
+ uint8_t Val = m_Registers[i].load(std::memory_order_relaxed);
+ Sum += 1.0 / static_cast<double>(1ull << Val);
+ if (Val == 0)
+ {
+ ++ZeroCount;
+ }
+ }
+
+ double Alpha = AlphaM();
+ double RawEstimate = Alpha * RegisterCount * RegisterCount / Sum;
+
+ // Small range correction using LinearCounting
+ if (RawEstimate <= 2.5 * RegisterCount && ZeroCount > 0)
+ {
+ return RegisterCount * std::log(static_cast<double>(RegisterCount) / ZeroCount);
+ }
+
+ return RawEstimate;
+ }
+
+ /** Return the estimate as an integer. */
+ uint64_t Count() const
+ {
+ double E = Estimate();
+ return E < 0.5 ? 0 : static_cast<uint64_t>(E + 0.5);
+ }
+
+ /** Reset all registers to zero. */
+ void Clear()
+ {
+ for (uint32_t i = 0; i < RegisterCount; ++i)
+ {
+ m_Registers[i].store(0, std::memory_order_relaxed);
+ }
+ }
+
+ /** Merge another HyperLogLog sketch into this one (union). */
+ void Merge(const HyperLogLog& Other)
+ {
+ for (uint32_t i = 0; i < RegisterCount; ++i)
+ {
+ uint8_t OtherVal = Other.m_Registers[i].load(std::memory_order_relaxed);
+ uint8_t Current = m_Registers[i].load(std::memory_order_relaxed);
+ while (OtherVal > Current)
+ {
+ if (m_Registers[i].compare_exchange_weak(Current, OtherVal, std::memory_order_relaxed))
+ {
+ break;
+ }
+ }
+ }
+ }
+
+private:
+ std::array<std::atomic<uint8_t>, RegisterCount> m_Registers;
+
+ static double AlphaM()
+ {
+ if constexpr (Precision == 4)
+ {
+ return 0.673;
+ }
+ else if constexpr (Precision == 5)
+ {
+ return 0.697;
+ }
+ else if constexpr (Precision == 6)
+ {
+ return 0.709;
+ }
+ else
+ {
+ return 0.7213 / (1.0 + 1.079 / RegisterCount);
+ }
+ }
+};
+
+} // namespace zen::metrics
+
+namespace zen {
+void hyperloglog_forcelink();
+} // namespace zen
diff --git a/src/zentelemetry/zentelemetry.cpp b/src/zentelemetry/zentelemetry.cpp
index ed6ad13b9..63af8a450 100644
--- a/src/zentelemetry/zentelemetry.cpp
+++ b/src/zentelemetry/zentelemetry.cpp
@@ -2,6 +2,7 @@
#include "zentelemetry/zentelemetry.h"
+#include "zentelemetry/hyperloglog.h"
#include "zentelemetry/otlptrace.h"
#include "zentelemetry/stats.h"
@@ -11,6 +12,7 @@ void
zentelemetry_forcelinktests()
{
zen::stats_forcelink();
+ zen::hyperloglog_forcelink();
#if ZEN_WITH_OTEL
zen::otel::otlptrace_forcelink();
#endif
diff --git a/src/zentest-appstub/zentest-appstub.cpp b/src/zentest-appstub/zentest-appstub.cpp
index 509629739..73cb7ff2d 100644
--- a/src/zentest-appstub/zentest-appstub.cpp
+++ b/src/zentest-appstub/zentest-appstub.cpp
@@ -33,6 +33,13 @@ using namespace zen;
// Some basic functions to implement some test "compute" functions
+struct ForcedExitException : std::exception
+{
+ int Code;
+ explicit ForcedExitException(int InCode) : Code(InCode) {}
+ const char* what() const noexcept override { return "forced exit"; }
+};
+
std::string
Rot13Function(std::string_view InputString)
{
@@ -111,6 +118,16 @@ DescribeFunctions()
<< "Sleep"sv;
Versions << "Version"sv << Guid::FromString("88888888-8888-8888-8888-888888888888"sv);
Versions.EndObject();
+ Versions.BeginObject();
+ Versions << "Name"sv
+ << "Fail"sv;
+ Versions << "Version"sv << Guid::FromString("fa11fa11-fa11-fa11-fa11-fa11fa11fa11"sv);
+ Versions.EndObject();
+ Versions.BeginObject();
+ Versions << "Name"sv
+ << "Crash"sv;
+ Versions << "Version"sv << Guid::FromString("c4a50000-c4a5-c4a5-c4a5-c4a5c4a5c4a5"sv);
+ Versions.EndObject();
Versions.EndArray();
return Versions.Save();
@@ -201,6 +218,38 @@ ExecuteFunction(CbObject Action, ContentResolver ChunkResolver)
zen::Sleep(static_cast<int>(SleepTimeMs));
return Apply(IdentityFunction);
}
+ else if (Function == "Fail"sv)
+ {
+ int FailExitCode = static_cast<int>(Action["Constants"sv].AsObjectView()["ExitCode"sv].AsUInt64());
+ if (FailExitCode == 0)
+ {
+ FailExitCode = 1;
+ }
+ throw ForcedExitException(FailExitCode);
+ }
+ else if (Function == "Crash"sv)
+ {
+ // Crash modes:
+ // "abort" - calls std::abort() (SIGABRT / process termination)
+ // "nullptr" - dereferences a null pointer (SIGSEGV / access violation)
+ std::string_view Mode = Action["Constants"sv].AsObjectView()["Mode"sv].AsString();
+
+ printf("[zentest] crashing with mode: %.*s\n", int(Mode.size()), Mode.data());
+ fflush(stdout);
+
+ if (Mode == "nullptr"sv)
+ {
+ volatile int* Ptr = nullptr;
+ *Ptr = 42;
+ }
+
+ // Default crash mode (also reached after nullptr write on platforms
+ // that don't immediately fault on null dereference)
+#if defined(_MSC_VER)
+ _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
+#endif
+ std::abort();
+ }
else
{
return {};
@@ -221,10 +270,10 @@ main(int argc, char* argv[])
try
{
- std::filesystem::path BasePath = std::filesystem::current_path();
- std::filesystem::path InputPath = std::filesystem::current_path() / "Inputs";
- std::filesystem::path OutputPath = std::filesystem::current_path() / "Outputs";
- std::filesystem::path VersionPath = std::filesystem::current_path() / "Versions";
+ std::filesystem::path BasePath = std::filesystem::current_path();
+ std::filesystem::path InputPath = std::filesystem::current_path() / "Inputs";
+ std::filesystem::path OutputPath = std::filesystem::current_path() / "Outputs";
+ std::filesystem::path VersionPath;
std::vector<std::filesystem::path> ActionPaths;
/*
@@ -291,6 +340,20 @@ main(int argc, char* argv[])
std::string_view ErrorArg = SplitArg(argv[i]);
ExitCode = ParseIntArg(ErrorArg);
}
+ else if (std::strncmp(argv[i], "-echo=", 6) == 0)
+ {
+ // Write a message to stdout. Useful for testing pipe capture.
+ std::string_view Message = SplitArg(argv[i]);
+ printf("%.*s", static_cast<int>(Message.size()), Message.data());
+ fflush(stdout);
+ }
+ else if (std::strncmp(argv[i], "-echoerr=", 9) == 0)
+ {
+ // Write a message to stderr. Useful for testing separate stderr pipe capture.
+ std::string_view Message = SplitArg(argv[i]);
+ fprintf(stderr, "%.*s", static_cast<int>(Message.size()), Message.data());
+ fflush(stderr);
+ }
else if ((_strnicmp(argv[i], "-input=", 7) == 0) || (_strnicmp(argv[i], "-i=", 3) == 0))
{
/* mimic DDC2
@@ -407,6 +470,12 @@ main(int argc, char* argv[])
}
}
}
+ catch (ForcedExitException& Ex)
+ {
+ printf("[zentest] forced exit with code: %d\n", Ex.Code);
+
+ ExitCode = Ex.Code;
+ }
catch (std::exception& Ex)
{
printf("[zentest] exception caught in main: '%s'\n", Ex.what());
diff --git a/src/zenutil-test/xmake.lua b/src/zenutil-test/xmake.lua
index c77af2482..e124c321d 100644
--- a/src/zenutil-test/xmake.lua
+++ b/src/zenutil-test/xmake.lua
@@ -6,4 +6,5 @@ target("zenutil-test")
add_headerfiles("**.h")
add_files("*.cpp")
add_deps("zenutil")
+ add_deps("zentest-appstub")
add_deps("doctest")
diff --git a/src/zenutil/cloud/imdscredentials.cpp b/src/zenutil/cloud/imdscredentials.cpp
index dde1dc019..5a6cf45d2 100644
--- a/src/zenutil/cloud/imdscredentials.cpp
+++ b/src/zenutil/cloud/imdscredentials.cpp
@@ -115,7 +115,7 @@ ImdsCredentialProvider::FetchToken()
HttpClient::KeyValueMap Headers;
Headers->emplace("X-aws-ec2-metadata-token-ttl-seconds", "21600");
- HttpClient::Response Response = m_HttpClient.Put("/latest/api/token", Headers);
+ HttpClient::Response Response = m_HttpClient.Put("/latest/api/token", IoBuffer{}, Headers);
if (!Response.IsSuccess())
{
ZEN_WARN("IMDS token request failed: {}", Response.ErrorMessage("PUT /latest/api/token"));
diff --git a/src/zenutil/cloud/minioprocess.cpp b/src/zenutil/cloud/minioprocess.cpp
index 565705731..e146f6677 100644
--- a/src/zenutil/cloud/minioprocess.cpp
+++ b/src/zenutil/cloud/minioprocess.cpp
@@ -45,7 +45,7 @@ struct MinioProcess::Impl
}
CreateProcOptions Options;
- Options.Flags |= CreateProcOptions::Flag_Windows_NewProcessGroup;
+ Options.Flags |= CreateProcOptions::Flag_NewProcessGroup;
Options.Environment.emplace_back("MINIO_ROOT_USER", m_Options.RootUser);
Options.Environment.emplace_back("MINIO_ROOT_PASSWORD", m_Options.RootPassword);
@@ -72,11 +72,12 @@ struct MinioProcess::Impl
ZEN_INFO("MinIO server started successfully (waited {})", NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
return;
}
- } while (Timer.GetElapsedTimeMs() < 10000);
+ } while (Timer.GetElapsedTimeMs() < 30000);
}
- // Report failure
- ZEN_WARN("MinIO server failed to start within timeout period");
+ // Report failure - throw so test failures show the real cause instead of a confusing
+ // assertion failure later when S3 operations fail silently.
+ throw std::runtime_error(fmt::format("MinIO server on port {} failed to start within timeout", m_Options.Port));
}
void StopMinioServer()
diff --git a/src/zenutil/cloud/s3client.cpp b/src/zenutil/cloud/s3client.cpp
index 88d844b61..d9fde05d9 100644
--- a/src/zenutil/cloud/s3client.cpp
+++ b/src/zenutil/cloud/s3client.cpp
@@ -137,6 +137,8 @@ namespace {
} // namespace
+std::string_view S3GetObjectResult::NotFoundErrorText = "Not found";
+
S3Client::S3Client(const S3ClientOptions& Options)
: m_Log(logging::Get("s3"))
, m_BucketName(Options.BucketName)
@@ -145,13 +147,7 @@ S3Client::S3Client(const S3ClientOptions& Options)
, m_PathStyle(Options.PathStyle)
, m_Credentials(Options.Credentials)
, m_CredentialProvider(Options.CredentialProvider)
-, m_HttpClient(BuildEndpoint(),
- HttpClientSettings{
- .LogCategory = "s3",
- .ConnectTimeout = Options.ConnectTimeout,
- .Timeout = Options.Timeout,
- .RetryCount = Options.RetryCount,
- })
+, m_HttpClient(BuildEndpoint(), Options.HttpSettings)
{
m_Host = BuildHostHeader();
ZEN_INFO("S3 client configured for bucket '{}' in region '{}' (endpoint: {}, {})",
@@ -171,14 +167,19 @@ S3Client::GetCurrentCredentials()
SigV4Credentials Creds = m_CredentialProvider->GetCredentials();
if (!Creds.AccessKeyId.empty())
{
- // Invalidate the signing key cache when the access key changes
+ // Invalidate the signing key cache when the access key changes, and update stored
+ // credentials atomically under the same lock so callers see a consistent snapshot.
+ RwLock::ExclusiveLockScope ExclusiveLock(m_SigningKeyLock);
if (Creds.AccessKeyId != m_Credentials.AccessKeyId)
{
- RwLock::ExclusiveLockScope ExclusiveLock(m_SigningKeyLock);
m_CachedDateStamp.clear();
}
m_Credentials = Creds;
+ // Return Creds directly - avoids reading m_Credentials after releasing the lock,
+ // which would race with another concurrent write.
+ return Creds;
}
+ // IMDS returned empty credentials; fall back to the last known-good credentials.
return m_Credentials;
}
return m_Credentials;
@@ -252,7 +253,7 @@ S3Client::BucketRootPath() const
Sha256Digest
S3Client::GetSigningKey(std::string_view DateStamp)
{
- // Fast path: shared lock for cache hit (common case — key only changes once per day)
+ // Fast path: shared lock for cache hit (common case - key only changes once per day)
{
RwLock::SharedLockScope SharedLock(m_SigningKeyLock);
if (m_CachedDateStamp == DateStamp)
@@ -342,15 +343,20 @@ S3Client::PutObject(std::string_view Key, IoBuffer Content)
}
S3GetObjectResult
-S3Client::GetObject(std::string_view Key)
+S3Client::GetObject(std::string_view Key, const std::filesystem::path& TempFilePath)
{
std::string Path = KeyToPath(Key);
HttpClient::KeyValueMap Headers = SignRequest("GET", Path, "", EmptyPayloadHash);
- HttpClient::Response Response = m_HttpClient.Get(Path, Headers);
+ HttpClient::Response Response = m_HttpClient.Download(Path, TempFilePath, Headers);
if (!Response.IsSuccess())
{
+ if (Response.StatusCode == HttpResponseCode::NotFound)
+ {
+ return S3GetObjectResult{S3Result{.Error = std::string(S3GetObjectResult::NotFoundErrorText)}, {}};
+ }
+
std::string Err = Response.ErrorMessage("S3 GET failed");
ZEN_WARN("S3 GET '{}' failed: {}", Key, Err);
return S3GetObjectResult{S3Result{std::move(Err)}, {}};
@@ -360,6 +366,51 @@ S3Client::GetObject(std::string_view Key)
return S3GetObjectResult{{}, std::move(Response.ResponsePayload)};
}
+S3GetObjectResult
+S3Client::GetObjectRange(std::string_view Key, uint64_t RangeStart, uint64_t RangeSize)
+{
+ ZEN_ASSERT(RangeSize > 0);
+ std::string Path = KeyToPath(Key);
+
+ HttpClient::KeyValueMap Headers = SignRequest("GET", Path, "", EmptyPayloadHash);
+ Headers->emplace("Range", fmt::format("bytes={}-{}", RangeStart, RangeStart + RangeSize - 1));
+
+ HttpClient::Response Response = m_HttpClient.Get(Path, Headers);
+ if (!Response.IsSuccess())
+ {
+ if (Response.StatusCode == HttpResponseCode::NotFound)
+ {
+ return S3GetObjectResult{S3Result{.Error = std::string(S3GetObjectResult::NotFoundErrorText)}, {}};
+ }
+
+ std::string Err = Response.ErrorMessage("S3 GET range failed");
+ ZEN_WARN("S3 GET range '{}' [{}-{}] failed: {}", Key, RangeStart, RangeStart + RangeSize - 1, Err);
+ return S3GetObjectResult{S3Result{std::move(Err)}, {}};
+ }
+
+ // Callers are expected to request only ranges that lie within the known object size (e.g.
+ // by calling HeadObject first). Treat a short read as an error rather than silently
+ // returning a truncated buffer - a partial write is more dangerous than a hard failure.
+ if (Response.ResponsePayload.GetSize() != RangeSize)
+ {
+ std::string Err = fmt::format("S3 GET range '{}' [{}-{}] returned {} bytes, expected {}",
+ Key,
+ RangeStart,
+ RangeStart + RangeSize - 1,
+ Response.ResponsePayload.GetSize(),
+ RangeSize);
+ ZEN_WARN("{}", Err);
+ return S3GetObjectResult{S3Result{std::move(Err)}, {}};
+ }
+
+ ZEN_DEBUG("S3 GET range '{}' [{}-{}] succeeded ({} bytes)",
+ Key,
+ RangeStart,
+ RangeStart + RangeSize - 1,
+ Response.ResponsePayload.GetSize());
+ return S3GetObjectResult{{}, std::move(Response.ResponsePayload)};
+}
+
S3Result
S3Client::DeleteObject(std::string_view Key)
{
@@ -693,19 +744,18 @@ S3Client::GeneratePresignedUrlForMethod(std::string_view Key, std::string_view M
}
S3Result
-S3Client::PutObjectMultipart(std::string_view Key, IoBuffer Content, uint64_t PartSize)
+S3Client::PutObjectMultipart(std::string_view Key,
+ uint64_t TotalSize,
+ std::function<IoBuffer(uint64_t Offset, uint64_t Size)> FetchRange,
+ uint64_t PartSize)
{
- const uint64_t ContentSize = Content.GetSize();
-
// If the content fits in a single part, just use PutObject
- if (ContentSize <= PartSize)
+ if (TotalSize <= PartSize)
{
- return PutObject(Key, Content);
+ return PutObject(Key, TotalSize > 0 ? FetchRange(0, TotalSize) : IoBuffer{});
}
- ZEN_INFO("S3 multipart upload '{}': {} bytes in ~{} parts", Key, ContentSize, (ContentSize + PartSize - 1) / PartSize);
-
- // Initiate multipart upload
+ ZEN_DEBUG("S3 multipart upload '{}': {} bytes in ~{} parts", Key, TotalSize, (TotalSize + PartSize - 1) / PartSize);
S3CreateMultipartUploadResult InitResult = CreateMultipartUpload(Key);
if (!InitResult)
@@ -722,38 +772,51 @@ S3Client::PutObjectMultipart(std::string_view Key, IoBuffer Content, uint64_t Pa
uint64_t Offset = 0;
uint32_t PartNumber = 1;
- while (Offset < ContentSize)
+ try
{
- uint64_t ThisPartSize = std::min(PartSize, ContentSize - Offset);
+ while (Offset < TotalSize)
+ {
+ uint64_t ThisPartSize = std::min(PartSize, TotalSize - Offset);
+ IoBuffer PartContent = FetchRange(Offset, ThisPartSize);
+ S3UploadPartResult PartResult = UploadPart(Key, UploadId, PartNumber, std::move(PartContent));
+ if (!PartResult)
+ {
+ AbortMultipartUpload(Key, UploadId);
+ return S3Result{std::move(PartResult.Error)};
+ }
- // Create a sub-buffer referencing the part data within the original content
- IoBuffer PartContent(Content, Offset, ThisPartSize);
+ PartETags.emplace_back(PartNumber, std::move(PartResult.ETag));
+ Offset += ThisPartSize;
+ PartNumber++;
+ }
- S3UploadPartResult PartResult = UploadPart(Key, UploadId, PartNumber, PartContent);
- if (!PartResult)
+ S3Result CompleteResult = CompleteMultipartUpload(Key, UploadId, PartETags);
+ if (!CompleteResult)
{
- // Attempt to abort the multipart upload on failure
AbortMultipartUpload(Key, UploadId);
- return S3Result{std::move(PartResult.Error)};
+ return CompleteResult;
}
-
- PartETags.emplace_back(PartNumber, std::move(PartResult.ETag));
- Offset += ThisPartSize;
- PartNumber++;
}
-
- // Complete multipart upload
- S3Result CompleteResult = CompleteMultipartUpload(Key, UploadId, PartETags);
- if (!CompleteResult)
+ catch (...)
{
AbortMultipartUpload(Key, UploadId);
- return CompleteResult;
+ throw;
}
- ZEN_INFO("S3 multipart upload '{}' completed ({} parts, {} bytes)", Key, PartETags.size(), ContentSize);
+ ZEN_DEBUG("S3 multipart upload '{}' completed ({} parts, {} bytes)", Key, PartETags.size(), TotalSize);
return {};
}
+S3Result
+S3Client::PutObjectMultipart(std::string_view Key, IoBuffer Content, uint64_t PartSize)
+{
+ return PutObjectMultipart(
+ Key,
+ Content.GetSize(),
+ [&Content](uint64_t Offset, uint64_t Size) { return IoBuffer(Content, Offset, Size); },
+ PartSize);
+}
+
//////////////////////////////////////////////////////////////////////////
// Tests
@@ -828,7 +891,10 @@ TEST_CASE("s3client.minio_integration")
{
using namespace std::literals;
- // Spawn a local MinIO server
+ // Spawn a single MinIO server for the entire test case. Previously each SUBCASE re-entered
+ // the TEST_CASE from the top, spawning and killing MinIO per subcase — slow and flaky on
+ // macOS CI. Sequential sections avoid the re-entry while still sharing one MinIO instance
+ // that is torn down via RAII at scope exit.
MinioProcessOptions MinioOpts;
MinioOpts.Port = 19000;
MinioOpts.RootUser = "testuser";
@@ -836,11 +902,8 @@ TEST_CASE("s3client.minio_integration")
MinioProcess Minio(MinioOpts);
Minio.SpawnMinioServer();
-
- // Pre-create the test bucket (creates a subdirectory in MinIO's data dir)
Minio.CreateBucket("integration-test");
- // Configure S3Client for the test bucket
S3ClientOptions Opts;
Opts.BucketName = "integration-test";
Opts.Region = "us-east-1";
@@ -851,7 +914,7 @@ TEST_CASE("s3client.minio_integration")
S3Client Client(Opts);
- SUBCASE("put_get_delete")
+ // -- put_get_delete -------------------------------------------------------
{
// PUT
std::string_view TestData = "hello, minio integration test!"sv;
@@ -880,14 +943,14 @@ TEST_CASE("s3client.minio_integration")
CHECK(HeadRes2.Status == HeadObjectResult::NotFound);
}
- SUBCASE("head_not_found")
+ // -- head_not_found -------------------------------------------------------
{
S3HeadObjectResult Res = Client.HeadObject("nonexistent/key.dat");
CHECK(Res.IsSuccess());
CHECK(Res.Status == HeadObjectResult::NotFound);
}
- SUBCASE("list_objects")
+ // -- list_objects ---------------------------------------------------------
{
// Upload several objects with a common prefix
for (int i = 0; i < 3; ++i)
@@ -922,7 +985,7 @@ TEST_CASE("s3client.minio_integration")
}
}
- SUBCASE("multipart_upload")
+ // -- multipart_upload -----------------------------------------------------
{
// Create a payload large enough to exercise multipart (use minimum part size)
constexpr uint64_t PartSize = 5 * 1024 * 1024; // 5 MB minimum
@@ -949,7 +1012,7 @@ TEST_CASE("s3client.minio_integration")
Client.DeleteObject("multipart/large.bin");
}
- SUBCASE("presigned_urls")
+ // -- presigned_urls -------------------------------------------------------
{
// Upload an object
std::string_view TestData = "presigned-url-test-data"sv;
@@ -975,8 +1038,6 @@ TEST_CASE("s3client.minio_integration")
// Cleanup
Client.DeleteObject("presigned/test.txt");
}
-
- Minio.StopMinioServer();
}
TEST_SUITE_END();
diff --git a/src/zenutil/config/loggingconfig.cpp b/src/zenutil/config/loggingconfig.cpp
index 5092c60aa..e2db31160 100644
--- a/src/zenutil/config/loggingconfig.cpp
+++ b/src/zenutil/config/loggingconfig.cpp
@@ -29,6 +29,8 @@ ZenLoggingCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenLoggingCon
("log-critical", "Change selected loggers to level CRITICAL", cxxopts::value<std::string>(LoggingConfig.Loggers[logging::Critical]))
("log-off", "Change selected loggers to level OFF", cxxopts::value<std::string>(LoggingConfig.Loggers[logging::Off]))
("otlp-endpoint", "OpenTelemetry endpoint URI (e.g http://localhost:4318)", cxxopts::value<std::string>(LoggingConfig.OtelEndpointUri))
+ ("force-color", "Force colored log output even when stdout is not a terminal", cxxopts::value<bool>(LoggingConfig.ForceColor)->default_value("false"))
+ ("log-stream", "TCP log stream endpoint (host:port)", cxxopts::value<std::string>(LoggingConfig.LogStreamEndpoint))
;
// clang-format on
}
diff --git a/src/zenutil/consul/consul.cpp b/src/zenutil/consul/consul.cpp
index 272096ebb..951beed65 100644
--- a/src/zenutil/consul/consul.cpp
+++ b/src/zenutil/consul/consul.cpp
@@ -9,9 +9,13 @@
#include <zencore/logging.h>
#include <zencore/process.h>
#include <zencore/string.h>
+#include <zencore/testing.h>
+#include <zencore/testutils.h>
#include <zencore/thread.h>
#include <zencore/timer.h>
+#include <zenhttp/httpserver.h>
+
#include <fmt/format.h>
namespace zen::consul {
@@ -20,7 +24,7 @@ namespace zen::consul {
struct ConsulProcess::Impl
{
- Impl(std::string_view BaseUri) : m_HttpClient(BaseUri) {}
+ Impl(std::string_view BaseUri, std::string_view Token = "") : m_Token(Token), m_HttpClient(BaseUri) {}
~Impl() = default;
void SpawnConsulAgent()
@@ -31,7 +35,7 @@ struct ConsulProcess::Impl
}
CreateProcOptions Options;
- Options.Flags |= CreateProcOptions::Flag_Windows_NewProcessGroup;
+ Options.Flags |= CreateProcOptions::Flag_NewProcessGroup;
const std::filesystem::path ConsulExe = GetRunningExecutablePath().parent_path() / ("consul" ZEN_EXE_SUFFIX_LITERAL);
CreateProcResult Result = CreateProc(ConsulExe, "consul" ZEN_EXE_SUFFIX_LITERAL " agent -dev", Options);
@@ -44,10 +48,16 @@ struct ConsulProcess::Impl
// Poll to check when the agent is ready
+ HttpClient::KeyValueMap AdditionalHeaders;
+ if (!m_Token.empty())
+ {
+ AdditionalHeaders.Entries.emplace("X-Consul-Token", m_Token);
+ }
+
do
{
Sleep(100);
- HttpClient::Response Resp = m_HttpClient.Get("v1/status/leader");
+ HttpClient::Response Resp = m_HttpClient.Get("v1/status/leader", AdditionalHeaders);
if (Resp)
{
ZEN_INFO("Consul agent started successfully (waited {})", NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
@@ -75,6 +85,7 @@ struct ConsulProcess::Impl
private:
ProcessHandle m_ProcessHandle;
+ std::string m_Token;
HttpClient m_HttpClient;
};
@@ -100,7 +111,7 @@ ConsulProcess::StopConsulAgent()
//////////////////////////////////////////////////////////////////////////
-ConsulClient::ConsulClient(std::string_view BaseUri) : m_HttpClient(BaseUri)
+ConsulClient::ConsulClient(const Configuration& Config) : m_Config(Config), m_HttpClient(m_Config.BaseUri)
{
}
@@ -111,9 +122,13 @@ ConsulClient::~ConsulClient()
void
ConsulClient::SetKeyValue(std::string_view Key, std::string_view Value)
{
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+ AdditionalHeaders.Entries.emplace(HttpClient::Accept(HttpContentType::kJSON));
+
IoBuffer ValueBuffer = IoBufferBuilder::MakeFromMemory(MakeMemoryView(Value));
ValueBuffer.SetContentType(HttpContentType::kText);
- HttpClient::Response Result = m_HttpClient.Put(fmt::format("v1/kv/{}", Key), ValueBuffer, HttpClient::Accept(HttpContentType::kJSON));
+ HttpClient::Response Result = m_HttpClient.Put(fmt::format("v1/kv/{}", Key), ValueBuffer, AdditionalHeaders);
if (!Result)
{
throw runtime_error("ConsulClient::SetKeyValue() failed to set key '{}' ({})", Key, Result.ErrorMessage(""));
@@ -123,7 +138,10 @@ ConsulClient::SetKeyValue(std::string_view Key, std::string_view Value)
std::string
ConsulClient::GetKeyValue(std::string_view Key)
{
- HttpClient::Response Result = m_HttpClient.Get(fmt::format("v1/kv/{}?raw", Key));
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+
+ HttpClient::Response Result = m_HttpClient.Get(fmt::format("v1/kv/{}?raw", Key), AdditionalHeaders);
if (!Result)
{
throw runtime_error("ConsulClient::GetKeyValue() failed to get key '{}' ({})", Key, Result.ErrorMessage(""));
@@ -134,7 +152,10 @@ ConsulClient::GetKeyValue(std::string_view Key)
void
ConsulClient::DeleteKey(std::string_view Key)
{
- HttpClient::Response Result = m_HttpClient.Delete(fmt::format("v1/kv/{}", Key));
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+
+ HttpClient::Response Result = m_HttpClient.Delete(fmt::format("v1/kv/{}", Key), AdditionalHeaders);
if (!Result)
{
throw runtime_error("ConsulClient::DeleteKey() failed to delete key '{}' ({})", Key, Result.ErrorMessage(""));
@@ -146,6 +167,12 @@ ConsulClient::RegisterService(const ServiceRegistrationInfo& Info)
{
using namespace std::literals;
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+ AdditionalHeaders.Entries.emplace(HttpClient::Accept(HttpContentType::kJSON));
+
+ HttpClient::KeyValueMap AdditionalParameters(std::make_pair<std::string, std::string>("replace-existing-checks", "true"));
+
CbObjectWriter Writer;
{
Writer.AddString("ID"sv, Info.ServiceId);
@@ -164,13 +191,23 @@ ConsulClient::RegisterService(const ServiceRegistrationInfo& Info)
}
Writer.EndArray(); // Tags
}
- Writer.BeginObject("Check"sv);
+ if (Info.HealthIntervalSeconds != 0)
{
- Writer.AddString("HTTP"sv, fmt::format("http://{}:{}/{}", Info.Address, Info.Port, Info.HealthEndpoint));
- Writer.AddString("Interval"sv, fmt::format("{}s", Info.HealthIntervalSeconds));
- Writer.AddString("DeregisterCriticalServiceAfter"sv, fmt::format("{}s", Info.DeregisterAfterSeconds));
+ // Consul requires Interval whenever HTTP is specified; omit the Check block entirely
+ // when no interval is configured (e.g. during Provisioning).
+ Writer.BeginObject("Check"sv);
+ {
+ Writer.AddString(
+ "HTTP"sv,
+ fmt::format("http://{}:{}/{}", Info.Address.empty() ? "localhost" : Info.Address, Info.Port, Info.HealthEndpoint));
+ Writer.AddString("Interval"sv, fmt::format("{}s", Info.HealthIntervalSeconds));
+ if (Info.DeregisterAfterSeconds != 0)
+ {
+ Writer.AddString("DeregisterCriticalServiceAfter"sv, fmt::format("{}s", Info.DeregisterAfterSeconds));
+ }
+ }
+ Writer.EndObject(); // Check
}
- Writer.EndObject(); // Check
}
ExtendableStringBuilder<512> SB;
@@ -178,7 +215,7 @@ ConsulClient::RegisterService(const ServiceRegistrationInfo& Info)
IoBuffer PayloadBuffer(IoBuffer::Wrap, SB.Data(), SB.Size());
PayloadBuffer.SetContentType(HttpContentType::kJSON);
- HttpClient::Response Result = m_HttpClient.Put("v1/agent/service/register", PayloadBuffer, HttpClient::Accept(HttpContentType::kJSON));
+ HttpClient::Response Result = m_HttpClient.Put("v1/agent/service/register", PayloadBuffer, AdditionalHeaders, AdditionalParameters);
if (!Result)
{
@@ -192,16 +229,113 @@ ConsulClient::RegisterService(const ServiceRegistrationInfo& Info)
bool
ConsulClient::DeregisterService(std::string_view ServiceId)
{
- HttpClient::Response Result =
- m_HttpClient.Put(fmt::format("v1/agent/service/deregister/{}", ServiceId), HttpClient::Accept(HttpContentType::kJSON));
+ using namespace std::literals;
+
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+ AdditionalHeaders.Entries.emplace(HttpClient::Accept(HttpContentType::kJSON));
+
+ HttpClient::Response Result = m_HttpClient.Put(fmt::format("v1/agent/service/deregister/{}", ServiceId), IoBuffer{}, AdditionalHeaders);
+ if (Result)
+ {
+ return true;
+ }
+
+ // Agent deregister failed — fall back to catalog deregister.
+ // This handles cases where the service was registered via a different Consul agent
+ // (e.g. load-balanced endpoint routing to different agents).
+ std::string NodeName = GetNodeName();
+ if (!NodeName.empty())
+ {
+ CbObjectWriter Writer;
+ Writer.AddString("Node"sv, NodeName);
+ Writer.AddString("ServiceID"sv, ServiceId);
+
+ ExtendableStringBuilder<256> SB;
+ CompactBinaryToJson(Writer.Save(), SB);
+
+ IoBuffer PayloadBuffer(IoBuffer::Wrap, SB.Data(), SB.Size());
+ PayloadBuffer.SetContentType(HttpContentType::kJSON);
+
+ HttpClient::Response CatalogResult = m_HttpClient.Put("v1/catalog/deregister", PayloadBuffer, AdditionalHeaders);
+ if (CatalogResult)
+ {
+ ZEN_INFO("ConsulClient::DeregisterService() deregistered service '{}' via catalog fallback (agent error: {})",
+ ServiceId,
+ Result.ErrorMessage(""));
+ return true;
+ }
+
+ ZEN_WARN("ConsulClient::DeregisterService() failed to deregister service '{}' (agent: {}, catalog: {})",
+ ServiceId,
+ Result.ErrorMessage(""),
+ CatalogResult.ErrorMessage(""));
+ }
+ else
+ {
+ ZEN_WARN(
+ "ConsulClient::DeregisterService() failed to deregister service '{}' (agent: {}, could not determine node name for catalog "
+ "fallback)",
+ ServiceId,
+ Result.ErrorMessage(""));
+ }
+
+ return false;
+}
+
+std::string
+ConsulClient::GetNodeName()
+{
+ using namespace std::literals;
+
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+ HttpClient::Response Result = m_HttpClient.Get("v1/agent/self", AdditionalHeaders);
if (!Result)
{
- ZEN_WARN("ConsulClient::DeregisterService() failed to deregister service '{}' ({})", ServiceId, Result.ErrorMessage(""));
- return false;
+ return {};
}
- return true;
+ std::string JsonError;
+ CbFieldIterator Root = LoadCompactBinaryFromJson(Result.AsText(), JsonError);
+ if (!Root || !JsonError.empty())
+ {
+ return {};
+ }
+
+ for (CbFieldView Field : Root)
+ {
+ if (Field.GetName() == "Config"sv)
+ {
+ CbObjectView Config = Field.AsObjectView();
+ if (Config)
+ {
+ return std::string(Config["NodeName"sv].AsString());
+ }
+ }
+ }
+
+ return {};
+}
+
+void
+ConsulClient::ApplyCommonHeaders(HttpClient::KeyValueMap& InOutHeaderMap)
+{
+ std::string Token;
+ if (!m_Config.StaticToken.empty())
+ {
+ Token = m_Config.StaticToken;
+ }
+ else if (!m_Config.TokenEnvName.empty())
+ {
+ Token = GetEnvVariable(m_Config.TokenEnvName);
+ }
+
+ if (!Token.empty())
+ {
+ InOutHeaderMap.Entries.emplace("X-Consul-Token", Token);
+ }
}
bool
@@ -235,7 +369,10 @@ ConsulClient::FindServiceInJson(std::string_view Json, std::string_view ServiceI
bool
ConsulClient::HasService(std::string_view ServiceId)
{
- HttpClient::Response Result = m_HttpClient.Get("v1/agent/services");
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+
+ HttpClient::Response Result = m_HttpClient.Get("v1/agent/services", AdditionalHeaders);
if (!Result)
{
return false;
@@ -246,10 +383,13 @@ ConsulClient::HasService(std::string_view ServiceId)
bool
ConsulClient::WatchService(std::string_view ServiceId, uint64_t& InOutIndex, int WaitSeconds)
{
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+
// Note: m_HttpClient uses unlimited HTTP timeout (Timeout{0}); the WaitSeconds parameter
// governs the server-side bound on the blocking query. Do not add a separate client timeout.
HttpClient::KeyValueMap Parameters({{"index", std::to_string(InOutIndex)}, {"wait", fmt::format("{}s", WaitSeconds)}});
- HttpClient::Response Result = m_HttpClient.Get("v1/agent/services", {}, Parameters);
+ HttpClient::Response Result = m_HttpClient.Get("v1/agent/services", AdditionalHeaders, Parameters);
if (!Result)
{
return false;
@@ -271,7 +411,24 @@ ConsulClient::WatchService(std::string_view ServiceId, uint64_t& InOutIndex, int
std::string
ConsulClient::GetAgentServicesJson()
{
- HttpClient::Response Result = m_HttpClient.Get("v1/agent/services");
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+
+ HttpClient::Response Result = m_HttpClient.Get("v1/agent/services", AdditionalHeaders);
+ if (!Result)
+ {
+ return "{}";
+ }
+ return Result.ToText();
+}
+
+std::string
+ConsulClient::GetAgentChecksJson()
+{
+ HttpClient::KeyValueMap AdditionalHeaders;
+ ApplyCommonHeaders(AdditionalHeaders);
+
+ HttpClient::Response Result = m_HttpClient.Get("v1/agent/checks", AdditionalHeaders);
if (!Result)
{
return "{}";
@@ -380,4 +537,191 @@ ServiceRegistration::RegistrationLoop()
}
}
+//////////////////////////////////////////////////////////////////////////
+// Tests
+
+#if ZEN_WITH_TESTS
+
+void
+consul_forcelink()
+{
+}
+
+struct MockHealthService : public HttpService
+{
+ std::atomic<bool> FailHealth{false};
+ std::atomic<int> HealthCheckCount{0};
+
+ const char* BaseUri() const override { return "/"; }
+
+ void HandleRequest(HttpServerRequest& Request) override
+ {
+ std::string_view Uri = Request.RelativeUri();
+ if (Uri == "health/" || Uri == "health")
+ {
+ HealthCheckCount.fetch_add(1);
+ if (FailHealth.load())
+ {
+ Request.WriteResponse(HttpResponseCode::ServiceUnavailable);
+ }
+ else
+ {
+ Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, "ok");
+ }
+ return;
+ }
+ Request.WriteResponse(HttpResponseCode::NotFound);
+ }
+};
+
+struct TestHealthServer
+{
+ MockHealthService Mock;
+
+ void Start()
+ {
+ m_TmpDir.emplace();
+ m_Server = CreateHttpServer(HttpServerConfig{.ServerClass = "asio"});
+ m_Port = m_Server->Initialize(0, m_TmpDir->Path() / "http");
+ REQUIRE(m_Port != -1);
+ m_Server->RegisterService(Mock);
+ m_ServerThread = std::thread([this]() { m_Server->Run(false); });
+ }
+
+ int Port() const { return m_Port; }
+
+ ~TestHealthServer()
+ {
+ if (m_Server)
+ {
+ m_Server->RequestExit();
+ }
+ if (m_ServerThread.joinable())
+ {
+ m_ServerThread.join();
+ }
+ if (m_Server)
+ {
+ m_Server->Close();
+ }
+ }
+
+private:
+ std::optional<ScopedTemporaryDirectory> m_TmpDir;
+ Ref<HttpServer> m_Server;
+ std::thread m_ServerThread;
+ int m_Port = -1;
+};
+
+static bool
+WaitForCondition(std::function<bool()> Predicate, int TimeoutMs, int PollIntervalMs = 200)
+{
+ Stopwatch Timer;
+ while (Timer.GetElapsedTimeMs() < static_cast<uint64_t>(TimeoutMs))
+ {
+ if (Predicate())
+ {
+ return true;
+ }
+ Sleep(PollIntervalMs);
+ }
+ return Predicate();
+}
+
+static std::string
+GetCheckStatus(ConsulClient& Client, std::string_view ServiceId)
+{
+ using namespace std::literals;
+
+ std::string JsonError;
+ CbFieldIterator ChecksRoot = LoadCompactBinaryFromJson(Client.GetAgentChecksJson(), JsonError);
+ if (!ChecksRoot || !JsonError.empty())
+ {
+ return {};
+ }
+
+ for (CbFieldView F : ChecksRoot)
+ {
+ if (!F.IsObject())
+ {
+ continue;
+ }
+ for (CbFieldView C : F.AsObjectView())
+ {
+ CbObjectView Check = C.AsObjectView();
+ if (Check["ServiceID"sv].AsString() == ServiceId)
+ {
+ return std::string(Check["Status"sv].AsString());
+ }
+ }
+ }
+ return {};
+}
+
+TEST_SUITE_BEGIN("util.consul");
+
+TEST_CASE("util.consul.service_lifecycle")
+{
+ ConsulProcess ConsulProc;
+ ConsulProc.SpawnConsulAgent();
+
+ TestHealthServer HealthServer;
+ HealthServer.Start();
+
+ ConsulClient Client({.BaseUri = "http://localhost:8500/"});
+
+ const std::string ServiceId = "test-health-svc";
+
+ ServiceRegistrationInfo Info;
+ Info.ServiceId = ServiceId;
+ Info.ServiceName = "zen-test-health";
+ Info.Address = "127.0.0.1";
+ Info.Port = static_cast<uint16_t>(HealthServer.Port());
+ Info.HealthEndpoint = "health/";
+ Info.HealthIntervalSeconds = 1;
+ Info.DeregisterAfterSeconds = 60;
+
+ // Phase 1: Register and verify Consul sends health checks to our service
+ REQUIRE(Client.RegisterService(Info));
+ REQUIRE(Client.HasService(ServiceId));
+
+ REQUIRE(WaitForCondition([&]() { return HealthServer.Mock.HealthCheckCount.load() >= 1; }, 10000));
+ CHECK(HealthServer.Mock.HealthCheckCount.load() >= 1);
+ CHECK_EQ(GetCheckStatus(Client, ServiceId), "passing");
+
+ // Phase 2: Explicit deregister
+ REQUIRE(Client.DeregisterService(ServiceId));
+ CHECK_FALSE(Client.HasService(ServiceId));
+
+ // Phase 3: Register again, verify passing, then fail health and verify check goes critical
+ HealthServer.Mock.HealthCheckCount.store(0);
+ HealthServer.Mock.FailHealth.store(false);
+
+ REQUIRE(Client.RegisterService(Info));
+ REQUIRE(Client.HasService(ServiceId));
+
+ REQUIRE(WaitForCondition([&]() { return HealthServer.Mock.HealthCheckCount.load() >= 1; }, 10000));
+ CHECK_EQ(GetCheckStatus(Client, ServiceId), "passing");
+
+ HealthServer.Mock.FailHealth.store(true);
+
+ // Wait for Consul to observe the failing check
+ REQUIRE(WaitForCondition([&]() { return GetCheckStatus(Client, ServiceId) == "critical"; }, 10000));
+ CHECK_EQ(GetCheckStatus(Client, ServiceId), "critical");
+
+ // Phase 4: Explicit deregister while critical
+ REQUIRE(Client.DeregisterService(ServiceId));
+ CHECK_FALSE(Client.HasService(ServiceId));
+
+ // Phase 5: Deregister an already-deregistered service - should not crash
+ Client.DeregisterService(ServiceId);
+ CHECK_FALSE(Client.HasService(ServiceId));
+
+ ConsulProc.StopConsulAgent();
+}
+
+TEST_SUITE_END();
+
+#endif
+
} // namespace zen::consul
diff --git a/src/zenutil/include/zenutil/cloud/s3client.h b/src/zenutil/include/zenutil/cloud/s3client.h
index 47501c5b5..f1f0df0e4 100644
--- a/src/zenutil/include/zenutil/cloud/s3client.h
+++ b/src/zenutil/include/zenutil/cloud/s3client.h
@@ -11,6 +11,7 @@
#include <zencore/thread.h>
+#include <functional>
#include <string>
#include <string_view>
#include <vector>
@@ -34,9 +35,7 @@ struct S3ClientOptions
/// Overrides the static Credentials field.
Ref<ImdsCredentialProvider> CredentialProvider;
- std::chrono::milliseconds ConnectTimeout{5000};
- std::chrono::milliseconds Timeout{};
- uint8_t RetryCount = 3;
+ HttpClientSettings HttpSettings = {.LogCategory = "s3", .ConnectTimeout = std::chrono::milliseconds(5000), .RetryCount = 3};
};
struct S3ObjectInfo
@@ -63,34 +62,36 @@ enum class HeadObjectResult
Error,
};
-/// Result of GetObject — carries the downloaded content.
+/// Result of GetObject - carries the downloaded content.
struct S3GetObjectResult : S3Result
{
IoBuffer Content;
std::string_view AsText() const { return std::string_view(reinterpret_cast<const char*>(Content.GetData()), Content.GetSize()); }
+
+ static std::string_view NotFoundErrorText;
};
-/// Result of HeadObject — carries object metadata and existence status.
+/// Result of HeadObject - carries object metadata and existence status.
struct S3HeadObjectResult : S3Result
{
S3ObjectInfo Info;
HeadObjectResult Status = HeadObjectResult::NotFound;
};
-/// Result of ListObjects — carries the list of matching objects.
+/// Result of ListObjects - carries the list of matching objects.
struct S3ListObjectsResult : S3Result
{
std::vector<S3ObjectInfo> Objects;
};
-/// Result of CreateMultipartUpload — carries the upload ID.
+/// Result of CreateMultipartUpload - carries the upload ID.
struct S3CreateMultipartUploadResult : S3Result
{
std::string UploadId;
};
-/// Result of UploadPart — carries the part ETag.
+/// Result of UploadPart - carries the part ETag.
struct S3UploadPartResult : S3Result
{
std::string ETag;
@@ -118,7 +119,12 @@ public:
S3Result PutObject(std::string_view Key, IoBuffer Content);
/// Download an object from S3
- S3GetObjectResult GetObject(std::string_view Key);
+ S3GetObjectResult GetObject(std::string_view Key, const std::filesystem::path& TempFilePath = {});
+
+ /// Download a byte range of an object from S3
+ /// @param RangeStart First byte offset (inclusive)
+ /// @param RangeSize Number of bytes to download
+ S3GetObjectResult GetObjectRange(std::string_view Key, uint64_t RangeStart, uint64_t RangeSize);
/// Delete an object from S3
S3Result DeleteObject(std::string_view Key);
@@ -151,6 +157,16 @@ public:
/// @param PartSize Size of each part in bytes (minimum 5 MB, default 8 MB)
S3Result PutObjectMultipart(std::string_view Key, IoBuffer Content, uint64_t PartSize = 8 * 1024 * 1024);
+ /// High-level multipart upload: calls FetchRange(Offset, Size) to read each part on demand,
+ /// avoiding loading the full content into memory.
+ /// @param TotalSize Total object size in bytes
+ /// @param FetchRange Callback invoked once per part; must return exactly Size bytes
+ /// @param PartSize Size of each part in bytes (minimum 5 MB, default 8 MB)
+ S3Result PutObjectMultipart(std::string_view Key,
+ uint64_t TotalSize,
+ std::function<IoBuffer(uint64_t Offset, uint64_t Size)> FetchRange,
+ uint64_t PartSize = 8 * 1024 * 1024);
+
/// Generate a pre-signed URL for downloading an object (GET)
/// @param Key The object key
/// @param ExpiresIn URL validity duration (default 1 hour, max 7 days)
diff --git a/src/zenutil/include/zenutil/config/loggingconfig.h b/src/zenutil/include/zenutil/config/loggingconfig.h
index b55b2d9f7..33a5eb172 100644
--- a/src/zenutil/include/zenutil/config/loggingconfig.h
+++ b/src/zenutil/include/zenutil/config/loggingconfig.h
@@ -16,10 +16,12 @@ struct ZenLoggingConfig
{
bool NoConsoleOutput = false; // Control default use of stdout for diagnostics
bool QuietConsole = false; // Configure console logger output to level WARN
+ bool ForceColor = false; // Force colored output even when stdout is not a terminal
std::filesystem::path AbsLogFile; // Absolute path to main log file
std::string Loggers[logging::LogLevelCount];
- std::string LogId; // Id for tagging log output
- std::string OtelEndpointUri; // OpenTelemetry endpoint URI
+ std::string LogId; // Id for tagging log output
+ std::string OtelEndpointUri; // OpenTelemetry endpoint URI
+ std::string LogStreamEndpoint; // TCP log stream endpoint (host:port)
};
void ApplyLoggingOptions(cxxopts::Options& options, ZenLoggingConfig& LoggingConfig);
diff --git a/src/zenutil/include/zenutil/consul.h b/src/zenutil/include/zenutil/consul.h
index b5bfa42d1..7517ddd1e 100644
--- a/src/zenutil/include/zenutil/consul.h
+++ b/src/zenutil/include/zenutil/consul.h
@@ -21,14 +21,21 @@ struct ServiceRegistrationInfo
uint16_t Port = 0;
std::string HealthEndpoint;
std::vector<std::pair<std::string, std::string>> Tags;
- int HealthIntervalSeconds = 10;
- int DeregisterAfterSeconds = 30;
+ uint32_t HealthIntervalSeconds = 10;
+ uint32_t DeregisterAfterSeconds = 30;
};
class ConsulClient
{
public:
- ConsulClient(std::string_view BaseUri);
+ struct Configuration
+ {
+ std::string BaseUri;
+ std::string StaticToken;
+ std::string TokenEnvName;
+ };
+
+ ConsulClient(const Configuration& Config);
~ConsulClient();
ConsulClient(const ConsulClient&) = delete;
@@ -44,6 +51,7 @@ public:
// Query methods for testing
bool HasService(std::string_view ServiceId);
std::string GetAgentServicesJson();
+ std::string GetAgentChecksJson();
// Blocking query on v1/agent/services. Blocks until the service list changes or
// the wait period expires. InOutIndex must be 0 for the first call; it is updated
@@ -53,8 +61,11 @@ public:
private:
static bool FindServiceInJson(std::string_view Json, std::string_view ServiceId);
+ void ApplyCommonHeaders(HttpClient::KeyValueMap& InOutHeaderMap);
+ std::string GetNodeName();
- HttpClient m_HttpClient;
+ Configuration m_Config;
+ HttpClient m_HttpClient;
};
class ConsulProcess
@@ -106,4 +117,6 @@ private:
void RegistrationLoop();
};
+void consul_forcelink();
+
} // namespace zen::consul
diff --git a/src/zenutil/include/zenutil/logging.h b/src/zenutil/include/zenutil/logging.h
index 95419c274..6abf6a96f 100644
--- a/src/zenutil/include/zenutil/logging.h
+++ b/src/zenutil/include/zenutil/logging.h
@@ -18,6 +18,10 @@
// for sharing across different executables
//
+namespace zen::logging {
+class BroadcastSink;
+}
+
namespace zen {
struct LoggingOptions
@@ -28,7 +32,8 @@ struct LoggingOptions
bool AllowAsync = true;
bool NoConsoleOutput = false;
bool QuietConsole = false;
- std::filesystem::path AbsLogFile; // Absolute path to main log file
+ bool ForceColor = false; // Force colored output even when stdout is not a terminal
+ std::filesystem::path AbsLogFile; // Absolute path to main log file
std::string LogId;
};
@@ -38,6 +43,7 @@ void FinishInitializeLogging(const LoggingOptions& LoggingOptions);
void InitializeLogging(const LoggingOptions& LoggingOptions);
void ShutdownLogging();
-logging::SinkPtr GetFileSink();
+logging::SinkPtr GetFileSink();
+Ref<logging::BroadcastSink> GetDefaultBroadcastSink();
} // namespace zen
diff --git a/src/zenutil/include/zenutil/process/subprocessmanager.h b/src/zenutil/include/zenutil/process/subprocessmanager.h
new file mode 100644
index 000000000..e16c0c446
--- /dev/null
+++ b/src/zenutil/include/zenutil/process/subprocessmanager.h
@@ -0,0 +1,285 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/process.h>
+#include <zencore/zencore.h>
+
+#include <filesystem>
+#include <functional>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace zen {
+
+/** Tracked process entry with latest metrics snapshot.
+ */
+struct TrackedProcessEntry
+{
+ int Pid = 0;
+ ProcessMetrics Metrics;
+
+ // Derived CPU usage percentage (delta-based, requires two samples).
+ // -1.0 means not yet sampled.
+ float CpuUsagePercent = -1.0f;
+};
+
+/** Aggregate metrics across all tracked processes.
+ */
+struct AggregateProcessMetrics
+{
+ uint64_t TotalWorkingSetSize = 0;
+ uint64_t TotalPeakWorkingSetSize = 0;
+ uint64_t TotalUserTimeMs = 0;
+ uint64_t TotalKernelTimeMs = 0;
+ uint32_t ProcessCount = 0;
+};
+
+} // namespace zen
+
+namespace asio {
+class io_context;
+}
+
+namespace zen {
+
+class ManagedProcess;
+class ProcessGroup;
+
+/// Callback invoked when a managed process exits.
+using ProcessExitCallback = std::function<void(ManagedProcess& Process, int ExitCode)>;
+
+/// Callback invoked when data is read from a managed process's stdout or stderr.
+using ProcessDataCallback = std::function<void(ManagedProcess& Process, std::string_view Data)>;
+
+/// Configuration for SubprocessManager.
+struct SubprocessManagerConfig
+{
+ /// Interval for periodic metrics sampling. Set to 0 to disable.
+ uint64_t MetricsSampleIntervalMs = 5000;
+
+ /// Number of processes sampled per metrics tick (round-robin).
+ uint32_t MetricsBatchSize = 16;
+};
+
+/// Manages a set of child processes with async exit detection, stdout/stderr
+/// capture, and periodic metrics sampling.
+///
+/// All callbacks are posted to the io_context and never invoked under internal
+/// locks. The caller must ensure the io_context outlives this manager and that
+/// its run loop is active.
+///
+/// Usage:
+/// asio::io_context IoContext;
+/// SubprocessManager Manager(IoContext);
+///
+/// StdoutPipeHandles StdoutPipe;
+/// CreateStdoutPipe(StdoutPipe);
+///
+/// CreateProcOptions Options;
+/// Options.StdoutPipe = &StdoutPipe;
+///
+/// auto* Proc = Manager.Spawn(Executable, CommandLine, Options,
+/// [](ManagedProcess& P, int Code) { ... });
+class SubprocessManager
+{
+public:
+ explicit SubprocessManager(asio::io_context& IoContext, SubprocessManagerConfig Config = {});
+ ~SubprocessManager();
+
+ SubprocessManager(const SubprocessManager&) = delete;
+ SubprocessManager& operator=(const SubprocessManager&) = delete;
+
+ /// Spawn a new child process and begin monitoring it.
+ ///
+ /// If Options.StdoutPipe is set, the pipe is consumed and async reading
+ /// begins automatically. Similarly for Options.StderrPipe. When providing
+ /// pipes, pass the corresponding data callback here so it is installed
+ /// before the first async read completes — setting it later via
+ /// SetStdoutCallback risks losing early output.
+ ///
+ /// Returns a non-owning pointer valid until Remove() or manager destruction.
+ /// The exit callback fires on an io_context thread when the process terminates.
+ ManagedProcess* Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout = {},
+ ProcessDataCallback OnStderr = {});
+
+ /// Adopt an already-running process by handle. Takes ownership of handle internals.
+ ManagedProcess* Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit);
+
+ /// Stop monitoring a process by pid. Does NOT kill the process — call
+ /// process->Kill() first if needed. The exit callback will not fire after
+ /// this returns.
+ void Remove(int Pid);
+
+ /// Remove all managed processes.
+ void RemoveAll();
+
+ /// Set default stdout callback. Per-process callbacks override this.
+ void SetDefaultStdoutCallback(ProcessDataCallback Callback);
+
+ /// Set default stderr callback. Per-process callbacks override this.
+ void SetDefaultStderrCallback(ProcessDataCallback Callback);
+
+ /// Snapshot of per-process metrics for all managed processes.
+ [[nodiscard]] std::vector<TrackedProcessEntry> GetMetricsSnapshot() const;
+
+ /// Aggregate metrics across all managed processes.
+ [[nodiscard]] AggregateProcessMetrics GetAggregateMetrics() const;
+
+ /// Number of currently managed processes.
+ [[nodiscard]] size_t GetProcessCount() const;
+
+ /// Enumerate all managed processes under a shared lock.
+ void Enumerate(std::function<void(const ManagedProcess&)> Callback) const;
+
+ /// Create a new process group. The group is owned by this manager.
+ /// On Windows the group is backed by a JobObject (kill-on-close guarantee).
+ /// On POSIX the group uses setpgid for bulk signal delivery.
+ ProcessGroup* CreateGroup(std::string Name);
+
+ /// Destroy a group by name. Kills all processes in the group first.
+ void DestroyGroup(std::string_view Name);
+
+ /// Find a group by name. Returns nullptr if not found.
+ [[nodiscard]] ProcessGroup* FindGroup(std::string_view Name) const;
+
+ /// Enumerate all groups.
+ void EnumerateGroups(std::function<void(const ProcessGroup&)> Callback) const;
+
+private:
+ friend class ProcessGroup;
+
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+};
+
+/// A process managed by SubprocessManager.
+///
+/// Not user-constructible. Pointers obtained from Spawn()/Adopt() remain valid
+/// until Remove() or manager destruction.
+class ManagedProcess
+{
+public:
+ ~ManagedProcess();
+
+ ManagedProcess(const ManagedProcess&) = delete;
+ ManagedProcess& operator=(const ManagedProcess&) = delete;
+
+ /// Process id.
+ [[nodiscard]] int Pid() const;
+
+ /// Whether the process is still running.
+ [[nodiscard]] bool IsRunning() const;
+
+ /// Underlying process handle.
+ [[nodiscard]] const ProcessHandle& GetHandle() const;
+
+ /// Most recently sampled metrics (best-effort snapshot).
+ [[nodiscard]] ProcessMetrics GetLatestMetrics() const;
+
+ /// CPU usage percentage from the last two samples. Returns -1.0 if not
+ /// yet computed.
+ [[nodiscard]] float GetCpuUsagePercent() const;
+
+ /// Return all stdout captured so far. When a callback is set, output is
+ /// delivered there instead of being accumulated.
+ [[nodiscard]] std::string GetCapturedStdout() const;
+
+ /// Return all stderr captured so far.
+ [[nodiscard]] std::string GetCapturedStderr() const;
+
+ /// Graceful shutdown with fallback to forced kill.
+ bool Kill();
+
+ /// Immediate forced termination.
+ bool Terminate(int ExitCode);
+
+ /// User-defined tag for identifying this process in callbacks.
+ void SetTag(std::string Tag);
+
+ /// Get the user-defined tag.
+ [[nodiscard]] std::string_view GetTag() const;
+
+private:
+ friend class SubprocessManager;
+ friend class ProcessGroup;
+
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+
+ explicit ManagedProcess(std::unique_ptr<Impl> InImpl);
+};
+
+/// A group of managed processes with OS-level backing.
+///
+/// On Windows: backed by a JobObject. All processes assigned on spawn.
+/// Kill-on-close guarantee — if the group is destroyed, the OS terminates
+/// all member processes.
+/// On Linux/macOS: uses setpgid() so children share a process group.
+/// Enables bulk signal delivery via kill(-pgid, sig).
+///
+/// Created via SubprocessManager::CreateGroup(). Not user-constructible.
+class ProcessGroup
+{
+public:
+ ~ProcessGroup();
+
+ ProcessGroup(const ProcessGroup&) = delete;
+ ProcessGroup& operator=(const ProcessGroup&) = delete;
+
+ /// Group name (as passed to CreateGroup).
+ [[nodiscard]] std::string_view GetName() const;
+
+ /// Spawn a process into this group. See SubprocessManager::Spawn for
+ /// details on the stdout/stderr callback parameters.
+ ManagedProcess* Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout = {},
+ ProcessDataCallback OnStderr = {});
+
+ /// Adopt an already-running process into this group.
+ /// On Windows the process is assigned to the group's JobObject.
+ /// On POSIX the process cannot be moved into a different process group
+ /// after creation, so OS-level grouping is best-effort for adopted processes.
+ ManagedProcess* Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit);
+
+ /// Remove a process from this group. Does NOT kill it.
+ void Remove(int Pid);
+
+ /// Kill all processes in the group.
+ /// On Windows: uses TerminateJobObject for atomic group kill.
+ /// On POSIX: sends SIGTERM then SIGKILL to the process group.
+ void KillAll();
+
+ /// Aggregate metrics for this group's processes.
+ [[nodiscard]] AggregateProcessMetrics GetAggregateMetrics() const;
+
+ /// Per-process metrics snapshot for this group.
+ [[nodiscard]] std::vector<TrackedProcessEntry> GetMetricsSnapshot() const;
+
+ /// Number of processes in this group.
+ [[nodiscard]] size_t GetProcessCount() const;
+
+ /// Enumerate processes in this group.
+ void Enumerate(std::function<void(const ManagedProcess&)> Callback) const;
+
+private:
+ friend class SubprocessManager;
+
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+
+ explicit ProcessGroup(std::unique_ptr<Impl> InImpl);
+};
+
+void subprocessmanager_forcelink(); // internal
+
+} // namespace zen
diff --git a/src/zenutil/include/zenutil/sessionsclient.h b/src/zenutil/include/zenutil/sessionsclient.h
new file mode 100644
index 000000000..aca45e61d
--- /dev/null
+++ b/src/zenutil/include/zenutil/sessionsclient.h
@@ -0,0 +1,65 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/compactbinary.h>
+#include <zencore/logging.h>
+#include <zencore/logging/sink.h>
+
+#include <zencore/uid.h>
+
+#include <memory>
+#include <string>
+
+namespace zen {
+
+class HttpClient;
+
+/// Client for announcing and maintaining a session on a remote zenserver's /sessions/ endpoint.
+/// Follows the same best-effort pattern as ZenComputeServer's coordinator announce.
+class SessionsServiceClient
+{
+public:
+ struct Options
+ {
+ std::string TargetUrl; // Base URL of the target zenserver (e.g. "http://localhost:8558")
+ std::string AppName; // Application name to register
+ std::string Mode; // Server mode (e.g. "Server", "Compute", "Proxy")
+ Oid SessionId = Oid::Zero; // Session ID to register under
+ Oid JobId = Oid::Zero; // Optional job ID
+ };
+
+ explicit SessionsServiceClient(Options Opts);
+ ~SessionsServiceClient();
+
+ SessionsServiceClient(const SessionsServiceClient&) = delete;
+ SessionsServiceClient& operator=(const SessionsServiceClient&) = delete;
+
+ /// POST /sessions/{id} — register or re-announce the session with optional metadata.
+ [[nodiscard]] bool Announce(CbObjectView Metadata = {});
+
+ /// PUT /sessions/{id} — update metadata on an existing session.
+ [[nodiscard]] bool UpdateMetadata(CbObjectView Metadata = {});
+
+ /// DELETE /sessions/{id} — remove the session.
+ [[nodiscard]] bool Remove();
+
+ /// Create a logging sink that forwards log messages to the session's log endpoint.
+ /// The sink batches messages on a background thread and POSTs them periodically.
+ /// The returned sink can be added to any logger via Logger::AddSink().
+ logging::SinkPtr CreateLogSink();
+
+ const Options& GetOptions() const { return m_Options; }
+ const std::string& GetSessionPath() const { return m_SessionPath; }
+
+private:
+ CbObject BuildRequestBody(CbObjectView Metadata) const;
+
+ LoggerRef Log() { return m_Log; }
+ LoggerRef m_Log;
+ Options m_Options;
+ std::string m_SessionPath; // "sessions/<hex>"
+ std::unique_ptr<HttpClient> m_Http;
+};
+
+} // namespace zen
diff --git a/src/zenutil/include/zenutil/splitconsole/logstreamlistener.h b/src/zenutil/include/zenutil/splitconsole/logstreamlistener.h
new file mode 100644
index 000000000..f3b960f51
--- /dev/null
+++ b/src/zenutil/include/zenutil/splitconsole/logstreamlistener.h
@@ -0,0 +1,61 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/zencore.h>
+
+#include <cstdint>
+#include <memory>
+#include <string_view>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <asio/io_context.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+namespace zen {
+
+/// Abstract target for log lines received over a TCP log stream.
+class LogStreamTarget
+{
+public:
+ virtual ~LogStreamTarget() = default;
+
+ /// Called (potentially from any thread) when a log line is received.
+ virtual void AppendLogLine(std::string_view Text) = 0;
+};
+
+/// TCP listener that accepts connections from remote processes streaming log messages.
+/// Each message is a CbObject with fields: "text" (string), "source" (string), "level" (string, optional).
+///
+/// Two modes of operation:
+/// - Owned thread: pass only Target and Port; an internal IO thread is created.
+/// - External io_context: pass an existing asio::io_context; no thread is created,
+/// the caller is responsible for running the io_context.
+class LogStreamListener
+{
+public:
+ /// Start listening with an internal IO thread.
+ LogStreamListener(LogStreamTarget& Target, uint16_t Port = 0);
+
+ /// Start listening on an externally-driven io_context (no thread created).
+ LogStreamListener(LogStreamTarget& Target, asio::io_context& IoContext, uint16_t Port = 0);
+
+ ~LogStreamListener();
+
+ LogStreamListener(const LogStreamListener&) = delete;
+ LogStreamListener& operator=(const LogStreamListener&) = delete;
+
+ /// Returns the actual port the listener is bound to.
+ uint16_t GetPort() const;
+
+ /// Gracefully stop accepting new connections and shut down existing sessions.
+ void Shutdown();
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+};
+
+void logstreamlistener_forcelink();
+
+} // namespace zen
diff --git a/src/zenutil/include/zenutil/splitconsole/tcplogstreamsink.h b/src/zenutil/include/zenutil/splitconsole/tcplogstreamsink.h
new file mode 100644
index 000000000..f4ac5ff22
--- /dev/null
+++ b/src/zenutil/include/zenutil/splitconsole/tcplogstreamsink.h
@@ -0,0 +1,193 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/compactbinarybuilder.h>
+#include <zencore/logging/sink.h>
+#include <zencore/thread.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <EASTL/fixed_vector.h>
+#include <asio.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+#include <atomic>
+#include <condition_variable>
+#include <deque>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace zen {
+
+/// Logging sink that connects to a LogStreamListener via TCP and sends CbObject-framed log messages.
+/// Connection is lazy (on first enqueued message) and silently reconnects on failure.
+/// Messages are serialized on the caller thread and written asynchronously from a dedicated IO thread.
+/// A bounded queue drops the oldest messages on overflow to prevent unbounded memory growth.
+class TcpLogStreamSink : public logging::Sink
+{
+public:
+ TcpLogStreamSink(const std::string& Host, uint16_t Port, std::string Source, uint32_t MaxQueueSize = 4096)
+ : m_Host(Host)
+ , m_Port(Port)
+ , m_Source(std::move(Source))
+ , m_MaxQueueSize(MaxQueueSize)
+ {
+ m_IoThread = std::thread([this]() { IoThreadMain(); });
+ }
+
+ ~TcpLogStreamSink() override
+ {
+ {
+ std::lock_guard<std::mutex> Lock(m_QueueMutex);
+ m_Stopping = true;
+ m_DrainDeadline = std::chrono::steady_clock::now() + std::chrono::seconds(2);
+ }
+ m_QueueCv.notify_one();
+ if (m_IoThread.joinable())
+ {
+ m_IoThread.join();
+ }
+ }
+
+ void Log(const logging::LogMessage& Msg) override
+ {
+ std::string_view Text = Msg.GetPayload();
+
+ // Strip trailing newlines
+ while (!Text.empty() && (Text.back() == '\n' || Text.back() == '\r'))
+ {
+ Text.remove_suffix(1);
+ }
+
+ uint64_t Seq = m_NextSequence.fetch_add(1, std::memory_order_relaxed);
+
+ // Build CbObject with text, source, level, and sequence number fields
+ CbObjectWriter Writer;
+ Writer.AddString("text", Text);
+ Writer.AddString("source", m_Source);
+ Writer.AddString("level", logging::ToStringView(Msg.GetLevel()));
+ Writer.AddInteger("seq", Seq);
+ CbObject Obj = Writer.Save();
+
+ // Enqueue for async write
+ {
+ std::lock_guard<std::mutex> Lock(m_QueueMutex);
+ while (m_Queue.size() >= m_MaxQueueSize)
+ {
+ m_Queue.pop_front();
+ }
+ m_Queue.push_back(std::move(Obj));
+ }
+ m_QueueCv.notify_one();
+ }
+
+ void Flush() override
+ {
+ // Nothing to flush — writes happen asynchronously
+ }
+
+ void SetFormatter(std::unique_ptr<logging::Formatter> /*InFormatter*/) override
+ {
+ // Not used — we output the raw payload directly
+ }
+
+private:
+ void IoThreadMain()
+ {
+ zen::SetCurrentThreadName("TcpLogSink");
+
+ for (;;)
+ {
+ std::deque<CbObject> Batch;
+ {
+ std::unique_lock<std::mutex> Lock(m_QueueMutex);
+ m_QueueCv.wait(Lock, [this]() { return m_Stopping || !m_Queue.empty(); });
+
+ if (m_Stopping && m_Queue.empty())
+ {
+ break;
+ }
+
+ if (m_Stopping && std::chrono::steady_clock::now() >= m_DrainDeadline)
+ {
+ break;
+ }
+
+ Batch.swap(m_Queue);
+ }
+
+ if (!m_Connected && !Connect())
+ {
+ if (m_Stopping)
+ {
+ break; // don't retry during shutdown
+ }
+ continue; // drop batch — will retry on next batch
+ }
+
+ // Build a gathered buffer sequence so the entire batch is written
+ // in a single socket operation (or as few as the OS needs).
+ eastl::fixed_vector<asio::const_buffer, 64> Buffers;
+ Buffers.reserve(Batch.size());
+ for (auto& Obj : Batch)
+ {
+ MemoryView View = Obj.GetView();
+ Buffers.emplace_back(View.GetData(), View.GetSize());
+ }
+
+ asio::error_code Ec;
+ asio::write(m_Socket, Buffers, Ec);
+ if (Ec)
+ {
+ m_Connected = false;
+ }
+ }
+ }
+
+ bool Connect()
+ {
+ try
+ {
+ asio::ip::tcp::resolver Resolver(m_IoContext);
+ auto Endpoints = Resolver.resolve(m_Host, std::to_string(m_Port));
+ asio::connect(m_Socket, Endpoints);
+ m_Connected = true;
+ return true;
+ }
+ catch (const std::exception&)
+ {
+ // Reset the socket for next attempt
+ m_Socket = asio::ip::tcp::socket(m_IoContext);
+ m_Connected = false;
+ return false;
+ }
+ }
+
+ // IO thread state (only accessed from m_IoThread)
+ asio::io_context m_IoContext;
+ asio::ip::tcp::socket m_Socket{m_IoContext};
+ bool m_Connected = false;
+
+ // Configuration (immutable after construction)
+ std::string m_Host;
+ uint16_t m_Port;
+ std::string m_Source;
+ uint32_t m_MaxQueueSize;
+
+ // Sequence counter — incremented atomically by Log() callers.
+ // Gaps in the sequence seen by the receiver indicate dropped messages.
+ std::atomic<uint64_t> m_NextSequence{0};
+
+ // Queue shared between Log() callers and IO thread
+ std::mutex m_QueueMutex;
+ std::condition_variable m_QueueCv;
+ std::deque<CbObject> m_Queue;
+ bool m_Stopping = false;
+ std::chrono::steady_clock::time_point m_DrainDeadline;
+
+ std::thread m_IoThread;
+};
+
+} // namespace zen
diff --git a/src/zenutil/include/zenutil/zenserverprocess.h b/src/zenutil/include/zenutil/zenserverprocess.h
index 101b078e9..d6f66fbea 100644
--- a/src/zenutil/include/zenutil/zenserverprocess.h
+++ b/src/zenutil/include/zenutil/zenserverprocess.h
@@ -12,6 +12,8 @@
#include <filesystem>
#include <functional>
#include <optional>
+#include <stdexcept>
+#include <string>
namespace zen {
@@ -50,7 +52,7 @@ public:
ZenServerEnvironment(EStorageTag, std::filesystem::path ProgramBaseDir);
ZenServerEnvironment(EHubTag,
std::filesystem::path ProgramBaseDir,
- std::filesystem::path TestBaseDir,
+ std::filesystem::path ChildBaseDir,
std::string_view ServerClass = "");
ZenServerEnvironment(ETestTag,
std::filesystem::path ProgramBaseDir,
@@ -64,6 +66,7 @@ public:
std::filesystem::path CreateNewTestDir();
std::filesystem::path CreateChildDir(std::string_view ChildName);
std::filesystem::path ProgramBaseDir() const { return m_ProgramBaseDir; }
+ std::filesystem::path GetChildBaseDir() const { return m_ChildProcessBaseDir; }
std::filesystem::path GetTestRootDir(std::string_view Path);
inline bool IsInitialized() const { return m_IsInitialized; }
inline bool IsTestEnvironment() const { return m_IsTestInstance; }
@@ -115,23 +118,25 @@ struct ZenServerInstance
ZenServerInstance(ZenServerEnvironment& TestEnvironment, ServerMode Mode = ServerMode::kStorageServer);
~ZenServerInstance();
- int Shutdown();
- bool SignalShutdown(std::error_code& OutEc);
- uint16_t WaitUntilReady();
- [[nodiscard]] bool WaitUntilReady(int Timeout);
- [[nodiscard]] bool WaitUntilExited(int Timeout, std::error_code& OutEc);
- void EnableTermination() { m_Terminate = true; }
- void EnableShutdownOnDestroy() { m_ShutdownOnDestroy = true; }
- void DisableShutdownOnDestroy() { m_ShutdownOnDestroy = false; }
- void Detach();
- inline int GetPid() const { return m_Process.Pid(); }
- inline void SetOwnerPid(int Pid) { m_OwnerPid = Pid; }
- void* GetProcessHandle() const { return m_Process.Handle(); }
+ int Shutdown();
+ bool SignalShutdown(std::error_code& OutEc);
+ uint16_t WaitUntilReady();
+ [[nodiscard]] bool WaitUntilReady(int Timeout);
+ [[nodiscard]] bool WaitUntilExited(int Timeout, std::error_code& OutEc);
+ void EnableTermination() { m_Terminate = true; }
+ void EnableShutdownOnDestroy() { m_ShutdownOnDestroy = true; }
+ void DisableShutdownOnDestroy() { m_ShutdownOnDestroy = false; }
+ void Detach();
+ inline int GetPid() const { return m_Process.Pid(); }
+ inline void SetOwnerPid(int Pid) { m_OwnerPid = Pid; }
+ const ProcessHandle& GetProcessHandle() const { return m_Process; }
+
#if ZEN_PLATFORM_WINDOWS
void SetJobObject(JobObject* Job) { m_JobObject = Job; }
#endif
- bool IsRunning();
+ bool IsRunning() const;
bool Terminate();
+ void ResetDeadProcess();
std::string GetLogOutput() const;
inline ServerMode GetServerMode() const { return m_ServerMode; }
@@ -329,4 +334,28 @@ CbObject MakeLockFilePayload(const LockFileInfo& Info);
LockFileInfo ReadLockFilePayload(const CbObject& Payload);
bool ValidateLockFileInfo(const LockFileInfo& Info, std::string& OutReason);
+struct StartupZenServerOptions
+{
+ std::filesystem::path ProgramBaseDir; // empty = auto-resolve from running executable
+ uint16_t Port = 0;
+ bool OpenConsole = false; // open a console window for the server process
+ bool ShowLog = false; // emit captured server log to LogRef on successful start
+ std::string ExtraArgs; // e.g. GlobalOptions.PassthroughCommandLine
+ ZenServerInstance::ServerMode Mode = ZenServerInstance::ServerMode::kStorageServer;
+};
+
+// Returns std::nullopt if a matching server is already running (no action taken); logs instance info via LogRef.
+// Returns 0 if the server was successfully started and is ready.
+// Returns a non-zero exit code if startup failed; the captured server log is emitted via LogRef before returning.
+std::optional<int> StartupZenServer(LoggerRef LogRef, const StartupZenServerOptions& Options);
+
+// Attempts graceful shutdown of a running server entry.
+// First tries ZenServerInstance::SignalShutdown; falls back to
+// ZenServerEntry::SignalShutdownRequest + polling.
+// Returns true on successful shutdown, false if it timed out.
+bool ShutdownZenServer(LoggerRef LogRef,
+ ZenServerState& State,
+ ZenServerState::ZenServerEntry* Entry,
+ const std::filesystem::path& ProgramBaseDir);
+
} // namespace zen
diff --git a/src/zenutil/logging/jsonformatter.cpp b/src/zenutil/logging/jsonformatter.cpp
index 673a03c94..c63ad891e 100644
--- a/src/zenutil/logging/jsonformatter.cpp
+++ b/src/zenutil/logging/jsonformatter.cpp
@@ -19,8 +19,6 @@ static void
WriteEscapedString(MemoryBuffer& Dest, std::string_view Text)
{
// Strip ANSI SGR sequences before escaping so they don't appear in JSON output
- static const auto IsEscapeStart = [](char C) { return C == '\033'; };
-
const char* RangeStart = Text.data();
const char* End = Text.data() + Text.size();
diff --git a/src/zenutil/logging/logging.cpp b/src/zenutil/logging/logging.cpp
index ea2448a42..aa34fc50c 100644
--- a/src/zenutil/logging/logging.cpp
+++ b/src/zenutil/logging/logging.cpp
@@ -8,6 +8,7 @@
#include <zencore/logging.h>
#include <zencore/logging/ansicolorsink.h>
#include <zencore/logging/asyncsink.h>
+#include <zencore/logging/broadcastsink.h>
#include <zencore/logging/logger.h>
#include <zencore/logging/msvcsink.h>
#include <zencore/logging/registry.h>
@@ -23,8 +24,9 @@
namespace zen {
-static bool g_IsLoggingInitialized;
-logging::SinkPtr g_FileSink;
+static bool g_IsLoggingInitialized;
+logging::SinkPtr g_FileSink;
+Ref<logging::BroadcastSink> g_BroadcastSink;
logging::SinkPtr
GetFileSink()
@@ -32,6 +34,12 @@ GetFileSink()
return g_FileSink;
}
+Ref<logging::BroadcastSink>
+GetDefaultBroadcastSink()
+{
+ return g_BroadcastSink;
+}
+
void
InitializeLogging(const LoggingOptions& LogOptions)
{
@@ -47,7 +55,6 @@ BeginInitializeLogging(const LoggingOptions& LogOptions)
ZEN_MEMSCOPE(ELLMTag::Logging);
zen::logging::InitializeLogging();
- zen::logging::EnableVTMode();
// Sinks
@@ -117,8 +124,10 @@ BeginInitializeLogging(const LoggingOptions& LogOptions)
LoggerRef DefaultLogger = zen::logging::Default();
- // Collect sinks into a local vector first so we can optionally wrap them
- std::vector<logging::SinkPtr> Sinks;
+ // Build the broadcast sink — a shared indirection point that all
+ // loggers cloned from the default will share. Adding or removing
+ // a child sink later is immediately visible to every logger.
+ std::vector<logging::SinkPtr> BroadcastChildren;
if (LogOptions.NoConsoleOutput)
{
@@ -126,17 +135,18 @@ BeginInitializeLogging(const LoggingOptions& LogOptions)
}
else
{
- logging::SinkPtr ConsoleSink(new logging::AnsiColorStdoutSink());
+ logging::SinkPtr ConsoleSink(
+ new logging::AnsiColorStdoutSink(LogOptions.ForceColor ? logging::ColorMode::On : logging::ColorMode::Auto));
if (LogOptions.QuietConsole)
{
ConsoleSink->SetLevel(logging::Warn);
}
- Sinks.push_back(ConsoleSink);
+ BroadcastChildren.push_back(ConsoleSink);
}
if (FileSink)
{
- Sinks.push_back(FileSink);
+ BroadcastChildren.push_back(FileSink);
}
#if ZEN_PLATFORM_WINDOWS
@@ -144,21 +154,21 @@ BeginInitializeLogging(const LoggingOptions& LogOptions)
{
logging::SinkPtr DebugSink(new logging::MsvcSink());
DebugSink->SetLevel(logging::Debug);
- Sinks.push_back(DebugSink);
+ BroadcastChildren.push_back(DebugSink);
}
#endif
+ g_BroadcastSink = Ref<logging::BroadcastSink>(new logging::BroadcastSink(std::move(BroadcastChildren)));
+
bool IsAsync = LogOptions.AllowAsync && !LogOptions.IsDebug && !LogOptions.IsTest;
if (IsAsync)
{
- std::vector<logging::SinkPtr> AsyncSinks;
- AsyncSinks.emplace_back(new logging::AsyncSink(std::move(Sinks)));
- DefaultLogger->SetSinks(std::move(AsyncSinks));
+ DefaultLogger->SetSink(logging::SinkPtr(new logging::AsyncSink({logging::SinkPtr(g_BroadcastSink.Get())})));
}
else
{
- DefaultLogger->SetSinks(std::move(Sinks));
+ DefaultLogger->SetSink(logging::SinkPtr(g_BroadcastSink.Get()));
}
static struct : logging::ErrorHandler
@@ -258,7 +268,8 @@ ShutdownLogging()
zen::logging::ShutdownLogging();
- g_FileSink = nullptr;
+ g_FileSink = nullptr;
+ g_BroadcastSink = nullptr;
}
} // namespace zen
diff --git a/src/zenutil/process/asyncpipereader.cpp b/src/zenutil/process/asyncpipereader.cpp
new file mode 100644
index 000000000..2fdcda30d
--- /dev/null
+++ b/src/zenutil/process/asyncpipereader.cpp
@@ -0,0 +1,276 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "asyncpipereader.h"
+
+#include <zencore/logging.h>
+
+#include <array>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+# include <asio/io_context.hpp>
+# include <asio/windows/stream_handle.hpp>
+#else
+# include <fcntl.h>
+# include <unistd.h>
+# include <asio/io_context.hpp>
+# include <asio/posix/stream_descriptor.hpp>
+#endif
+
+ZEN_THIRD_PARTY_INCLUDES_END
+
+namespace zen {
+
+static constexpr size_t kReadBufferSize = 4096;
+
+// ============================================================================
+// POSIX: non-blocking pipe + stream_descriptor
+// ============================================================================
+
+#if !ZEN_PLATFORM_WINDOWS
+
+struct AsyncPipeReader::Impl
+{
+ asio::io_context& m_IoContext;
+ std::unique_ptr<asio::posix::stream_descriptor> m_Descriptor;
+ std::function<void(std::string_view)> m_DataCallback;
+ std::function<void()> m_EofCallback;
+ std::array<char, kReadBufferSize> m_Buffer{};
+
+ explicit Impl(asio::io_context& IoContext) : m_IoContext(IoContext) {}
+
+ ~Impl() { Stop(); }
+
+ void Start(StdoutPipeHandles&& Pipe, std::function<void(std::string_view)> DataCallback, std::function<void()> EofCallback)
+ {
+ m_DataCallback = std::move(DataCallback);
+ m_EofCallback = std::move(EofCallback);
+
+ int Fd = Pipe.ReadFd;
+
+ // Close the write end — child already has it
+ Pipe.CloseWriteEnd();
+
+ // Set non-blocking
+ int Flags = fcntl(Fd, F_GETFL, 0);
+ fcntl(Fd, F_SETFL, Flags | O_NONBLOCK);
+
+ // Take ownership of the fd. Detach it from StdoutPipeHandles so it
+ // doesn't get double-closed.
+ Pipe.ReadFd = -1;
+
+ m_Descriptor = std::make_unique<asio::posix::stream_descriptor>(m_IoContext, Fd);
+ EnqueueRead();
+ }
+
+ void Stop()
+ {
+ if (m_Descriptor)
+ {
+ asio::error_code Ec;
+ m_Descriptor->cancel(Ec);
+ m_Descriptor.reset();
+ }
+ }
+
+ void EnqueueRead()
+ {
+ if (!m_Descriptor)
+ {
+ return;
+ }
+
+ m_Descriptor->async_read_some(asio::buffer(m_Buffer), [this](const asio::error_code& Ec, size_t BytesRead) {
+ if (Ec)
+ {
+ if (Ec != asio::error::operation_aborted && m_EofCallback)
+ {
+ m_EofCallback();
+ }
+ return;
+ }
+
+ if (BytesRead > 0 && m_DataCallback)
+ {
+ m_DataCallback(std::string_view(m_Buffer.data(), BytesRead));
+ }
+
+ EnqueueRead();
+ });
+ }
+};
+
+bool
+CreateOverlappedStdoutPipe(StdoutPipeHandles& OutPipe)
+{
+ // On POSIX, regular pipes work fine with non-blocking I/O
+ return CreateStdoutPipe(OutPipe);
+}
+
+// ============================================================================
+// Windows: overlapped named pipe + asio::windows::stream_handle
+//
+// Anonymous pipes (CreatePipe) do not support overlapped I/O. Instead, we
+// create a named pipe pair with FILE_FLAG_OVERLAPPED on the read (server) end.
+// The write (client) end is inheritable and used as the child's stdout/stderr.
+//
+// Callers must use CreateOverlappedStdoutPipe() instead of CreateStdoutPipe()
+// so the pipe is overlapped from the start. Passing a non-overlapped anonymous
+// pipe to Start() will fail.
+// ============================================================================
+
+#else // ZEN_PLATFORM_WINDOWS
+
+static std::atomic<uint64_t> s_PipeSerial{0};
+
+bool
+CreateOverlappedStdoutPipe(StdoutPipeHandles& OutPipe)
+{
+ // Generate a unique pipe name
+ uint64_t Serial = s_PipeSerial.fetch_add(1);
+ wchar_t PipeName[128];
+ swprintf_s(PipeName,
+ _countof(PipeName),
+ L"\\\\.\\pipe\\zen_async_%u_%llu",
+ GetCurrentProcessId(),
+ static_cast<unsigned long long>(Serial));
+
+ // Create the server (read) end with FILE_FLAG_OVERLAPPED
+ HANDLE ReadHandle = CreateNamedPipeW(PipeName,
+ PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_WAIT,
+ 1, // max instances
+ 0, // out buffer size
+ kReadBufferSize,
+ 0, // default timeout
+ nullptr);
+
+ if (ReadHandle == INVALID_HANDLE_VALUE)
+ {
+ ZEN_WARN("CreateNamedPipeW failed: {}", GetLastError());
+ return false;
+ }
+
+ // The read end should not be inherited by the child
+ SetHandleInformation(ReadHandle, HANDLE_FLAG_INHERIT, 0);
+
+ // Open the client (write) end — inheritable, for the child process
+ SECURITY_ATTRIBUTES Sa;
+ Sa.nLength = sizeof(Sa);
+ Sa.lpSecurityDescriptor = nullptr;
+ Sa.bInheritHandle = TRUE;
+
+ HANDLE WriteHandle = CreateFileW(PipeName,
+ GENERIC_WRITE,
+ 0, // no sharing
+ &Sa, // inheritable
+ OPEN_EXISTING,
+ 0, // no special flags on write end
+ nullptr);
+
+ if (WriteHandle == INVALID_HANDLE_VALUE)
+ {
+ DWORD Err = GetLastError();
+ CloseHandle(ReadHandle);
+ ZEN_WARN("CreateFileW for pipe client end failed: {}", Err);
+ return false;
+ }
+
+ OutPipe.ReadHandle = ReadHandle;
+ OutPipe.WriteHandle = WriteHandle;
+ return true;
+}
+
+struct AsyncPipeReader::Impl
+{
+ asio::io_context& m_IoContext;
+ std::unique_ptr<asio::windows::stream_handle> m_StreamHandle;
+ std::function<void(std::string_view)> m_DataCallback;
+ std::function<void()> m_EofCallback;
+ std::array<char, kReadBufferSize> m_Buffer{};
+
+ explicit Impl(asio::io_context& IoContext) : m_IoContext(IoContext) {}
+
+ ~Impl() { Stop(); }
+
+ void Start(StdoutPipeHandles&& Pipe, std::function<void(std::string_view)> DataCallback, std::function<void()> EofCallback)
+ {
+ m_DataCallback = std::move(DataCallback);
+ m_EofCallback = std::move(EofCallback);
+
+ HANDLE ReadHandle = static_cast<HANDLE>(Pipe.ReadHandle);
+
+ // Close the write end — child already has it
+ Pipe.CloseWriteEnd();
+
+ // Take ownership of the read handle
+ Pipe.ReadHandle = nullptr;
+
+ m_StreamHandle = std::make_unique<asio::windows::stream_handle>(m_IoContext, ReadHandle);
+ EnqueueRead();
+ }
+
+ void Stop()
+ {
+ if (m_StreamHandle)
+ {
+ asio::error_code Ec;
+ m_StreamHandle->cancel(Ec);
+ m_StreamHandle.reset();
+ }
+ }
+
+ void EnqueueRead()
+ {
+ if (!m_StreamHandle)
+ {
+ return;
+ }
+
+ m_StreamHandle->async_read_some(asio::buffer(m_Buffer), [this](const asio::error_code& Ec, size_t BytesRead) {
+ if (Ec)
+ {
+ if (Ec != asio::error::operation_aborted && m_EofCallback)
+ {
+ m_EofCallback();
+ }
+ return;
+ }
+
+ if (BytesRead > 0 && m_DataCallback)
+ {
+ m_DataCallback(std::string_view(m_Buffer.data(), BytesRead));
+ }
+
+ EnqueueRead();
+ });
+ }
+};
+
+#endif
+
+// ============================================================================
+// Common wrapper
+// ============================================================================
+
+AsyncPipeReader::AsyncPipeReader(asio::io_context& IoContext) : m_Impl(std::make_unique<Impl>(IoContext))
+{
+}
+
+AsyncPipeReader::~AsyncPipeReader() = default;
+
+void
+AsyncPipeReader::Start(StdoutPipeHandles&& Pipe, std::function<void(std::string_view)> DataCallback, std::function<void()> EofCallback)
+{
+ m_Impl->Start(std::move(Pipe), std::move(DataCallback), std::move(EofCallback));
+}
+
+void
+AsyncPipeReader::Stop()
+{
+ m_Impl->Stop();
+}
+
+} // namespace zen
diff --git a/src/zenutil/process/asyncpipereader.h b/src/zenutil/process/asyncpipereader.h
new file mode 100644
index 000000000..ad2ff8455
--- /dev/null
+++ b/src/zenutil/process/asyncpipereader.h
@@ -0,0 +1,62 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/process.h>
+#include <zencore/zencore.h>
+
+#include <functional>
+#include <memory>
+#include <string_view>
+
+namespace asio {
+class io_context;
+}
+
+namespace zen {
+
+/// Create an overlapped pipe pair suitable for async I/O on Windows.
+///
+/// Unlike CreateStdoutPipe() (which creates anonymous non-overlapped pipes),
+/// this creates a named pipe with FILE_FLAG_OVERLAPPED on the read end, so it
+/// can be used with asio::windows::stream_handle for fully async reads.
+/// The write end is inheritable and suitable for child process redirection.
+///
+/// On non-Windows platforms this simply delegates to CreateStdoutPipe().
+bool CreateOverlappedStdoutPipe(StdoutPipeHandles& OutPipe);
+
+/// Async pipe reader for capturing child process stdout/stderr.
+///
+/// Takes ownership of a pipe's read end and reads asynchronously:
+/// Linux/macOS: non-blocking fd + asio::posix::stream_descriptor
+/// Windows: overlapped named pipe + asio::windows::stream_handle
+///
+/// On Windows the pipe must have been created with CreateOverlappedStdoutPipe()
+/// for async I/O to work. Pipes from CreateStdoutPipe() will fail.
+///
+/// DataCallback is invoked for each chunk read (on the io_context).
+/// EofCallback is invoked when the pipe closes (child exited or pipe broken).
+class AsyncPipeReader
+{
+public:
+ explicit AsyncPipeReader(asio::io_context& IoContext);
+ ~AsyncPipeReader();
+
+ AsyncPipeReader(const AsyncPipeReader&) = delete;
+ AsyncPipeReader& operator=(const AsyncPipeReader&) = delete;
+
+ /// Take ownership of the pipe read-end and start async reading.
+ /// The write end is closed immediately (caller should have already launched
+ /// the child process). DataCallback receives raw chunks. EofCallback fires
+ /// once when the pipe reaches EOF.
+ void Start(StdoutPipeHandles&& Pipe, std::function<void(std::string_view Data)> DataCallback, std::function<void()> EofCallback);
+
+ /// Stop reading and close the pipe. Callbacks will not fire after this returns.
+ void Stop();
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+};
+
+} // namespace zen
diff --git a/src/zenutil/process/exitwatcher.cpp b/src/zenutil/process/exitwatcher.cpp
new file mode 100644
index 000000000..cef31ebca
--- /dev/null
+++ b/src/zenutil/process/exitwatcher.cpp
@@ -0,0 +1,294 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "exitwatcher.h"
+
+#include <zencore/logging.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+# include <asio/io_context.hpp>
+# include <asio/windows/object_handle.hpp>
+#elif ZEN_PLATFORM_LINUX
+# include <sys/syscall.h>
+# include <sys/wait.h>
+# include <unistd.h>
+# include <asio/io_context.hpp>
+# include <asio/posix/stream_descriptor.hpp>
+
+# ifndef SYS_pidfd_open
+# define SYS_pidfd_open 434 // x86_64
+# endif
+#elif ZEN_PLATFORM_MAC
+# include <sys/event.h>
+# include <sys/wait.h>
+# include <unistd.h>
+# include <asio/io_context.hpp>
+# include <asio/posix/stream_descriptor.hpp>
+#endif
+
+ZEN_THIRD_PARTY_INCLUDES_END
+
+namespace zen {
+
+// ============================================================================
+// Linux: pidfd_open + stream_descriptor
+// ============================================================================
+
+#if ZEN_PLATFORM_LINUX
+
+struct ProcessExitWatcher::Impl
+{
+ asio::io_context& m_IoContext;
+ std::unique_ptr<asio::posix::stream_descriptor> m_Descriptor;
+ int m_PidFd = -1;
+ int m_Pid = 0;
+
+ explicit Impl(asio::io_context& IoContext) : m_IoContext(IoContext) {}
+
+ ~Impl() { Cancel(); }
+
+ void Watch(const ProcessHandle& Handle, std::function<void(int ExitCode)> OnExit)
+ {
+ m_Pid = Handle.Pid();
+
+ // pidfd_open returns an fd that becomes readable when the process exits.
+ // Available since Linux 5.3.
+ m_PidFd = static_cast<int>(syscall(SYS_pidfd_open, m_Pid, 0));
+ if (m_PidFd < 0)
+ {
+ ZEN_WARN("pidfd_open failed for pid {}: {}", m_Pid, strerror(errno));
+ return;
+ }
+
+ m_Descriptor = std::make_unique<asio::posix::stream_descriptor>(m_IoContext, m_PidFd);
+
+ m_Descriptor->async_wait(asio::posix::stream_descriptor::wait_read,
+ [this, Callback = std::move(OnExit)](const asio::error_code& Ec) {
+ if (Ec)
+ {
+ return; // Cancelled or error
+ }
+
+ int ExitCode = -1;
+ int Status = 0;
+ // The pidfd told us the process exited. Reap it with waitpid.
+ if (waitpid(m_Pid, &Status, WNOHANG) > 0)
+ {
+ if (WIFEXITED(Status))
+ {
+ ExitCode = WEXITSTATUS(Status);
+ }
+ else if (WIFSIGNALED(Status))
+ {
+ constexpr int kSignalExitBase = 128;
+ ExitCode = kSignalExitBase + WTERMSIG(Status);
+ }
+ }
+
+ Callback(ExitCode);
+ });
+ }
+
+ void Cancel()
+ {
+ if (m_Descriptor)
+ {
+ asio::error_code Ec;
+ m_Descriptor->cancel(Ec);
+ m_Descriptor.reset();
+ // stream_descriptor closes the fd on destruction, so don't close m_PidFd separately
+ m_PidFd = -1;
+ }
+ else if (m_PidFd >= 0)
+ {
+ close(m_PidFd);
+ m_PidFd = -1;
+ }
+ }
+};
+
+// ============================================================================
+// Windows: object_handle::async_wait
+// ============================================================================
+
+#elif ZEN_PLATFORM_WINDOWS
+
+struct ProcessExitWatcher::Impl
+{
+ asio::io_context& m_IoContext;
+ std::unique_ptr<asio::windows::object_handle> m_ObjectHandle;
+ void* m_DuplicatedHandle = nullptr;
+
+ explicit Impl(asio::io_context& IoContext) : m_IoContext(IoContext) {}
+
+ ~Impl() { Cancel(); }
+
+ void Watch(const ProcessHandle& Handle, std::function<void(int ExitCode)> OnExit)
+ {
+ // Duplicate the process handle so ASIO can take ownership independently
+ HANDLE SourceHandle = static_cast<HANDLE>(Handle.Handle());
+ HANDLE CurrentProcess = GetCurrentProcess();
+ BOOL Success = DuplicateHandle(CurrentProcess,
+ SourceHandle,
+ CurrentProcess,
+ reinterpret_cast<LPHANDLE>(&m_DuplicatedHandle),
+ SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
+ FALSE,
+ 0);
+
+ if (!Success)
+ {
+ ZEN_WARN("DuplicateHandle failed for pid {}: {}", Handle.Pid(), GetLastError());
+ return;
+ }
+
+ // object_handle takes ownership of the handle
+ m_ObjectHandle = std::make_unique<asio::windows::object_handle>(m_IoContext, m_DuplicatedHandle);
+
+ m_ObjectHandle->async_wait([this, DupHandle = m_DuplicatedHandle, Callback = std::move(OnExit)](const asio::error_code& Ec) {
+ if (Ec)
+ {
+ return;
+ }
+
+ DWORD ExitCode = 0;
+ GetExitCodeProcess(static_cast<HANDLE>(DupHandle), &ExitCode);
+ Callback(static_cast<int>(ExitCode));
+ });
+ }
+
+ void Cancel()
+ {
+ if (m_ObjectHandle)
+ {
+ asio::error_code Ec;
+ m_ObjectHandle->cancel(Ec);
+ m_ObjectHandle.reset(); // Closes the duplicated handle
+ m_DuplicatedHandle = nullptr;
+ }
+ else if (m_DuplicatedHandle)
+ {
+ CloseHandle(static_cast<HANDLE>(m_DuplicatedHandle));
+ m_DuplicatedHandle = nullptr;
+ }
+ }
+};
+
+// ============================================================================
+// macOS: kqueue EVFILT_PROC + stream_descriptor
+// ============================================================================
+
+#elif ZEN_PLATFORM_MAC
+
+struct ProcessExitWatcher::Impl
+{
+ asio::io_context& m_IoContext;
+ std::unique_ptr<asio::posix::stream_descriptor> m_Descriptor;
+ int m_KqueueFd = -1;
+ int m_Pid = 0;
+
+ explicit Impl(asio::io_context& IoContext) : m_IoContext(IoContext) {}
+
+ ~Impl() { Cancel(); }
+
+ void Watch(const ProcessHandle& Handle, std::function<void(int ExitCode)> OnExit)
+ {
+ m_Pid = Handle.Pid();
+
+ m_KqueueFd = kqueue();
+ if (m_KqueueFd < 0)
+ {
+ ZEN_WARN("kqueue() failed for pid {}: {}", m_Pid, strerror(errno));
+ return;
+ }
+
+ // Register interest in the process exit event
+ struct kevent Change;
+ EV_SET(&Change, static_cast<uintptr_t>(m_Pid), EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, nullptr);
+
+ if (kevent(m_KqueueFd, &Change, 1, nullptr, 0, nullptr) < 0)
+ {
+ ZEN_WARN("kevent register failed for pid {}: {}", m_Pid, strerror(errno));
+ close(m_KqueueFd);
+ m_KqueueFd = -1;
+ return;
+ }
+
+ m_Descriptor = std::make_unique<asio::posix::stream_descriptor>(m_IoContext, m_KqueueFd);
+
+ m_Descriptor->async_wait(asio::posix::stream_descriptor::wait_read,
+ [this, Callback = std::move(OnExit)](const asio::error_code& Ec) {
+ if (Ec)
+ {
+ return;
+ }
+
+ // Drain the kqueue event
+ struct kevent Event;
+ struct timespec Timeout = {0, 0};
+ kevent(m_KqueueFd, nullptr, 0, &Event, 1, &Timeout);
+
+ int ExitCode = -1;
+ int Status = 0;
+ if (waitpid(m_Pid, &Status, WNOHANG) > 0)
+ {
+ if (WIFEXITED(Status))
+ {
+ ExitCode = WEXITSTATUS(Status);
+ }
+ else if (WIFSIGNALED(Status))
+ {
+ constexpr int kSignalExitBase = 128;
+ ExitCode = kSignalExitBase + WTERMSIG(Status);
+ }
+ }
+
+ Callback(ExitCode);
+ });
+ }
+
+ void Cancel()
+ {
+ if (m_Descriptor)
+ {
+ asio::error_code Ec;
+ m_Descriptor->cancel(Ec);
+ m_Descriptor.reset();
+ // stream_descriptor closes the kqueue fd on destruction
+ m_KqueueFd = -1;
+ }
+ else if (m_KqueueFd >= 0)
+ {
+ close(m_KqueueFd);
+ m_KqueueFd = -1;
+ }
+ }
+};
+
+#endif
+
+// ============================================================================
+// Common wrapper (delegates to Impl)
+// ============================================================================
+
+ProcessExitWatcher::ProcessExitWatcher(asio::io_context& IoContext) : m_Impl(std::make_unique<Impl>(IoContext))
+{
+}
+
+ProcessExitWatcher::~ProcessExitWatcher() = default;
+
+void
+ProcessExitWatcher::Watch(const ProcessHandle& Handle, std::function<void(int ExitCode)> OnExit)
+{
+ m_Impl->Watch(Handle, std::move(OnExit));
+}
+
+void
+ProcessExitWatcher::Cancel()
+{
+ m_Impl->Cancel();
+}
+
+} // namespace zen
diff --git a/src/zenutil/process/exitwatcher.h b/src/zenutil/process/exitwatcher.h
new file mode 100644
index 000000000..24906d7d0
--- /dev/null
+++ b/src/zenutil/process/exitwatcher.h
@@ -0,0 +1,48 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/process.h>
+#include <zencore/zencore.h>
+
+#include <functional>
+#include <memory>
+
+namespace asio {
+class io_context;
+}
+
+namespace zen {
+
+/// Async process exit watcher.
+///
+/// Uses platform-specific mechanisms for scalable, non-polling exit detection:
+/// Linux: pidfd_open() + asio::posix::stream_descriptor
+/// Windows: asio::windows::object_handle
+/// macOS: kqueue EVFILT_PROC/NOTE_EXIT + asio::posix::stream_descriptor
+///
+/// The callback is invoked exactly once when the process exits, posted to the
+/// io_context. Call Cancel() to suppress the callback.
+class ProcessExitWatcher
+{
+public:
+ explicit ProcessExitWatcher(asio::io_context& IoContext);
+ ~ProcessExitWatcher();
+
+ ProcessExitWatcher(const ProcessExitWatcher&) = delete;
+ ProcessExitWatcher& operator=(const ProcessExitWatcher&) = delete;
+
+ /// Begin watching the given process. The callback is posted to the io_context
+ /// when the process exits. Only one Watch() may be active at a time.
+ void Watch(const ProcessHandle& Handle, std::function<void(int ExitCode)> OnExit);
+
+ /// Cancel any outstanding watch. The callback will not be invoked after this
+ /// returns. Safe to call if no watch is active.
+ void Cancel();
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+};
+
+} // namespace zen
diff --git a/src/zenutil/process/subprocessmanager.cpp b/src/zenutil/process/subprocessmanager.cpp
new file mode 100644
index 000000000..e908dd63a
--- /dev/null
+++ b/src/zenutil/process/subprocessmanager.cpp
@@ -0,0 +1,1838 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zenutil/process/subprocessmanager.h>
+
+#include "asyncpipereader.h"
+#include "exitwatcher.h"
+
+#include <zencore/logging.h>
+#include <zencore/thread.h>
+#include <zencore/timer.h>
+#include <zencore/trace.h>
+
+#include <algorithm>
+#include <atomic>
+#include <numeric>
+#include <random>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#if ZEN_PLATFORM_WINDOWS
+# include <zencore/windows.h>
+#else
+# include <csignal>
+#endif
+#include <asio/io_context.hpp>
+#include <asio/steady_timer.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+namespace zen {
+
+// ============================================================================
+// ManagedProcess::Impl
+// ============================================================================
+
+struct ManagedProcess::Impl
+{
+ asio::io_context& m_IoContext;
+ ProcessHandle m_Handle;
+ ProcessExitWatcher m_ExitWatcher;
+ ProcessExitCallback m_ExitCallback;
+ std::atomic<bool> m_Exited{false};
+
+ // Stdout capture
+ std::unique_ptr<AsyncPipeReader> m_StdoutReader;
+ ProcessDataCallback m_StdoutCallback;
+ mutable RwLock m_StdoutLock;
+ std::string m_CapturedStdout;
+
+ // Stderr capture
+ std::unique_ptr<AsyncPipeReader> m_StderrReader;
+ ProcessDataCallback m_StderrCallback;
+ mutable RwLock m_StderrLock;
+ std::string m_CapturedStderr;
+
+ // Metrics
+ ProcessMetrics m_LastMetrics;
+ std::atomic<float> m_CpuUsagePercent{-1.0f};
+ uint64_t m_PrevUserTimeMs = 0;
+ uint64_t m_PrevKernelTimeMs = 0;
+ uint64_t m_PrevSampleTicks = 0;
+
+ // User tag
+ std::string m_Tag;
+
+ explicit Impl(asio::io_context& IoContext) : m_IoContext(IoContext), m_ExitWatcher(IoContext) {}
+
+ void OnStdoutData(ManagedProcess& Self, std::string_view Data)
+ {
+ if (m_StdoutCallback)
+ {
+ m_StdoutCallback(Self, Data);
+ }
+ else
+ {
+ RwLock::ExclusiveLockScope $(m_StdoutLock);
+ m_CapturedStdout.append(Data);
+ }
+ }
+
+ void OnStderrData(ManagedProcess& Self, std::string_view Data)
+ {
+ if (m_StderrCallback)
+ {
+ m_StderrCallback(Self, Data);
+ }
+ else
+ {
+ RwLock::ExclusiveLockScope $(m_StderrLock);
+ m_CapturedStderr.append(Data);
+ }
+ }
+
+ void SampleMetrics()
+ {
+ if (m_Exited.load())
+ {
+ return;
+ }
+
+ ProcessMetrics Metrics;
+ GetProcessMetrics(m_Handle, Metrics);
+
+ uint64_t NowTicks = GetHifreqTimerValue();
+
+ if (m_PrevSampleTicks > 0)
+ {
+ uint64_t ElapsedMs = Stopwatch::GetElapsedTimeMs(NowTicks - m_PrevSampleTicks);
+ uint64_t DeltaCpuTimeMs = (Metrics.UserTimeMs + Metrics.KernelTimeMs) - (m_PrevUserTimeMs + m_PrevKernelTimeMs);
+ if (ElapsedMs > 0)
+ {
+ m_CpuUsagePercent.store(static_cast<float>(static_cast<double>(DeltaCpuTimeMs) / ElapsedMs * 100.0));
+ }
+ }
+
+ m_PrevUserTimeMs = Metrics.UserTimeMs;
+ m_PrevKernelTimeMs = Metrics.KernelTimeMs;
+ m_PrevSampleTicks = NowTicks;
+ m_LastMetrics = Metrics;
+ }
+
+ [[nodiscard]] int Pid() const { return m_Handle.Pid(); }
+
+ [[nodiscard]] bool IsRunning() const { return !m_Exited.load() && m_Handle.IsValid() && m_Handle.IsRunning(); }
+
+ [[nodiscard]] std::string GetCapturedStdout() const
+ {
+ RwLock::SharedLockScope $(m_StdoutLock);
+ return m_CapturedStdout;
+ }
+
+ [[nodiscard]] std::string GetCapturedStderr() const
+ {
+ RwLock::SharedLockScope $(m_StderrLock);
+ return m_CapturedStderr;
+ }
+
+ void CancelAll()
+ {
+ m_ExitWatcher.Cancel();
+ if (m_StdoutReader)
+ {
+ m_StdoutReader->Stop();
+ }
+ if (m_StderrReader)
+ {
+ m_StderrReader->Stop();
+ }
+ }
+};
+
+// ============================================================================
+// ManagedProcess
+// ============================================================================
+
+ManagedProcess::ManagedProcess(std::unique_ptr<Impl> InImpl) : m_Impl(std::move(InImpl))
+{
+}
+
+ManagedProcess::~ManagedProcess()
+{
+ if (m_Impl)
+ {
+ m_Impl->CancelAll();
+ }
+}
+
+int
+ManagedProcess::Pid() const
+{
+ return m_Impl->Pid();
+}
+
+bool
+ManagedProcess::IsRunning() const
+{
+ return m_Impl->IsRunning();
+}
+
+const ProcessHandle&
+ManagedProcess::GetHandle() const
+{
+ return m_Impl->m_Handle;
+}
+
+ProcessMetrics
+ManagedProcess::GetLatestMetrics() const
+{
+ return m_Impl->m_LastMetrics;
+}
+
+float
+ManagedProcess::GetCpuUsagePercent() const
+{
+ return m_Impl->m_CpuUsagePercent.load();
+}
+
+std::string
+ManagedProcess::GetCapturedStdout() const
+{
+ return m_Impl->GetCapturedStdout();
+}
+
+std::string
+ManagedProcess::GetCapturedStderr() const
+{
+ return m_Impl->GetCapturedStderr();
+}
+
+bool
+ManagedProcess::Kill()
+{
+ return m_Impl->m_Handle.Kill();
+}
+
+bool
+ManagedProcess::Terminate(int ExitCode)
+{
+ return m_Impl->m_Handle.Terminate(ExitCode);
+}
+
+void
+ManagedProcess::SetTag(std::string Tag)
+{
+ m_Impl->m_Tag = std::move(Tag);
+}
+
+std::string_view
+ManagedProcess::GetTag() const
+{
+ return m_Impl->m_Tag;
+}
+
+// ============================================================================
+// SubprocessManager::Impl
+// ============================================================================
+
+struct SubprocessManager::Impl
+{
+ asio::io_context& m_IoContext;
+ SubprocessManagerConfig m_Config;
+
+ // Ungrouped processes
+ mutable RwLock m_Lock;
+ std::unordered_map<int, std::unique_ptr<ManagedProcess>> m_Processes;
+
+ // Groups
+ mutable RwLock m_GroupsLock;
+ std::unordered_map<std::string, std::unique_ptr<ProcessGroup>> m_Groups;
+
+ // Cross-group metrics index: all pids (grouped + ungrouped) for round-robin sampling
+ mutable RwLock m_MetricsLock;
+ std::unordered_map<int, ManagedProcess*> m_AllProcesses; // non-owning
+ std::vector<int> m_KeyOrder;
+ size_t m_NextSampleIndex = 0;
+
+ ProcessDataCallback m_DefaultStdoutCallback;
+ ProcessDataCallback m_DefaultStderrCallback;
+
+ std::unique_ptr<asio::steady_timer> m_MetricsTimer;
+ std::atomic<bool> m_Running{true};
+
+ explicit Impl(asio::io_context& IoContext, SubprocessManagerConfig Config);
+ ~Impl();
+
+ ManagedProcess* AddProcess(std::unique_ptr<ManagedProcess> Process);
+ void RegisterForMetrics(int Pid, ManagedProcess* Ptr);
+ void UnregisterFromMetrics(int Pid);
+ ManagedProcess* FindProcess(int Pid) const;
+
+ void SetupExitWatcher(ManagedProcess* Proc, ProcessExitCallback OnExit);
+ void SetupStdoutReader(ManagedProcess* Proc, StdoutPipeHandles&& Pipe);
+ void SetupStderrReader(ManagedProcess* Proc, StdoutPipeHandles&& Pipe);
+
+ ManagedProcess* Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout,
+ ProcessDataCallback OnStderr);
+ ManagedProcess* Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit);
+ void Remove(int Pid);
+ void RemoveAll();
+
+ void SetDefaultStdoutCallback(ProcessDataCallback Callback) { m_DefaultStdoutCallback = std::move(Callback); }
+ void SetDefaultStderrCallback(ProcessDataCallback Callback) { m_DefaultStderrCallback = std::move(Callback); }
+
+ void EnqueueMetricsTimer();
+ void SampleBatch();
+ std::vector<TrackedProcessEntry> GetMetricsSnapshot() const;
+ AggregateProcessMetrics GetAggregateMetrics() const;
+ [[nodiscard]] size_t GetProcessCount() const;
+ void Enumerate(std::function<void(const ManagedProcess&)> Callback) const;
+
+ ProcessGroup* CreateGroup(std::string Name);
+ void DestroyGroup(std::string_view Name);
+ ProcessGroup* FindGroup(std::string_view Name) const;
+ void EnumerateGroups(std::function<void(const ProcessGroup&)> Callback) const;
+};
+
+// ============================================================================
+// SubprocessManager::Impl method definitions
+// ============================================================================
+
+SubprocessManager::Impl::Impl(asio::io_context& IoContext, SubprocessManagerConfig Config) : m_IoContext(IoContext), m_Config(Config)
+{
+ if (m_Config.MetricsSampleIntervalMs > 0)
+ {
+ m_MetricsTimer = std::make_unique<asio::steady_timer>(IoContext);
+ EnqueueMetricsTimer();
+ }
+}
+
+SubprocessManager::Impl::~Impl()
+{
+ m_Running = false;
+ if (m_MetricsTimer)
+ {
+ m_MetricsTimer->cancel();
+ }
+
+ // Destroy groups first (they reference m_Manager back to us)
+ {
+ RwLock::ExclusiveLockScope $(m_GroupsLock);
+ m_Groups.clear();
+ }
+
+ RemoveAll();
+}
+
+ManagedProcess*
+SubprocessManager::Impl::AddProcess(std::unique_ptr<ManagedProcess> Process)
+{
+ int Pid = Process->Pid();
+ ManagedProcess* Ptr = Process.get();
+
+ {
+ RwLock::ExclusiveLockScope $(m_Lock);
+ m_Processes[Pid] = std::move(Process);
+ }
+
+ RegisterForMetrics(Pid, Ptr);
+ return Ptr;
+}
+
+void
+SubprocessManager::Impl::RegisterForMetrics(int Pid, ManagedProcess* Ptr)
+{
+ RwLock::ExclusiveLockScope $(m_MetricsLock);
+ m_AllProcesses[Pid] = Ptr;
+ m_KeyOrder.push_back(Pid);
+}
+
+void
+SubprocessManager::Impl::UnregisterFromMetrics(int Pid)
+{
+ RwLock::ExclusiveLockScope $(m_MetricsLock);
+ m_AllProcesses.erase(Pid);
+ m_KeyOrder.erase(std::remove(m_KeyOrder.begin(), m_KeyOrder.end(), Pid), m_KeyOrder.end());
+ if (m_NextSampleIndex >= m_KeyOrder.size())
+ {
+ m_NextSampleIndex = 0;
+ }
+}
+
+ManagedProcess*
+SubprocessManager::Impl::FindProcess(int Pid) const
+{
+ RwLock::SharedLockScope $(m_MetricsLock);
+ auto It = m_AllProcesses.find(Pid);
+ if (It != m_AllProcesses.end())
+ {
+ return It->second;
+ }
+ return nullptr;
+}
+
+void
+SubprocessManager::Impl::SetupExitWatcher(ManagedProcess* Proc, ProcessExitCallback OnExit)
+{
+ int Pid = Proc->Pid();
+
+ Proc->m_Impl->m_ExitWatcher.Watch(Proc->m_Impl->m_Handle, [this, Pid, Callback = std::move(OnExit)](int ExitCode) {
+ ManagedProcess* Found = FindProcess(Pid);
+
+ if (Found)
+ {
+ Found->m_Impl->m_Exited.store(true);
+ Callback(*Found, ExitCode);
+ }
+ });
+}
+
+void
+SubprocessManager::Impl::SetupStdoutReader(ManagedProcess* Proc, StdoutPipeHandles&& Pipe)
+{
+ int Pid = Proc->Pid();
+ Proc->m_Impl->m_StdoutReader = std::make_unique<AsyncPipeReader>(m_IoContext);
+ Proc->m_Impl->m_StdoutReader->Start(
+ std::move(Pipe),
+ [this, Pid](std::string_view Data) {
+ ManagedProcess* Found = FindProcess(Pid);
+ if (Found)
+ {
+ if (Found->m_Impl->m_StdoutCallback)
+ {
+ Found->m_Impl->m_StdoutCallback(*Found, Data);
+ }
+ else if (m_DefaultStdoutCallback)
+ {
+ m_DefaultStdoutCallback(*Found, Data);
+ }
+ else
+ {
+ Found->m_Impl->OnStdoutData(*Found, Data);
+ }
+ }
+ },
+ [] {});
+}
+
+void
+SubprocessManager::Impl::SetupStderrReader(ManagedProcess* Proc, StdoutPipeHandles&& Pipe)
+{
+ int Pid = Proc->Pid();
+ Proc->m_Impl->m_StderrReader = std::make_unique<AsyncPipeReader>(m_IoContext);
+ Proc->m_Impl->m_StderrReader->Start(
+ std::move(Pipe),
+ [this, Pid](std::string_view Data) {
+ ManagedProcess* Found = FindProcess(Pid);
+ if (Found)
+ {
+ if (Found->m_Impl->m_StderrCallback)
+ {
+ Found->m_Impl->m_StderrCallback(*Found, Data);
+ }
+ else if (m_DefaultStderrCallback)
+ {
+ m_DefaultStderrCallback(*Found, Data);
+ }
+ else
+ {
+ Found->m_Impl->OnStderrData(*Found, Data);
+ }
+ }
+ },
+ [] {});
+}
+
+ManagedProcess*
+SubprocessManager::Impl::Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout,
+ ProcessDataCallback OnStderr)
+{
+ bool HasStdout = Options.StdoutPipe != nullptr;
+ bool HasStderr = Options.StderrPipe != nullptr;
+
+ CreateProcResult Result = CreateProc(Executable, CommandLine, Options);
+
+ auto ImplPtr = std::make_unique<ManagedProcess::Impl>(m_IoContext);
+#if ZEN_PLATFORM_WINDOWS
+ ImplPtr->m_Handle.Initialize(Result);
+#else
+ ImplPtr->m_Handle.Initialize(static_cast<int>(Result));
+#endif
+
+ // Install callbacks before starting async readers so no data is missed.
+ if (OnStdout)
+ {
+ ImplPtr->m_StdoutCallback = std::move(OnStdout);
+ }
+ if (OnStderr)
+ {
+ ImplPtr->m_StderrCallback = std::move(OnStderr);
+ }
+
+ auto Proc = std::unique_ptr<ManagedProcess>(new ManagedProcess(std::move(ImplPtr)));
+
+ ManagedProcess* Ptr = AddProcess(std::move(Proc));
+ SetupExitWatcher(Ptr, std::move(OnExit));
+
+ if (HasStdout)
+ {
+ SetupStdoutReader(Ptr, std::move(*Options.StdoutPipe));
+ }
+ if (HasStderr)
+ {
+ SetupStderrReader(Ptr, std::move(*Options.StderrPipe));
+ }
+
+ return Ptr;
+}
+
+ManagedProcess*
+SubprocessManager::Impl::Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit)
+{
+ int Pid = Handle.Pid();
+
+ auto ImplPtr = std::make_unique<ManagedProcess::Impl>(m_IoContext);
+ ImplPtr->m_Handle.Initialize(Pid);
+
+ // Reset the original handle so caller doesn't double-close
+ Handle.Reset();
+
+ auto Proc = std::unique_ptr<ManagedProcess>(new ManagedProcess(std::move(ImplPtr)));
+
+ ManagedProcess* Ptr = AddProcess(std::move(Proc));
+ SetupExitWatcher(Ptr, std::move(OnExit));
+
+ return Ptr;
+}
+
+void
+SubprocessManager::Impl::Remove(int Pid)
+{
+ UnregisterFromMetrics(Pid);
+
+ RwLock::ExclusiveLockScope $(m_Lock);
+ auto It = m_Processes.find(Pid);
+ if (It != m_Processes.end())
+ {
+ It->second->m_Impl->CancelAll();
+ m_Processes.erase(It);
+ }
+}
+
+void
+SubprocessManager::Impl::RemoveAll()
+{
+ {
+ RwLock::ExclusiveLockScope $(m_Lock);
+ for (auto& [Pid, Proc] : m_Processes)
+ {
+ Proc->m_Impl->CancelAll();
+ }
+ m_Processes.clear();
+ }
+
+ {
+ RwLock::ExclusiveLockScope $(m_MetricsLock);
+ m_AllProcesses.clear();
+ m_KeyOrder.clear();
+ m_NextSampleIndex = 0;
+ }
+}
+
+void
+SubprocessManager::Impl::EnqueueMetricsTimer()
+{
+ if (!m_MetricsTimer || !m_Running.load())
+ {
+ return;
+ }
+
+ m_MetricsTimer->expires_after(std::chrono::milliseconds(m_Config.MetricsSampleIntervalMs));
+ m_MetricsTimer->async_wait([this](const asio::error_code& Ec) {
+ if (Ec || !m_Running.load())
+ {
+ return;
+ }
+
+ SampleBatch();
+ EnqueueMetricsTimer();
+ });
+}
+
+void
+SubprocessManager::Impl::SampleBatch()
+{
+ RwLock::SharedLockScope $(m_MetricsLock);
+
+ if (m_KeyOrder.empty())
+ {
+ return;
+ }
+
+ size_t Remaining = std::min(static_cast<size_t>(m_Config.MetricsBatchSize), m_KeyOrder.size());
+
+ while (Remaining > 0)
+ {
+ if (m_NextSampleIndex >= m_KeyOrder.size())
+ {
+ m_NextSampleIndex = 0;
+ }
+
+ int Pid = m_KeyOrder[m_NextSampleIndex];
+ auto It = m_AllProcesses.find(Pid);
+
+ if (It != m_AllProcesses.end())
+ {
+ It->second->m_Impl->SampleMetrics();
+ }
+
+ m_NextSampleIndex++;
+ Remaining--;
+ }
+}
+
+std::vector<TrackedProcessEntry>
+SubprocessManager::Impl::GetMetricsSnapshot() const
+{
+ std::vector<TrackedProcessEntry> Result;
+
+ RwLock::SharedLockScope $(m_MetricsLock);
+ Result.reserve(m_AllProcesses.size());
+
+ for (const auto& [Pid, Proc] : m_AllProcesses)
+ {
+ TrackedProcessEntry Entry;
+ Entry.Pid = Pid;
+ Entry.Metrics = Proc->m_Impl->m_LastMetrics;
+ Entry.CpuUsagePercent = Proc->m_Impl->m_CpuUsagePercent.load();
+ Result.push_back(std::move(Entry));
+ }
+
+ return Result;
+}
+
+AggregateProcessMetrics
+SubprocessManager::Impl::GetAggregateMetrics() const
+{
+ AggregateProcessMetrics Agg;
+
+ RwLock::SharedLockScope $(m_MetricsLock);
+
+ for (const auto& [Pid, Proc] : m_AllProcesses)
+ {
+ const ProcessMetrics& M = Proc->m_Impl->m_LastMetrics;
+ Agg.TotalWorkingSetSize += M.WorkingSetSize;
+ Agg.TotalPeakWorkingSetSize += M.PeakWorkingSetSize;
+ Agg.TotalUserTimeMs += M.UserTimeMs;
+ Agg.TotalKernelTimeMs += M.KernelTimeMs;
+ Agg.ProcessCount++;
+ }
+
+ return Agg;
+}
+
+size_t
+SubprocessManager::Impl::GetProcessCount() const
+{
+ RwLock::SharedLockScope $(m_MetricsLock);
+ return m_AllProcesses.size();
+}
+
+void
+SubprocessManager::Impl::Enumerate(std::function<void(const ManagedProcess&)> Callback) const
+{
+ RwLock::SharedLockScope $(m_MetricsLock);
+ for (const auto& [Pid, Proc] : m_AllProcesses)
+ {
+ Callback(*Proc);
+ }
+}
+
+ProcessGroup*
+SubprocessManager::Impl::CreateGroup(std::string Name)
+{
+ auto GroupImpl = std::make_unique<ProcessGroup::Impl>(std::move(Name), *this, m_IoContext);
+ ProcessGroup* Ptr = nullptr;
+
+ auto Group = std::unique_ptr<ProcessGroup>(new ProcessGroup(std::move(GroupImpl)));
+ Ptr = Group.get();
+
+ RwLock::ExclusiveLockScope $(m_GroupsLock);
+ m_Groups[std::string(Ptr->GetName())] = std::move(Group);
+
+ return Ptr;
+}
+
+void
+SubprocessManager::Impl::DestroyGroup(std::string_view Name)
+{
+ RwLock::ExclusiveLockScope $(m_GroupsLock);
+ auto It = m_Groups.find(std::string(Name));
+ if (It != m_Groups.end())
+ {
+ It->second->KillAll();
+ m_Groups.erase(It);
+ }
+}
+
+ProcessGroup*
+SubprocessManager::Impl::FindGroup(std::string_view Name) const
+{
+ RwLock::SharedLockScope $(m_GroupsLock);
+ auto It = m_Groups.find(std::string(Name));
+ if (It != m_Groups.end())
+ {
+ return It->second.get();
+ }
+ return nullptr;
+}
+
+void
+SubprocessManager::Impl::EnumerateGroups(std::function<void(const ProcessGroup&)> Callback) const
+{
+ RwLock::SharedLockScope $(m_GroupsLock);
+ for (const auto& [Name, Group] : m_Groups)
+ {
+ Callback(*Group);
+ }
+}
+
+// ============================================================================
+// SubprocessManager
+// ============================================================================
+
+SubprocessManager::SubprocessManager(asio::io_context& IoContext, SubprocessManagerConfig Config)
+: m_Impl(std::make_unique<Impl>(IoContext, Config))
+{
+}
+
+SubprocessManager::~SubprocessManager() = default;
+
+ManagedProcess*
+SubprocessManager::Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout,
+ ProcessDataCallback OnStderr)
+{
+ ZEN_TRACE_CPU("SubprocessManager::Spawn");
+ return m_Impl->Spawn(Executable, CommandLine, Options, std::move(OnExit), std::move(OnStdout), std::move(OnStderr));
+}
+
+ManagedProcess*
+SubprocessManager::Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit)
+{
+ ZEN_TRACE_CPU("SubprocessManager::Adopt");
+ return m_Impl->Adopt(std::move(Handle), std::move(OnExit));
+}
+
+void
+SubprocessManager::Remove(int Pid)
+{
+ ZEN_TRACE_CPU("SubprocessManager::Remove");
+ m_Impl->Remove(Pid);
+}
+
+void
+SubprocessManager::RemoveAll()
+{
+ ZEN_TRACE_CPU("SubprocessManager::RemoveAll");
+ m_Impl->RemoveAll();
+}
+
+void
+SubprocessManager::SetDefaultStdoutCallback(ProcessDataCallback Callback)
+{
+ m_Impl->SetDefaultStdoutCallback(std::move(Callback));
+}
+
+void
+SubprocessManager::SetDefaultStderrCallback(ProcessDataCallback Callback)
+{
+ m_Impl->SetDefaultStderrCallback(std::move(Callback));
+}
+
+std::vector<TrackedProcessEntry>
+SubprocessManager::GetMetricsSnapshot() const
+{
+ return m_Impl->GetMetricsSnapshot();
+}
+
+AggregateProcessMetrics
+SubprocessManager::GetAggregateMetrics() const
+{
+ return m_Impl->GetAggregateMetrics();
+}
+
+size_t
+SubprocessManager::GetProcessCount() const
+{
+ return m_Impl->GetProcessCount();
+}
+
+void
+SubprocessManager::Enumerate(std::function<void(const ManagedProcess&)> Callback) const
+{
+ m_Impl->Enumerate(std::move(Callback));
+}
+
+ProcessGroup*
+SubprocessManager::CreateGroup(std::string Name)
+{
+ ZEN_TRACE_CPU("SubprocessManager::CreateGroup");
+ return m_Impl->CreateGroup(std::move(Name));
+}
+
+void
+SubprocessManager::DestroyGroup(std::string_view Name)
+{
+ ZEN_TRACE_CPU("SubprocessManager::DestroyGroup");
+ m_Impl->DestroyGroup(Name);
+}
+
+ProcessGroup*
+SubprocessManager::FindGroup(std::string_view Name) const
+{
+ return m_Impl->FindGroup(Name);
+}
+
+void
+SubprocessManager::EnumerateGroups(std::function<void(const ProcessGroup&)> Callback) const
+{
+ m_Impl->EnumerateGroups(std::move(Callback));
+}
+
+// ============================================================================
+// ProcessGroup::Impl
+// ============================================================================
+
+struct ProcessGroup::Impl
+{
+ std::string m_Name;
+ SubprocessManager::Impl& m_Manager;
+ asio::io_context& m_IoContext;
+
+ mutable RwLock m_Lock;
+ std::unordered_map<int, std::unique_ptr<ManagedProcess>> m_Processes;
+
+#if ZEN_PLATFORM_WINDOWS
+ JobObject m_JobObject;
+#else
+ int m_Pgid = 0;
+#endif
+
+ Impl(std::string Name, SubprocessManager::Impl& Manager, asio::io_context& IoContext);
+ ~Impl();
+
+ ManagedProcess* AddProcess(std::unique_ptr<ManagedProcess> Process);
+
+ ManagedProcess* Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout,
+ ProcessDataCallback OnStderr);
+ ManagedProcess* Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit);
+ void Remove(int Pid);
+ void KillAll();
+
+ AggregateProcessMetrics GetAggregateMetrics() const;
+ std::vector<TrackedProcessEntry> GetMetricsSnapshot() const;
+ [[nodiscard]] size_t GetProcessCount() const;
+ void Enumerate(std::function<void(const ManagedProcess&)> Callback) const;
+};
+
+// ============================================================================
+// ProcessGroup::Impl method definitions
+// ============================================================================
+
+ProcessGroup::Impl::Impl(std::string Name, SubprocessManager::Impl& Manager, asio::io_context& IoContext)
+: m_Name(std::move(Name))
+, m_Manager(Manager)
+, m_IoContext(IoContext)
+{
+#if ZEN_PLATFORM_WINDOWS
+ m_JobObject.Initialize();
+#endif
+}
+
+ProcessGroup::Impl::~Impl()
+{
+ KillAll();
+}
+
+ManagedProcess*
+ProcessGroup::Impl::AddProcess(std::unique_ptr<ManagedProcess> Process)
+{
+ int Pid = Process->Pid();
+ ManagedProcess* Ptr = Process.get();
+
+ {
+ RwLock::ExclusiveLockScope $(m_Lock);
+ m_Processes[Pid] = std::move(Process);
+ }
+
+ m_Manager.RegisterForMetrics(Pid, Ptr);
+ return Ptr;
+}
+
+ManagedProcess*
+ProcessGroup::Impl::Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout,
+ ProcessDataCallback OnStderr)
+{
+ bool HasStdout = Options.StdoutPipe != nullptr;
+ bool HasStderr = Options.StderrPipe != nullptr;
+
+#if ZEN_PLATFORM_WINDOWS
+ if (m_JobObject.IsValid())
+ {
+ Options.AssignToJob = &m_JobObject;
+ }
+#else
+ if (m_Pgid == 0)
+ {
+ Options.Flags |= CreateProcOptions::Flag_NewProcessGroup;
+ }
+ else
+ {
+ Options.ProcessGroupId = m_Pgid;
+ }
+#endif
+
+ CreateProcResult Result = CreateProc(Executable, CommandLine, Options);
+
+ auto ImplPtr = std::make_unique<ManagedProcess::Impl>(m_IoContext);
+#if ZEN_PLATFORM_WINDOWS
+ ImplPtr->m_Handle.Initialize(Result);
+#else
+ int Pid = static_cast<int>(Result);
+ ImplPtr->m_Handle.Initialize(Pid);
+
+ // First process becomes the group leader
+ if (m_Pgid == 0)
+ {
+ m_Pgid = Pid;
+ }
+#endif
+
+ // Install callbacks before starting async readers so no data is missed.
+ if (OnStdout)
+ {
+ ImplPtr->m_StdoutCallback = std::move(OnStdout);
+ }
+ if (OnStderr)
+ {
+ ImplPtr->m_StderrCallback = std::move(OnStderr);
+ }
+
+ auto Proc = std::unique_ptr<ManagedProcess>(new ManagedProcess(std::move(ImplPtr)));
+
+ ManagedProcess* Ptr = AddProcess(std::move(Proc));
+ m_Manager.SetupExitWatcher(Ptr, std::move(OnExit));
+
+ if (HasStdout)
+ {
+ m_Manager.SetupStdoutReader(Ptr, std::move(*Options.StdoutPipe));
+ }
+ if (HasStderr)
+ {
+ m_Manager.SetupStderrReader(Ptr, std::move(*Options.StderrPipe));
+ }
+
+ return Ptr;
+}
+
+ManagedProcess*
+ProcessGroup::Impl::Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit)
+{
+ int Pid = Handle.Pid();
+
+ auto ImplPtr = std::make_unique<ManagedProcess::Impl>(m_IoContext);
+ ImplPtr->m_Handle.Initialize(Pid);
+ Handle.Reset();
+
+#if ZEN_PLATFORM_WINDOWS
+ if (m_JobObject.IsValid())
+ {
+ m_JobObject.AssignProcess(ImplPtr->m_Handle.Handle());
+ }
+#endif
+
+ auto Proc = std::unique_ptr<ManagedProcess>(new ManagedProcess(std::move(ImplPtr)));
+
+ ManagedProcess* Ptr = AddProcess(std::move(Proc));
+ m_Manager.SetupExitWatcher(Ptr, std::move(OnExit));
+
+ return Ptr;
+}
+
+void
+ProcessGroup::Impl::Remove(int Pid)
+{
+ m_Manager.UnregisterFromMetrics(Pid);
+
+ RwLock::ExclusiveLockScope $(m_Lock);
+ auto It = m_Processes.find(Pid);
+ if (It != m_Processes.end())
+ {
+ It->second->m_Impl->CancelAll();
+ m_Processes.erase(It);
+ }
+}
+
+void
+ProcessGroup::Impl::KillAll()
+{
+#if ZEN_PLATFORM_WINDOWS
+ if (m_JobObject.IsValid())
+ {
+ TerminateJobObject(static_cast<HANDLE>(m_JobObject.Handle()), 1);
+ }
+#else
+ if (m_Pgid > 0)
+ {
+ kill(-m_Pgid, SIGTERM);
+ }
+#endif
+ // Also kill individually as fallback and clean up
+ RwLock::ExclusiveLockScope $(m_Lock);
+ for (auto& [Pid, Proc] : m_Processes)
+ {
+ if (Proc->IsRunning())
+ {
+ Proc->Kill();
+ }
+ m_Manager.UnregisterFromMetrics(Pid);
+ Proc->m_Impl->CancelAll();
+ }
+ m_Processes.clear();
+}
+
+AggregateProcessMetrics
+ProcessGroup::Impl::GetAggregateMetrics() const
+{
+ AggregateProcessMetrics Agg;
+
+ RwLock::SharedLockScope $(m_Lock);
+
+ for (const auto& [Pid, Proc] : m_Processes)
+ {
+ const ProcessMetrics& M = Proc->m_Impl->m_LastMetrics;
+ Agg.TotalWorkingSetSize += M.WorkingSetSize;
+ Agg.TotalPeakWorkingSetSize += M.PeakWorkingSetSize;
+ Agg.TotalUserTimeMs += M.UserTimeMs;
+ Agg.TotalKernelTimeMs += M.KernelTimeMs;
+ Agg.ProcessCount++;
+ }
+
+ return Agg;
+}
+
+std::vector<TrackedProcessEntry>
+ProcessGroup::Impl::GetMetricsSnapshot() const
+{
+ std::vector<TrackedProcessEntry> Result;
+
+ RwLock::SharedLockScope $(m_Lock);
+ Result.reserve(m_Processes.size());
+
+ for (const auto& [Pid, Proc] : m_Processes)
+ {
+ TrackedProcessEntry Entry;
+ Entry.Pid = Pid;
+ Entry.Metrics = Proc->m_Impl->m_LastMetrics;
+ Entry.CpuUsagePercent = Proc->m_Impl->m_CpuUsagePercent.load();
+ Result.push_back(std::move(Entry));
+ }
+
+ return Result;
+}
+
+size_t
+ProcessGroup::Impl::GetProcessCount() const
+{
+ RwLock::SharedLockScope $(m_Lock);
+ return m_Processes.size();
+}
+
+void
+ProcessGroup::Impl::Enumerate(std::function<void(const ManagedProcess&)> Callback) const
+{
+ RwLock::SharedLockScope $(m_Lock);
+ for (const auto& [Pid, Proc] : m_Processes)
+ {
+ Callback(*Proc);
+ }
+}
+
+// ============================================================================
+// ProcessGroup
+// ============================================================================
+
+ProcessGroup::ProcessGroup(std::unique_ptr<Impl> InImpl) : m_Impl(std::move(InImpl))
+{
+}
+
+ProcessGroup::~ProcessGroup() = default;
+
+std::string_view
+ProcessGroup::GetName() const
+{
+ return m_Impl->m_Name;
+}
+
+ManagedProcess*
+ProcessGroup::Spawn(const std::filesystem::path& Executable,
+ std::string_view CommandLine,
+ CreateProcOptions& Options,
+ ProcessExitCallback OnExit,
+ ProcessDataCallback OnStdout,
+ ProcessDataCallback OnStderr)
+{
+ ZEN_TRACE_CPU("ProcessGroup::Spawn");
+ return m_Impl->Spawn(Executable, CommandLine, Options, std::move(OnExit), std::move(OnStdout), std::move(OnStderr));
+}
+
+ManagedProcess*
+ProcessGroup::Adopt(ProcessHandle&& Handle, ProcessExitCallback OnExit)
+{
+ ZEN_TRACE_CPU("ProcessGroup::Adopt");
+ return m_Impl->Adopt(std::move(Handle), std::move(OnExit));
+}
+
+void
+ProcessGroup::Remove(int Pid)
+{
+ ZEN_TRACE_CPU("ProcessGroup::Remove");
+ m_Impl->Remove(Pid);
+}
+
+void
+ProcessGroup::KillAll()
+{
+ ZEN_TRACE_CPU("ProcessGroup::KillAll");
+ m_Impl->KillAll();
+}
+
+AggregateProcessMetrics
+ProcessGroup::GetAggregateMetrics() const
+{
+ return m_Impl->GetAggregateMetrics();
+}
+
+std::vector<TrackedProcessEntry>
+ProcessGroup::GetMetricsSnapshot() const
+{
+ return m_Impl->GetMetricsSnapshot();
+}
+
+size_t
+ProcessGroup::GetProcessCount() const
+{
+ return m_Impl->GetProcessCount();
+}
+
+void
+ProcessGroup::Enumerate(std::function<void(const ManagedProcess&)> Callback) const
+{
+ m_Impl->Enumerate(std::move(Callback));
+}
+
+} // namespace zen
+
+// ============================================================================
+// Tests
+// ============================================================================
+
+#if ZEN_WITH_TESTS
+
+# include <zencore/testing.h>
+
+# include <chrono>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+# include <asio/io_context.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+using namespace zen;
+using namespace std::literals;
+
+void
+zen::subprocessmanager_forcelink()
+{
+}
+
+namespace {
+
+std::filesystem::path
+GetAppStubPath()
+{
+ std::error_code Ec;
+ std::filesystem::path SelfPath = GetProcessExecutablePath(zen::GetCurrentProcessId(), Ec);
+ return SelfPath.parent_path() / "zentest-appstub" ZEN_EXE_SUFFIX_LITERAL;
+}
+
+} // namespace
+
+TEST_SUITE_BEGIN("util.subprocessmanager");
+
+TEST_CASE("SubprocessManager.SpawnAndDetectExit")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -f=42";
+
+ int ReceivedExitCode = -1;
+ bool CallbackFired = false;
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int ExitCode) {
+ ReceivedExitCode = ExitCode;
+ CallbackFired = true;
+ });
+
+ IoContext.run_for(5s);
+
+ CHECK(CallbackFired);
+ CHECK(ReceivedExitCode == 42);
+}
+
+TEST_CASE("SubprocessManager.SpawnAndDetectCleanExit")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string();
+
+ int ReceivedExitCode = -1;
+ bool CallbackFired = false;
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int ExitCode) {
+ ReceivedExitCode = ExitCode;
+ CallbackFired = true;
+ });
+
+ IoContext.run_for(5s);
+
+ CHECK(CallbackFired);
+ CHECK(ReceivedExitCode == 0);
+}
+
+TEST_CASE("SubprocessManager.StdoutCapture")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -echo=hello_world";
+
+ StdoutPipeHandles StdoutPipe;
+ REQUIRE(CreateOverlappedStdoutPipe(StdoutPipe));
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+ Options.StdoutPipe = &StdoutPipe;
+
+ bool Exited = false;
+
+ ManagedProcess* Proc = Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { Exited = true; });
+
+ IoContext.run_for(5s);
+
+ CHECK(Exited);
+ std::string Captured = Proc->GetCapturedStdout();
+ CHECK(Captured.find("hello_world") != std::string::npos);
+}
+
+TEST_CASE("SubprocessManager.StderrCapture")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -echoerr=error_msg";
+
+ StdoutPipeHandles StdoutPipe;
+ StdoutPipeHandles StderrPipe;
+ REQUIRE(CreateOverlappedStdoutPipe(StdoutPipe));
+ REQUIRE(CreateOverlappedStdoutPipe(StderrPipe));
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+ Options.StdoutPipe = &StdoutPipe;
+ Options.StderrPipe = &StderrPipe;
+
+ bool Exited = false;
+
+ ManagedProcess* Proc = Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { Exited = true; });
+
+ IoContext.run_for(5s);
+
+ CHECK(Exited);
+ std::string CapturedErr = Proc->GetCapturedStderr();
+ CHECK(CapturedErr.find("error_msg") != std::string::npos);
+}
+
+TEST_CASE("SubprocessManager.StdoutCallback")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -echo=callback_test";
+
+ StdoutPipeHandles StdoutPipe;
+ REQUIRE(CreateOverlappedStdoutPipe(StdoutPipe));
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+ Options.StdoutPipe = &StdoutPipe;
+
+ std::string ReceivedData;
+ bool Exited = false;
+
+ ManagedProcess* Proc = Manager.Spawn(
+ AppStub,
+ CmdLine,
+ Options,
+ [&](ManagedProcess&, int) { Exited = true; },
+ [&](ManagedProcess&, std::string_view Data) { ReceivedData.append(Data); });
+
+ IoContext.run_for(5s);
+
+ CHECK(Exited);
+ CHECK(ReceivedData.find("callback_test") != std::string::npos);
+ // When a callback is set, accumulated buffer should be empty
+ CHECK(Proc->GetCapturedStdout().empty());
+}
+
+TEST_CASE("SubprocessManager.MetricsSampling")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 100, .MetricsBatchSize = 16});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -t=2";
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ bool Exited = false;
+
+ ManagedProcess* Proc = Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { Exited = true; });
+
+ // Run for enough time to get metrics samples
+ IoContext.run_for(1s);
+
+ ProcessMetrics Metrics = Proc->GetLatestMetrics();
+ CHECK(Metrics.WorkingSetSize > 0);
+
+ auto Snapshot = Manager.GetMetricsSnapshot();
+ CHECK(Snapshot.size() == 1);
+
+ // Let it finish
+ IoContext.run_for(3s);
+ CHECK(Exited);
+}
+
+TEST_CASE("SubprocessManager.RemoveWhileRunning")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -t=10";
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ bool CallbackFired = false;
+
+ ManagedProcess* Proc = Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { CallbackFired = true; });
+
+ int Pid = Proc->Pid();
+
+ // Let it start
+ IoContext.run_for(100ms);
+
+ // Remove without killing — callback should NOT fire after this
+ Manager.Remove(Pid);
+
+ IoContext.run_for(500ms);
+
+ CHECK_FALSE(CallbackFired);
+ CHECK(Manager.GetProcessCount() == 0);
+}
+
+TEST_CASE("SubprocessManager.KillAndWaitForExit")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -t=60";
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ bool CallbackFired = false;
+
+ ManagedProcess* Proc = Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { CallbackFired = true; });
+
+ // Let it start
+ IoContext.run_for(200ms);
+
+ Proc->Kill();
+
+ IoContext.run_for(2s);
+
+ CHECK(CallbackFired);
+}
+
+TEST_CASE("SubprocessManager.AdoptProcess")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -f=7";
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ CreateProcResult Result = CreateProc(AppStub, CmdLine, Options);
+
+ int ReceivedExitCode = -1;
+
+ Manager.Adopt(ProcessHandle(Result), [&](ManagedProcess&, int ExitCode) { ReceivedExitCode = ExitCode; });
+
+ IoContext.run_for(5s);
+
+ CHECK(ReceivedExitCode == 7);
+}
+
+TEST_CASE("SubprocessManager.UserTag")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ std::string CmdLine = AppStub.string() + " -f=0";
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ std::string ReceivedTag;
+
+ ManagedProcess* Proc = Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess& P, int) { ReceivedTag = std::string(P.GetTag()); });
+
+ Proc->SetTag("my-worker-1");
+ CHECK(Proc->GetTag() == "my-worker-1");
+
+ IoContext.run_for(5s);
+
+ CHECK(ReceivedTag == "my-worker-1");
+}
+
+TEST_CASE("ProcessGroup.SpawnAndMembership")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ ProcessGroup* Group = Manager.CreateGroup("test-group");
+ REQUIRE(Group != nullptr);
+ CHECK(Group->GetName() == "test-group");
+
+ std::filesystem::path AppStub = GetAppStubPath();
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ int ExitCount = 0;
+
+ std::string CmdLine1 = AppStub.string() + " -f=0";
+ std::string CmdLine2 = AppStub.string() + " -f=1";
+
+ Group->Spawn(AppStub, CmdLine1, Options, [&](ManagedProcess&, int) { ExitCount++; });
+ Group->Spawn(AppStub, CmdLine2, Options, [&](ManagedProcess&, int) { ExitCount++; });
+
+ CHECK(Group->GetProcessCount() == 2);
+ CHECK(Manager.GetProcessCount() == 2);
+
+ IoContext.run_for(5s);
+
+ CHECK(ExitCount == 2);
+}
+
+TEST_CASE("ProcessGroup.KillAll")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ ProcessGroup* Group = Manager.CreateGroup("kill-group");
+
+ std::filesystem::path AppStub = GetAppStubPath();
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ int ExitCount = 0;
+
+ std::string CmdLine = AppStub.string() + " -t=60";
+
+ Group->Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { ExitCount++; });
+ Group->Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { ExitCount++; });
+
+ // Let them start
+ IoContext.run_for(200ms);
+ CHECK(Group->GetProcessCount() == 2);
+
+ Group->KillAll();
+ CHECK(Group->GetProcessCount() == 0);
+}
+
+TEST_CASE("ProcessGroup.AggregateMetrics")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 100, .MetricsBatchSize = 16});
+
+ ProcessGroup* Group = Manager.CreateGroup("metrics-group");
+
+ std::filesystem::path AppStub = GetAppStubPath();
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ std::string CmdLine = AppStub.string() + " -t=3";
+
+ Group->Spawn(AppStub, CmdLine, Options, [](ManagedProcess&, int) {});
+ Group->Spawn(AppStub, CmdLine, Options, [](ManagedProcess&, int) {});
+
+ // Wait for metrics sampling
+ IoContext.run_for(1s);
+
+ AggregateProcessMetrics GroupAgg = Group->GetAggregateMetrics();
+ CHECK(GroupAgg.ProcessCount == 2);
+ CHECK(GroupAgg.TotalWorkingSetSize > 0);
+
+ // Manager-level metrics should include group processes
+ AggregateProcessMetrics ManagerAgg = Manager.GetAggregateMetrics();
+ CHECK(ManagerAgg.ProcessCount == 2);
+
+ Group->KillAll();
+}
+
+TEST_CASE("ProcessGroup.DestroyGroup")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ ProcessGroup* Group = Manager.CreateGroup("destroy-group");
+
+ std::filesystem::path AppStub = GetAppStubPath();
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ std::string CmdLine = AppStub.string() + " -t=60";
+
+ Group->Spawn(AppStub, CmdLine, Options, [](ManagedProcess&, int) {});
+ Group->Spawn(AppStub, CmdLine, Options, [](ManagedProcess&, int) {});
+
+ IoContext.run_for(200ms);
+ CHECK(Manager.GetProcessCount() == 2);
+
+ Manager.DestroyGroup("destroy-group");
+
+ CHECK(Manager.FindGroup("destroy-group") == nullptr);
+ CHECK(Manager.GetProcessCount() == 0);
+}
+
+TEST_CASE("ProcessGroup.MixedGroupedAndUngrouped")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ ProcessGroup* Group = Manager.CreateGroup("mixed-group");
+
+ std::filesystem::path AppStub = GetAppStubPath();
+
+ CreateProcOptions Options;
+ Options.Flags = CreateProcOptions::Flag_NoConsole;
+
+ int GroupExitCount = 0;
+ int UngroupedExitCode = -1;
+
+ std::string CmdLine = AppStub.string() + " -f=0";
+
+ // Grouped processes
+ Group->Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { GroupExitCount++; });
+ Group->Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int) { GroupExitCount++; });
+
+ // Ungrouped process
+ Manager.Spawn(AppStub, CmdLine, Options, [&](ManagedProcess&, int ExitCode) { UngroupedExitCode = ExitCode; });
+
+ CHECK(Group->GetProcessCount() == 2);
+ CHECK(Manager.GetProcessCount() == 3);
+
+ IoContext.run_for(5s);
+
+ CHECK(GroupExitCount == 2);
+ CHECK(UngroupedExitCode == 0);
+}
+
+TEST_CASE("ProcessGroup.FindGroup")
+{
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 0});
+
+ CHECK(Manager.FindGroup("nonexistent") == nullptr);
+
+ ProcessGroup* Group = Manager.CreateGroup("findable");
+ CHECK(Manager.FindGroup("findable") == Group);
+ CHECK(Manager.FindGroup("findable")->GetName() == "findable");
+}
+
+TEST_CASE("SubprocessManager.StressTest" * doctest::skip())
+{
+ // Seed for reproducibility — change to explore different orderings
+ //
+ // Note that while this is a stress test, it is still single-threaded
+
+ constexpr uint32_t Seed = 42;
+ std::mt19937 Rng(Seed);
+ ZEN_INFO("StressTest: seed={}", Seed);
+
+ asio::io_context IoContext;
+ SubprocessManager Manager(IoContext, {.MetricsSampleIntervalMs = 200, .MetricsBatchSize = 32});
+
+ std::filesystem::path AppStub = GetAppStubPath();
+ CreateProcOptions BaseOptions;
+ BaseOptions.Flags = CreateProcOptions::Flag_NoConsole;
+
+ std::atomic<int> TotalExitCallbacks{0};
+ std::atomic<int> KilledGroupProcessCount{0};
+
+ auto MakeExitCallback = [&](std::atomic<int>& Counter) {
+ return [&Counter, &TotalExitCallbacks](ManagedProcess&, int) {
+ Counter++;
+ TotalExitCallbacks++;
+ };
+ };
+
+ // ========================================================================
+ // Phase 1: Spawn multiple groups with varied workloads
+ // ========================================================================
+
+ ZEN_INFO("StressTest: Phase 1 — spawning initial groups");
+
+ constexpr int NumInitialGroups = 8;
+ std::vector<std::string> GroupNames;
+ std::vector<std::atomic<int>> GroupExitCounts(NumInitialGroups);
+ std::uniform_int_distribution<int> ProcCountDist(5, 100);
+ std::uniform_int_distribution<int> SleepDist(1, 5);
+ std::uniform_int_distribution<int> ExitCodeDist(0, 10);
+ std::uniform_int_distribution<int> WorkloadDist(0, 2); // 0=sleep, 1=exit-code, 2=echo+exit
+ int TotalPhase1Spawned = 0;
+
+ for (int G = 0; G < NumInitialGroups; G++)
+ {
+ std::string GroupName = fmt::format("stress-group-{}", G);
+ ProcessGroup* Group = Manager.CreateGroup(GroupName);
+ GroupNames.push_back(GroupName);
+
+ int ProcCount = ProcCountDist(Rng);
+ for (int P = 0; P < ProcCount; P++)
+ {
+ std::string CmdLine;
+ int Workload = WorkloadDist(Rng);
+ if (Workload == 0)
+ {
+ int Sleep = SleepDist(Rng);
+ CmdLine = fmt::format("{} -t={}", AppStub.string(), Sleep);
+ }
+ else if (Workload == 1)
+ {
+ int Code = ExitCodeDist(Rng);
+ CmdLine = fmt::format("{} -f={}", AppStub.string(), Code);
+ }
+ else
+ {
+ int Code = ExitCodeDist(Rng);
+ CmdLine = fmt::format("{} -echo=stress_g{}_p{} -f={}", AppStub.string(), G, P, Code);
+ }
+
+ Group->Spawn(AppStub, CmdLine, BaseOptions, MakeExitCallback(GroupExitCounts[G]));
+ TotalPhase1Spawned++;
+ }
+
+ ZEN_INFO("StressTest: group '{}' spawned {} processes", GroupName, ProcCount);
+ }
+
+ ZEN_INFO("StressTest: Phase 1 total spawned: {}", TotalPhase1Spawned);
+
+ // Let processes start running and some short-lived ones exit
+ IoContext.run_for(1s);
+
+ // ========================================================================
+ // Phase 2: Randomly kill some groups, create replacements, add ungrouped
+ // ========================================================================
+
+ ZEN_INFO("StressTest: Phase 2 — random group kills and replacements");
+
+ constexpr int NumGroupsToKill = 3;
+
+ // Pick random groups to kill
+ std::vector<int> GroupIndices(NumInitialGroups);
+ std::iota(GroupIndices.begin(), GroupIndices.end(), 0);
+ std::shuffle(GroupIndices.begin(), GroupIndices.end(), Rng);
+
+ std::vector<int> KilledIndices(GroupIndices.begin(), GroupIndices.begin() + NumGroupsToKill);
+
+ for (int Idx : KilledIndices)
+ {
+ ProcessGroup* Group = Manager.FindGroup(GroupNames[Idx]);
+ if (Group)
+ {
+ size_t Count = Group->GetProcessCount();
+ ZEN_INFO("StressTest: killing group '{}' ({} processes)", GroupNames[Idx], Count);
+ Manager.DestroyGroup(GroupNames[Idx]);
+ }
+ }
+
+ // Let kills propagate
+ IoContext.run_for(500ms);
+
+ // Create replacement groups
+ std::atomic<int> ReplacementExitCount{0};
+ std::uniform_int_distribution<int> ReplacementCountDist(3, 10);
+
+ for (int R = 0; R < NumGroupsToKill; R++)
+ {
+ std::string Name = fmt::format("replacement-group-{}", R);
+ ProcessGroup* Group = Manager.CreateGroup(Name);
+ int Count = ReplacementCountDist(Rng);
+
+ for (int P = 0; P < Count; P++)
+ {
+ int Sleep = SleepDist(Rng);
+ std::string CmdLine = fmt::format("{} -t={}", AppStub.string(), Sleep);
+ Group->Spawn(AppStub, CmdLine, BaseOptions, MakeExitCallback(ReplacementExitCount));
+ }
+
+ ZEN_INFO("StressTest: replacement group '{}' spawned {} processes", Name, Count);
+ }
+
+ // Also spawn some ungrouped processes
+ std::atomic<int> UngroupedExitCount{0};
+ constexpr int NumUngrouped = 10;
+
+ for (int U = 0; U < NumUngrouped; U++)
+ {
+ int ExitCode = ExitCodeDist(Rng);
+ std::string CmdLine = fmt::format("{} -f={}", AppStub.string(), ExitCode);
+ Manager.Spawn(AppStub, CmdLine, BaseOptions, MakeExitCallback(UngroupedExitCount));
+ }
+
+ ZEN_INFO("StressTest: spawned {} ungrouped processes", NumUngrouped);
+
+ // Let things run
+ IoContext.run_for(2s);
+
+ // ========================================================================
+ // Phase 3: Rapid spawn/exit churn
+ // ========================================================================
+
+ ZEN_INFO("StressTest: Phase 3 — rapid spawn/exit churn");
+
+ std::atomic<int> ChurnExitCount{0};
+ int TotalChurnSpawned = 0;
+ constexpr int NumChurnBatches = 10;
+ std::uniform_int_distribution<int> ChurnBatchSizeDist(10, 20);
+
+ for (int Batch = 0; Batch < NumChurnBatches; Batch++)
+ {
+ std::string Name = fmt::format("churn-batch-{}", Batch);
+ ProcessGroup* Group = Manager.CreateGroup(Name);
+ int Count = ChurnBatchSizeDist(Rng);
+
+ for (int P = 0; P < Count; P++)
+ {
+ // Immediate exit processes to stress spawn/exit path
+ std::string CmdLine = fmt::format("{} -f=0", AppStub.string());
+ Group->Spawn(AppStub, CmdLine, BaseOptions, MakeExitCallback(ChurnExitCount));
+ TotalChurnSpawned++;
+ }
+
+ // Brief pump to allow some exits to be processed
+ IoContext.run_for(200ms);
+
+ // Destroy the group — any still-running processes get killed
+ Manager.DestroyGroup(Name);
+ }
+
+ ZEN_INFO("StressTest: Phase 3 spawned {} churn processes across {} batches", TotalChurnSpawned, NumChurnBatches);
+
+ // ========================================================================
+ // Phase 4: Drain and verify
+ // ========================================================================
+
+ ZEN_INFO("StressTest: Phase 4 — draining remaining processes");
+
+ // Check metrics were collected before we wind down
+ AggregateProcessMetrics Agg = Manager.GetAggregateMetrics();
+ ZEN_INFO("StressTest: aggregate metrics: {} processes, {} bytes working set", Agg.ProcessCount, Agg.TotalWorkingSetSize);
+
+ // Let remaining processes finish (replacement groups have up to 5s sleep)
+ IoContext.run_for(8s);
+
+ // Kill anything still running
+ Manager.RemoveAll();
+
+ // Final pump to process any remaining callbacks
+ IoContext.run_for(1s);
+
+ ZEN_INFO("StressTest: Results:");
+ ZEN_INFO("StressTest: total exit callbacks fired: {}", TotalExitCallbacks.load());
+ ZEN_INFO("StressTest: ungrouped exits: {}", UngroupedExitCount.load());
+ ZEN_INFO("StressTest: replacement exits: {}", ReplacementExitCount.load());
+ ZEN_INFO("StressTest: churn exits: {}", ChurnExitCount.load());
+
+ // Verify the manager is clean
+ CHECK(Manager.GetProcessCount() == 0);
+
+ // Ungrouped processes should all have exited (they were immediate-exit)
+ CHECK(UngroupedExitCount.load() == NumUngrouped);
+
+ // Verify we got a reasonable number of total callbacks
+ // (exact count is hard to predict due to killed groups, but should be > 0)
+ CHECK(TotalExitCallbacks.load() > 0);
+
+ ZEN_INFO("StressTest: PASSED — seed={}", Seed);
+}
+
+TEST_SUITE_END();
+
+#endif
diff --git a/src/zenutil/sessionsclient.cpp b/src/zenutil/sessionsclient.cpp
new file mode 100644
index 000000000..c62cc4099
--- /dev/null
+++ b/src/zenutil/sessionsclient.cpp
@@ -0,0 +1,377 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zenutil/sessionsclient.h>
+
+#include <zencore/blockingqueue.h>
+#include <zencore/compactbinarybuilder.h>
+#include <zencore/fmtutils.h>
+#include <zencore/iobuffer.h>
+#include <zencore/logging/logmsg.h>
+#include <zencore/thread.h>
+#include <zenhttp/httpclient.h>
+
+#include <thread>
+#include <vector>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <fmt/format.h>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+namespace zen {
+
+//////////////////////////////////////////////////////////////////////////
+//
+// SessionLogSink — batching log sink that forwards to /sessions/{id}/log
+//
+
+static const char*
+LogLevelToString(logging::LogLevel Level)
+{
+ switch (Level)
+ {
+ case logging::Trace:
+ return "trace";
+ case logging::Debug:
+ return "debug";
+ case logging::Info:
+ return "info";
+ case logging::Warn:
+ return "warn";
+ case logging::Err:
+ return "error";
+ case logging::Critical:
+ return "critical";
+ default:
+ return "info";
+ }
+}
+
+struct BufferedLogEntry
+{
+ enum class Type : uint8_t
+ {
+ Log,
+ Flush,
+ Shutdown
+ };
+
+ Type Type = Type::Log;
+ std::string Level;
+ std::string Message;
+};
+
+class SessionLogSink final : public logging::Sink
+{
+public:
+ SessionLogSink(std::string TargetUrl, std::string LogPath) : m_LogPath(std::move(LogPath))
+ {
+ HttpClientSettings Settings;
+ Settings.ConnectTimeout = std::chrono::milliseconds(3000);
+ m_Http = std::make_unique<HttpClient>(std::move(TargetUrl), Settings);
+
+ SetLevel(logging::Info);
+
+ m_WorkerThread = std::thread([this]() {
+ zen::SetCurrentThreadName("SessionLog");
+ WorkerLoop();
+ });
+ }
+
+ ~SessionLogSink() override
+ {
+ BufferedLogEntry ShutdownMsg;
+ ShutdownMsg.Type = BufferedLogEntry::Type::Shutdown;
+ m_Queue.Enqueue(std::move(ShutdownMsg));
+
+ if (m_WorkerThread.joinable())
+ {
+ m_WorkerThread.join();
+ }
+ }
+
+ void Log(const logging::LogMessage& Msg) override
+ {
+ BufferedLogEntry Entry;
+ Entry.Type = BufferedLogEntry::Type::Log;
+ Entry.Level = LogLevelToString(Msg.GetLevel());
+ Entry.Message = std::string(Msg.GetPayload());
+ m_Queue.Enqueue(std::move(Entry));
+ }
+
+ void Flush() override
+ {
+ // Best-effort: enqueue a flush marker so the worker sends any pending entries
+ BufferedLogEntry FlushMsg;
+ FlushMsg.Type = BufferedLogEntry::Type::Flush;
+ m_Queue.Enqueue(std::move(FlushMsg));
+ }
+
+ void SetFormatter(std::unique_ptr<logging::Formatter> /*InFormatter*/) override
+ {
+ // No formatting needed — we send raw message text
+ }
+
+private:
+ static constexpr size_t BatchSize = 50;
+
+ void WorkerLoop()
+ {
+ std::vector<BufferedLogEntry> Batch;
+ Batch.reserve(BatchSize);
+
+ BufferedLogEntry Msg;
+ while (m_Queue.WaitAndDequeue(Msg))
+ {
+ if (Msg.Type == BufferedLogEntry::Type::Shutdown)
+ {
+ // Drain remaining log entries
+ BufferedLogEntry Remaining;
+ while (m_Queue.WaitAndDequeue(Remaining))
+ {
+ if (Remaining.Type == BufferedLogEntry::Type::Log)
+ {
+ Batch.push_back(std::move(Remaining));
+ }
+ }
+ if (!Batch.empty())
+ {
+ SendBatch(Batch);
+ }
+ return;
+ }
+
+ if (Msg.Type == BufferedLogEntry::Type::Flush)
+ {
+ if (!Batch.empty())
+ {
+ SendBatch(Batch);
+ Batch.clear();
+ }
+ continue;
+ }
+
+ // Log entry
+ Batch.push_back(std::move(Msg));
+
+ if (Batch.size() >= BatchSize)
+ {
+ SendBatch(Batch);
+ Batch.clear();
+ }
+ else
+ {
+ // Drain any additional queued entries without blocking
+ while (Batch.size() < BatchSize && m_Queue.Size() > 0)
+ {
+ BufferedLogEntry Extra;
+ if (m_Queue.WaitAndDequeue(Extra))
+ {
+ if (Extra.Type == BufferedLogEntry::Type::Shutdown)
+ {
+ if (!Batch.empty())
+ {
+ SendBatch(Batch);
+ }
+ // Drain remaining
+ while (m_Queue.WaitAndDequeue(Extra))
+ {
+ if (Extra.Type == BufferedLogEntry::Type::Log)
+ {
+ Batch.push_back(std::move(Extra));
+ }
+ }
+ if (!Batch.empty())
+ {
+ SendBatch(Batch);
+ }
+ return;
+ }
+ if (Extra.Type == BufferedLogEntry::Type::Log)
+ {
+ Batch.push_back(std::move(Extra));
+ }
+ else if (Extra.Type == BufferedLogEntry::Type::Flush)
+ {
+ break;
+ }
+ }
+ }
+
+ if (!Batch.empty())
+ {
+ SendBatch(Batch);
+ Batch.clear();
+ }
+ }
+ }
+ }
+
+ void SendBatch(const std::vector<BufferedLogEntry>& Batch)
+ {
+ try
+ {
+ CbObjectWriter Writer;
+ Writer.BeginArray("entries");
+ for (const BufferedLogEntry& Entry : Batch)
+ {
+ Writer.BeginObject();
+ Writer << "level" << Entry.Level;
+ Writer << "message" << Entry.Message;
+ Writer.EndObject();
+ }
+ Writer.EndArray();
+
+ HttpClient::Response Result = m_Http->Post(m_LogPath, Writer.Save());
+ (void)Result; // Best-effort
+ }
+ catch (const std::exception&)
+ {
+ // Best-effort — silently discard on failure
+ }
+ }
+
+ std::string m_LogPath;
+ std::unique_ptr<HttpClient> m_Http;
+ BlockingQueue<BufferedLogEntry> m_Queue;
+ std::thread m_WorkerThread;
+};
+
+SessionsServiceClient::SessionsServiceClient(Options Opts)
+: m_Log(logging::Get("sessionsclient"))
+, m_Options(std::move(Opts))
+, m_SessionPath(fmt::format("sessions/{}", m_Options.SessionId))
+{
+ HttpClientSettings Settings;
+ Settings.ConnectTimeout = std::chrono::milliseconds(3000);
+ m_Http = std::make_unique<HttpClient>(m_Options.TargetUrl, Settings);
+}
+
+SessionsServiceClient::~SessionsServiceClient() = default;
+
+CbObject
+SessionsServiceClient::BuildRequestBody(CbObjectView Metadata) const
+{
+ CbObjectWriter Writer;
+ Writer << "appname" << m_Options.AppName;
+ if (!m_Options.Mode.empty())
+ {
+ Writer << "mode" << m_Options.Mode;
+ }
+ if (m_Options.JobId != Oid::Zero)
+ {
+ Writer << "jobid" << m_Options.JobId;
+ }
+ if (Metadata.GetSize() > 0)
+ {
+ Writer.AddObject("metadata", Metadata);
+ }
+ return Writer.Save();
+}
+
+bool
+SessionsServiceClient::Announce(CbObjectView Metadata)
+{
+ try
+ {
+ CbObject Body = BuildRequestBody(Metadata);
+
+ HttpClient::Response Result = m_Http->Post(m_SessionPath, std::move(Body));
+
+ if (Result.Error)
+ {
+ ZEN_WARN("sessions announce failed for '{}': HTTP error {} - {}",
+ m_Options.TargetUrl,
+ static_cast<int>(Result.Error->ErrorCode),
+ Result.Error->ErrorMessage);
+ return false;
+ }
+ if (!IsHttpOk(Result.StatusCode))
+ {
+ ZEN_WARN("sessions announce failed for '{}': HTTP status {}", m_Options.TargetUrl, static_cast<int>(Result.StatusCode));
+ return false;
+ }
+
+ ZEN_INFO("session announced to '{}'", m_Options.TargetUrl);
+ return true;
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("sessions announce failed for '{}': {}", m_Options.TargetUrl, Ex.what());
+ return false;
+ }
+}
+
+bool
+SessionsServiceClient::UpdateMetadata(CbObjectView Metadata)
+{
+ try
+ {
+ CbObject Body = BuildRequestBody(Metadata);
+
+ MemoryView View = Body.GetView();
+ IoBuffer Payload = IoBufferBuilder::MakeCloneFromMemory(View, ZenContentType::kCbObject);
+
+ HttpClient::Response Result = m_Http->Put(m_SessionPath, Payload);
+
+ if (Result.Error)
+ {
+ ZEN_WARN("sessions update failed for '{}': HTTP error {} - {}",
+ m_Options.TargetUrl,
+ static_cast<int>(Result.Error->ErrorCode),
+ Result.Error->ErrorMessage);
+ return false;
+ }
+ if (!IsHttpOk(Result.StatusCode))
+ {
+ ZEN_WARN("sessions update failed for '{}': HTTP status {}", m_Options.TargetUrl, static_cast<int>(Result.StatusCode));
+ return false;
+ }
+
+ return true;
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("sessions update failed for '{}': {}", m_Options.TargetUrl, Ex.what());
+ return false;
+ }
+}
+
+bool
+SessionsServiceClient::Remove()
+{
+ try
+ {
+ HttpClient::Response Result = m_Http->Delete(m_SessionPath);
+
+ if (Result.Error)
+ {
+ ZEN_WARN("sessions remove failed for '{}': HTTP error {} - {}",
+ m_Options.TargetUrl,
+ static_cast<int>(Result.Error->ErrorCode),
+ Result.Error->ErrorMessage);
+ return false;
+ }
+ if (!IsHttpOk(Result.StatusCode))
+ {
+ ZEN_WARN("sessions remove failed for '{}': HTTP status {}", m_Options.TargetUrl, static_cast<int>(Result.StatusCode));
+ return false;
+ }
+
+ ZEN_INFO("session removed from '{}'", m_Options.TargetUrl);
+ return true;
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_WARN("sessions remove failed for '{}': {}", m_Options.TargetUrl, Ex.what());
+ return false;
+ }
+}
+
+logging::SinkPtr
+SessionsServiceClient::CreateLogSink()
+{
+ std::string LogPath = m_SessionPath + "/log";
+ return Ref(new SessionLogSink(m_Options.TargetUrl, std::move(LogPath)));
+}
+
+} // namespace zen
diff --git a/src/zenutil/splitconsole/logstreamlistener.cpp b/src/zenutil/splitconsole/logstreamlistener.cpp
new file mode 100644
index 000000000..04718b543
--- /dev/null
+++ b/src/zenutil/splitconsole/logstreamlistener.cpp
@@ -0,0 +1,426 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zenutil/splitconsole/logstreamlistener.h>
+
+#include <zenbase/refcount.h>
+#include <zencore/compactbinary.h>
+#include <zencore/fmtutils.h>
+#include <zencore/logging.h>
+#include <zencore/thread.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <asio.hpp>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+#include <vector>
+
+namespace zen {
+
+//////////////////////////////////////////////////////////////////////////
+// LogStreamSession — reads CbObject-framed messages from a single TCP connection
+
+class LogStreamSession : public RefCounted
+{
+public:
+ LogStreamSession(asio::ip::tcp::socket Socket, LogStreamTarget& Target) : m_Socket(std::move(Socket)), m_Target(Target) {}
+
+ void Start() { DoRead(); }
+
+private:
+ void DoRead()
+ {
+ Ref<LogStreamSession> Self(this);
+ m_Socket.async_read_some(asio::buffer(m_ReadBuf.data() + m_BufferUsed, m_ReadBuf.size() - m_BufferUsed),
+ [Self](const asio::error_code& Ec, std::size_t BytesRead) {
+ if (Ec)
+ {
+ return; // connection closed or error — session ends
+ }
+ Self->m_BufferUsed += BytesRead;
+ Self->ProcessBuffer();
+ Self->DoRead();
+ });
+ }
+
+ void ProcessBuffer()
+ {
+ // Try to consume as many complete CbObject messages as possible
+ while (m_BufferUsed > 0)
+ {
+ MemoryView View = MakeMemoryView(m_ReadBuf.data(), m_BufferUsed);
+ CbFieldType Type;
+ uint64_t Size = 0;
+
+ if (!TryMeasureCompactBinary(View, Type, Size))
+ {
+ break; // need more data
+ }
+
+ if (Size > m_BufferUsed)
+ {
+ break; // need more data
+ }
+
+ // Parse the CbObject
+ CbObject Obj = CbObject(SharedBuffer::Clone(MakeMemoryView(m_ReadBuf.data(), Size)));
+
+ std::string_view Text = Obj["text"].AsString();
+ std::string_view Source = Obj["source"].AsString();
+
+ // Check sequence number for gaps (dropped messages)
+ uint64_t Seq = Obj["seq"].AsUInt64();
+ if (Seq > m_NextExpectedSeq)
+ {
+ uint64_t Dropped = Seq - m_NextExpectedSeq;
+ m_Target.AppendLogLine(fmt::format("[{}] *** {} log message(s) dropped ***", Source.empty() ? "log" : Source, Dropped));
+ }
+ m_NextExpectedSeq = Seq + 1;
+
+ // Split multi-line messages into individual AppendLogLine calls so that
+ // each line gets its own row in the target's log output.
+ while (!Text.empty())
+ {
+ std::string_view Line = Text;
+ auto Pos = Text.find('\n');
+ if (Pos != std::string_view::npos)
+ {
+ Line = Text.substr(0, Pos);
+ Text.remove_prefix(Pos + 1);
+ }
+ else
+ {
+ Text = {};
+ }
+
+ // Strip trailing CR from CRLF
+ if (!Line.empty() && Line.back() == '\r')
+ {
+ Line.remove_suffix(1);
+ }
+
+ if (Line.empty())
+ {
+ continue;
+ }
+
+ if (!Source.empty())
+ {
+ m_Target.AppendLogLine(fmt::format("[{}] {}", Source, Line));
+ }
+ else
+ {
+ m_Target.AppendLogLine(Line);
+ }
+ }
+
+ // Remove consumed bytes from buffer
+ std::size_t Consumed = static_cast<std::size_t>(Size);
+ std::memmove(m_ReadBuf.data(), m_ReadBuf.data() + Consumed, m_BufferUsed - Consumed);
+ m_BufferUsed -= Consumed;
+ }
+
+ // If buffer is full and we can't parse a message, the message is too large — drop connection
+ if (m_BufferUsed == m_ReadBuf.size())
+ {
+ ZEN_WARN("LogStreamSession: buffer full with no complete message, dropping connection");
+ asio::error_code Ec;
+ m_Socket.close(Ec);
+ m_BufferUsed = 0;
+ }
+ }
+
+ asio::ip::tcp::socket m_Socket;
+ LogStreamTarget& m_Target;
+ std::array<uint8_t, 65536> m_ReadBuf{};
+ std::size_t m_BufferUsed = 0;
+ uint64_t m_NextExpectedSeq = 0;
+};
+
+//////////////////////////////////////////////////////////////////////////
+// LogStreamListener::Impl
+
+struct LogStreamListener::Impl
+{
+ // Owned io_context mode — creates and runs its own thread
+ Impl(LogStreamTarget& Target, uint16_t Port)
+ : m_Target(Target)
+ , m_OwnedIoContext(std::make_unique<asio::io_context>())
+ , m_Acceptor(*m_OwnedIoContext)
+ {
+ SetupAcceptor(Port);
+ m_IoThread = std::thread([this]() {
+ zen::SetCurrentThreadName("LogStreamIO");
+ m_OwnedIoContext->run();
+ });
+ }
+
+ // External io_context mode — caller drives the io_context
+ Impl(LogStreamTarget& Target, asio::io_context& IoContext, uint16_t Port) : m_Target(Target), m_Acceptor(IoContext)
+ {
+ SetupAcceptor(Port);
+ }
+
+ ~Impl() { Shutdown(); }
+
+ void Shutdown()
+ {
+ if (m_Stopped.exchange(true))
+ {
+ return;
+ }
+
+ asio::error_code Ec;
+ m_Acceptor.close(Ec);
+
+ if (m_OwnedIoContext)
+ {
+ m_OwnedIoContext->stop();
+ }
+
+ if (m_IoThread.joinable())
+ {
+ m_IoThread.join();
+ }
+ }
+
+ uint16_t GetPort() const { return m_Port; }
+
+private:
+ void SetupAcceptor(uint16_t Port)
+ {
+ auto& IoCtx = m_OwnedIoContext ? *m_OwnedIoContext : m_Acceptor.get_executor().context();
+ ZEN_UNUSED(IoCtx);
+
+ // Try dual-stack IPv6 first (accepts both IPv4 and IPv6), fall back to IPv4-only
+ asio::error_code Ec;
+ m_Acceptor.open(asio::ip::tcp::v6(), Ec);
+ if (!Ec)
+ {
+ m_Acceptor.set_option(asio::ip::v6_only(false), Ec);
+ if (!Ec)
+ {
+ m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::tcp::v6(), Port), Ec);
+ }
+ }
+
+ if (Ec)
+ {
+ // Fall back to IPv4-only
+ if (m_Acceptor.is_open())
+ {
+ m_Acceptor.close();
+ }
+ m_Acceptor.open(asio::ip::tcp::v4());
+ m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::tcp::v4(), Port));
+ }
+
+ m_Acceptor.listen();
+ m_Port = m_Acceptor.local_endpoint().port();
+ StartAccept();
+ }
+
+ void StartAccept()
+ {
+ m_Acceptor.async_accept([this](const asio::error_code& Ec, asio::ip::tcp::socket Socket) {
+ if (Ec)
+ {
+ return; // acceptor closed
+ }
+
+ Ref<LogStreamSession> Session(new LogStreamSession(std::move(Socket), m_Target));
+ Session->Start();
+
+ if (!m_Stopped.load())
+ {
+ StartAccept();
+ }
+ });
+ }
+
+ LogStreamTarget& m_Target;
+ std::unique_ptr<asio::io_context> m_OwnedIoContext; // null when using external io_context
+ asio::ip::tcp::acceptor m_Acceptor;
+ std::thread m_IoThread;
+ uint16_t m_Port = 0;
+ std::atomic<bool> m_Stopped{false};
+};
+
+//////////////////////////////////////////////////////////////////////////
+// LogStreamListener
+
+LogStreamListener::LogStreamListener(LogStreamTarget& Target, uint16_t Port) : m_Impl(std::make_unique<Impl>(Target, Port))
+{
+}
+
+LogStreamListener::LogStreamListener(LogStreamTarget& Target, asio::io_context& IoContext, uint16_t Port)
+: m_Impl(std::make_unique<Impl>(Target, IoContext, Port))
+{
+}
+
+LogStreamListener::~LogStreamListener() = default;
+
+uint16_t
+LogStreamListener::GetPort() const
+{
+ return m_Impl->GetPort();
+}
+
+void
+LogStreamListener::Shutdown()
+{
+ m_Impl->Shutdown();
+}
+
+} // namespace zen
+
+#if ZEN_WITH_TESTS
+
+# include <zencore/testing.h>
+# include <zenutil/splitconsole/tcplogstreamsink.h>
+
+namespace zen {
+
+void
+logstreamlistener_forcelink()
+{
+}
+
+namespace {
+
+ class CollectingTarget : public LogStreamTarget
+ {
+ public:
+ void AppendLogLine(std::string_view Text) override
+ {
+ std::lock_guard<std::mutex> Lock(m_Mutex);
+ m_Lines.emplace_back(Text);
+ m_Cv.notify_all();
+ }
+
+ std::vector<std::string> WaitForLines(size_t Count, std::chrono::milliseconds Timeout = std::chrono::milliseconds(5000))
+ {
+ std::unique_lock<std::mutex> Lock(m_Mutex);
+ m_Cv.wait_for(Lock, Timeout, [&]() { return m_Lines.size() >= Count; });
+ return m_Lines;
+ }
+
+ private:
+ std::mutex m_Mutex;
+ std::condition_variable m_Cv;
+ std::vector<std::string> m_Lines;
+ };
+
+ logging::LogMessage MakeLogMessage(std::string_view Text, logging::LogLevel Level = logging::Info)
+ {
+ static logging::LogPoint Point{{}, Level, {}};
+ Point.Level = Level;
+ return logging::LogMessage(Point, "test", Text);
+ }
+
+} // namespace
+
+TEST_SUITE_BEGIN("util.logstreamlistener");
+
+TEST_CASE("BasicMessageDelivery")
+{
+ CollectingTarget Target;
+ LogStreamListener Listener(Target);
+
+ {
+ TcpLogStreamSink Sink("127.0.0.1", Listener.GetPort(), "TestSource", 64);
+ Sink.Log(MakeLogMessage("hello world"));
+ Sink.Log(MakeLogMessage("second line"));
+ }
+
+ auto Lines = Target.WaitForLines(2);
+ REQUIRE(Lines.size() == 2);
+ CHECK(Lines[0] == "[TestSource] hello world");
+ CHECK(Lines[1] == "[TestSource] second line");
+}
+
+TEST_CASE("MultiLineMessageSplit")
+{
+ CollectingTarget Target;
+ LogStreamListener Listener(Target);
+
+ {
+ TcpLogStreamSink Sink("127.0.0.1", Listener.GetPort(), "src", 64);
+ Sink.Log(MakeLogMessage("line1\nline2\nline3"));
+ }
+
+ auto Lines = Target.WaitForLines(3);
+ REQUIRE(Lines.size() == 3);
+ CHECK(Lines[0] == "[src] line1");
+ CHECK(Lines[1] == "[src] line2");
+ CHECK(Lines[2] == "[src] line3");
+}
+
+TEST_CASE("DroppedMessageDetection")
+{
+ // Test sequence-gap detection deterministically by sending raw CbObjects
+ // with an explicit gap in sequence numbers, bypassing TcpLogStreamSink.
+ CollectingTarget Target;
+ LogStreamListener Listener(Target);
+
+ {
+ asio::io_context IoContext;
+ asio::ip::tcp::socket Socket(IoContext);
+ Socket.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), Listener.GetPort()));
+
+ // Send seq=0, then seq=5 — the listener should detect a gap of 4
+ for (uint64_t Seq : {uint64_t(0), uint64_t(5)})
+ {
+ CbObjectWriter Writer;
+ Writer.AddString("text", fmt::format("msg{}", Seq));
+ Writer.AddString("source", "src");
+ Writer.AddInteger("seq", Seq);
+ CbObject Obj = Writer.Save();
+ MemoryView View = Obj.GetView();
+
+ asio::write(Socket, asio::buffer(View.GetData(), View.GetSize()));
+ }
+ }
+
+ // Expect: msg0, drop notice, msg5
+ auto Lines = Target.WaitForLines(3);
+ REQUIRE(Lines.size() >= 3);
+ CHECK(Lines[0] == "[src] msg0");
+ CHECK(Lines[1].find("4 log message(s) dropped") != std::string::npos);
+ CHECK(Lines[2] == "[src] msg5");
+}
+
+TEST_CASE("SequenceNumbersAreContiguous")
+{
+ CollectingTarget Target;
+ LogStreamListener Listener(Target);
+
+ constexpr int NumMessages = 5;
+ {
+ TcpLogStreamSink Sink("127.0.0.1", Listener.GetPort(), "seq", 64);
+ for (int i = 0; i < NumMessages; i++)
+ {
+ Sink.Log(MakeLogMessage(fmt::format("msg{}", i)));
+ }
+ }
+
+ auto Lines = Target.WaitForLines(NumMessages);
+ REQUIRE(Lines.size() == NumMessages);
+
+ // No "dropped" notices should appear when nothing is dropped
+ for (auto& Line : Lines)
+ {
+ CHECK(Line.find("dropped") == std::string::npos);
+ }
+
+ // Verify ordering
+ for (int i = 0; i < NumMessages; i++)
+ {
+ CHECK(Lines[i] == fmt::format("[seq] msg{}", i));
+ }
+}
+
+TEST_SUITE_END();
+
+} // namespace zen
+
+#endif
diff --git a/src/zenutil/xmake.lua b/src/zenutil/xmake.lua
index 1e19f7b2f..83a6b7f93 100644
--- a/src/zenutil/xmake.lua
+++ b/src/zenutil/xmake.lua
@@ -11,6 +11,10 @@ target('zenutil')
add_deps("robin-map")
add_packages("json11")
+ if is_plat("linux", "macosx") then
+ add_packages("openssl3")
+ end
+
if is_plat("linux") then
add_includedirs("$(projectdir)/thirdparty/systemd/include")
add_linkdirs("$(projectdir)/thirdparty/systemd/lib")
diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp
index e0d99c981..2b27b2d8b 100644
--- a/src/zenutil/zenserverprocess.cpp
+++ b/src/zenutil/zenserverprocess.cpp
@@ -15,6 +15,7 @@
#include <zencore/timer.h>
#include <atomic>
+#include <string>
#include <gsl/gsl-lite.hpp>
@@ -764,10 +765,10 @@ ZenServerEnvironment::ZenServerEnvironment(EStorageTag, std::filesystem::path Pr
ZenServerEnvironment::ZenServerEnvironment(EHubTag,
std::filesystem::path ProgramBaseDir,
- std::filesystem::path TestBaseDir,
+ std::filesystem::path ChildBaseDir,
std::string_view ServerClass)
{
- InitializeForHub(ProgramBaseDir, TestBaseDir, ServerClass);
+ InitializeForHub(ProgramBaseDir, ChildBaseDir, ServerClass);
}
ZenServerEnvironment::ZenServerEnvironment(ETestTag,
@@ -964,6 +965,7 @@ ZenServerInstance::Shutdown()
ZEN_DEBUG("zenserver process {} ({}) exited", m_Name, m_Process.Pid());
int ExitCode = m_Process.GetExitCode();
m_Process.Reset();
+ m_ShutdownEvent.reset();
return ExitCode;
}
@@ -993,6 +995,7 @@ ZenServerInstance::Shutdown()
ZEN_DEBUG("zenserver process {} ({}) exited", m_Name, m_Process.Pid());
int ExitCode = m_Process.GetExitCode();
m_Process.Reset();
+ m_ShutdownEvent.reset();
return ExitCode;
}
else if (Ec)
@@ -1020,6 +1023,7 @@ ZenServerInstance::Shutdown()
int ExitCode = m_Process.GetExitCode();
ZEN_DEBUG("zenserver process {} ({}) exited", m_Name, m_Process.Pid());
m_Process.Reset();
+ m_ShutdownEvent.reset();
return ExitCode;
}
ZEN_DEBUG("Detached from zenserver process {} ({})", m_Name, m_Process.Pid());
@@ -1371,18 +1375,31 @@ ZenServerInstance::OnServerReady()
const ZenServerState::ZenServerEntry* Entry = nullptr;
- if (m_BasePort)
- {
- Entry = State.Lookup(m_BasePort);
- }
- else
+ // The child process signals its ready event after writing its state entry, but under
+ // heavy instrumentation (e.g. sanitizers) the shared memory writes may not be immediately
+ // visible to this process. Retry briefly before giving up.
+ for (int Attempt = 0; Attempt < 10; ++Attempt)
{
- State.Snapshot([&](const ZenServerState::ZenServerEntry& InEntry) {
- if (InEntry.Pid == (uint32_t)m_Process.Pid())
- {
- Entry = &InEntry;
- }
- });
+ if (m_BasePort)
+ {
+ Entry = State.Lookup(m_BasePort);
+ }
+ else
+ {
+ State.Snapshot([&](const ZenServerState::ZenServerEntry& InEntry) {
+ if (InEntry.Pid == (uint32_t)m_Process.Pid())
+ {
+ Entry = &InEntry;
+ }
+ });
+ }
+
+ if (Entry)
+ {
+ break;
+ }
+
+ Sleep(100);
}
if (!Entry)
@@ -1419,7 +1436,7 @@ ZenServerInstance::SetDataDir(std::filesystem::path TestDir)
}
bool
-ZenServerInstance::IsRunning()
+ZenServerInstance::IsRunning() const
{
if (!m_Process.IsValid())
{
@@ -1428,6 +1445,16 @@ ZenServerInstance::IsRunning()
return m_Process.IsRunning();
}
+void
+ZenServerInstance::ResetDeadProcess()
+{
+ if (m_Process.IsValid() && !m_Process.IsRunning())
+ {
+ m_Process.Reset();
+ m_ShutdownEvent.reset();
+ }
+}
+
std::string
ZenServerInstance::GetLogOutput() const
{
@@ -1553,4 +1580,135 @@ ValidateLockFileInfo(const LockFileInfo& Info, std::string& OutReason)
return true;
}
+std::optional<int>
+StartupZenServer(LoggerRef LogRef, const StartupZenServerOptions& Options)
+{
+ auto Log = [&LogRef]() { return LogRef; };
+
+ // Check if a matching server is already running
+ {
+ ZenServerState State;
+ if (State.InitializeReadOnly())
+ {
+ uint32_t RunningPid = 0;
+ uint16_t RunningEffectivePort = 0;
+ State.Snapshot([&, DesiredPort = Options.Port](const ZenServerState::ZenServerEntry& Entry) {
+ if (RunningPid == 0 && (DesiredPort == 0 || Entry.DesiredListenPort.load() == DesiredPort))
+ {
+ RunningPid = Entry.Pid.load();
+ RunningEffectivePort = Entry.EffectiveListenPort.load();
+ }
+ });
+ if (RunningPid != 0)
+ {
+ ZEN_INFO("Zen server already running at port {}, pid {}", RunningEffectivePort, RunningPid);
+ return std::nullopt;
+ }
+ }
+ }
+
+ std::filesystem::path ProgramBaseDir = Options.ProgramBaseDir;
+ if (ProgramBaseDir.empty())
+ {
+ ProgramBaseDir = GetRunningExecutablePath().parent_path();
+ }
+
+ ZenServerEnvironment ServerEnvironment;
+ ServerEnvironment.Initialize(ProgramBaseDir);
+ ZenServerInstance Server(ServerEnvironment, Options.Mode);
+
+ std::string ServerArguments(Options.ExtraArgs);
+ if ((Options.Port != 0) && (ServerArguments.find("--port") == std::string::npos))
+ {
+ ServerArguments.append(fmt::format(" --port {}", Options.Port));
+ }
+ Server.SpawnServer(ServerArguments, Options.OpenConsole, /*WaitTimeoutMs*/ 0);
+
+ constexpr int Timeout = 10000;
+
+ if (!Server.WaitUntilReady(Timeout))
+ {
+ ZEN_WARN("{}", Server.GetLogOutput());
+ if (Server.IsRunning())
+ {
+ ZEN_WARN("Zen server launch failed (timed out), terminating");
+ Server.Terminate();
+ return 1;
+ }
+ int ExitCode = Server.Shutdown();
+ ZEN_WARN("Zen server failed to get to a ready state and exited with return code {}", ExitCode);
+ return ExitCode != 0 ? ExitCode : 1;
+ }
+
+ if (Options.ShowLog)
+ {
+ ZEN_INFO("{}", Server.GetLogOutput());
+ }
+ return 0;
+}
+
+bool
+ShutdownZenServer(LoggerRef LogRef,
+ ZenServerState& State,
+ ZenServerState::ZenServerEntry* Entry,
+ const std::filesystem::path& ProgramBaseDir)
+{
+ auto Log = [&LogRef]() { return LogRef; };
+ int EntryPort = (int)Entry->DesiredListenPort.load();
+ const uint32_t ServerProcessPid = Entry->Pid.load();
+ try
+ {
+ ZenServerEnvironment ServerEnvironment;
+ ServerEnvironment.Initialize(ProgramBaseDir);
+ ZenServerInstance Server(ServerEnvironment);
+ Server.AttachToRunningServer(EntryPort);
+
+ ZEN_INFO("attached to server on port {} (pid {}), requesting shutdown", EntryPort, ServerProcessPid);
+
+ std::error_code Ec;
+ if (Server.SignalShutdown(Ec) && !Ec)
+ {
+ Stopwatch Timer;
+ while (Timer.GetElapsedTimeMs() < 10000)
+ {
+ if (Server.WaitUntilExited(100, Ec) && !Ec)
+ {
+ ZEN_INFO("shutdown complete");
+ return true;
+ }
+ else if (Ec)
+ {
+ ZEN_WARN("Waiting for server on port {} (pid {}) failed. Reason: '{}'", EntryPort, ServerProcessPid, Ec.message());
+ }
+ }
+ }
+ else if (Ec)
+ {
+ ZEN_WARN("Requesting shutdown of server on port {} failed. Reason: '{}'", EntryPort, Ec.message());
+ }
+ }
+ catch (const std::exception& Ex)
+ {
+ ZEN_DEBUG("Exception caught when requesting shutdown: {}", Ex.what());
+ }
+
+ ZEN_INFO("Requesting detached shutdown of server on port {}", EntryPort);
+ Entry->SignalShutdownRequest();
+
+ Stopwatch Timer;
+ while (Timer.GetElapsedTimeMs() < 10000)
+ {
+ State.Sweep();
+ Entry = State.Lookup(EntryPort);
+ if (Entry == nullptr || Entry->Pid.load() != ServerProcessPid)
+ {
+ ZEN_INFO("Shutdown complete");
+ return true;
+ }
+ Sleep(100);
+ }
+
+ return false;
+}
+
} // namespace zen
diff --git a/src/zenutil/zenutil.cpp b/src/zenutil/zenutil.cpp
index 734813b69..516eec3a9 100644
--- a/src/zenutil/zenutil.cpp
+++ b/src/zenutil/zenutil.cpp
@@ -5,10 +5,13 @@
#if ZEN_WITH_TESTS
# include <zenutil/cloud/imdscredentials.h>
+# include <zenutil/consul.h>
# include <zenutil/cloud/s3client.h>
# include <zenutil/cloud/sigv4.h>
-# include <zenutil/rpcrecording.h>
# include <zenutil/config/commandlineoptions.h>
+# include <zenutil/rpcrecording.h>
+# include <zenutil/splitconsole/logstreamlistener.h>
+# include <zenutil/process/subprocessmanager.h>
# include <zenutil/wildcard.h>
namespace zen {
@@ -18,7 +21,10 @@ zenutil_forcelinktests()
{
cache::rpcrecord_forcelink();
commandlineoptions_forcelink();
+ consul::consul_forcelink();
imdscredentials_forcelink();
+ logstreamlistener_forcelink();
+ subprocessmanager_forcelink();
s3client_forcelink();
sigv4_forcelink();
wildcard_forcelink();